编程小技能 - wtdig/study GitHub Wiki
JDK1.7开始,java引入了 try-with-resources 声明,将 try-catch-finally 简化为 try-catch,这其实是一种语法糖,在编译时会进行转化为 try-catch-finally 语句。新的声明包含三部分:try-with-resources 声明、try 块、catch 块。它要求在 try-with-resources 声明中定义的变量实现了 AutoCloseable 接口,这样在系统可以自动调用它们的close方法,从而替代了finally中关闭资源的功能。
但是,它们的异常抛出机制发生了变化。在过去的 try-catch-finally 结构中,我们在finally块中关闭资源通常是这样的:
catch (Exception e) {
e.printStackTrace(); // 第一处异常处理
}
finally {
try {
if (c != null) {
c.close();
}
} catch (IOException e) {
e.printStackTrace(); // 第二处异常处理
}
}
异常处理有两种情况:
try 块没有发生异常时,直接调用finally块,如果 close 发生异常,就处理。 try 块发生异常,catch 块捕捉,进行第一处异常处理,然后调用 finally 块,如果 close 发生异常,就进行第二处异常处理。 但是在 try-with-resources 结构中,异常处理也有两种情况(注意,不论 try 中是否有异常,都会首先自动执行 close 方法,然后才判断是否进入 catch 块,建议阅读后面的反编译代码):
try 块没有发生异常时,自动调用 close 方法,如果发生异常,catch 块捕捉并处理异常。 try 块发生异常,然后自动调用 close 方法,如果 close 也发生异常,catch 块只会捕捉 try 块抛出的异常,close 方法的异常会在catch 中被压制,但是你可以在catch块中,用 Throwable.getSuppressed 方法来获取到压制异常的数组。
public class Main {
public static void startTest() {
try (MyAutoCloseA a = new MyAutoCloseA();
MyAutoCloseB b = new MyAutoCloseB()) {
a.test();
b.test();
} catch (Exception e) {
System.out.println("Main: exception");
System.out.println(e.getMessage());
Throwable[] suppressed = e.getSuppressed();
for (int i = 0; i < suppressed.length; i++)
System.out.println(suppressed[i].getMessage());
}
}
public static void main(String[] args) throws Exception {
startTest();
}
}
将临时变量抽取出来,采用查询的方式,比如:
int i = a*b;
先确定临时变量只赋值一次,finnal int i = a*b;
然后抽取出函数
finnal int i = queryCount();
private int queryCount(){
return a*b;
}
2018.12.23 自封装字段、以对象取代数据值、将值对象改为引用对象
json_extract(字段名称,'$.mappingSetId') mappingSetId存储在json中的名称
json_extract(detail.mapping_value,'$.mappingSetId')
find_in_set(传入值,字段名称)
find_in_set(#{targetField,jdbcType=VARCHAR}, a.target_field)
update
sac_accounting_line_rules a
left join sac_accounting_line_field_rules b
on a.id = b.acct_line_rule_id
set a.gmt_modified = NOW()
where a.is_deleted = 'n' and b.is_deleted = 'n'
and b.target_field = "je_created_by"
and substring_index(a.bt,"_",1) = "intercompany"
substring_index(a.bt,"_",1) 截取指定字段,比如a.bt=aaa_vvv_11,结果为aaa
is not null 不包括空字符串
判断空字段串,使用 rule_condition ="" 或者 rule_condition <>"" ,如果该字段有多个空格也是可以的
update sac_accounting_line_rules a,sac_accounting_rules b set a.bt=b.bt where a.acct_rule_id = b.id and b.bt like 'ot_ee%' and a.bt <> b.bt
在MySQL数据库中,如果在insert语句后面带上ON DUPLICATE KEY UPDATE 子句,而要插入的行与表中现有记录的惟一索引或主键中产生重复值,那么就会发生旧行的更新;如果插入的行数据与现有表中记录的唯一索引或者主键不重复,则执行新纪录插入操作。
举例:
insert into daily_hit_counter (day, slot, cnt) values ('2017-11-19', 1, 1) ON DUPLICATE KEY UPDATE cnt = cnt + 1;
3表关联查询
<resultMap id="accountingRulesMap" type="sac.dal.vo.SacAccountingRulesTableVo">
<id column="rules_id" property="id" jdbcType="BIGINT"/>
<result column="rule_name" property="ruleName" jdbcType="VARCHAR"/>
<result column="bt" property="bt" jdbcType="VARCHAR"/>
<result column="creator" property="creator" jdbcType="VARCHAR"/>
<result column="coa_id" property="coaId" jdbcType="BIGINT"/>
<result column="rule_type" property="ruleType" jdbcType="VARCHAR"/>
<result column="rule_condition" property="ruleCondition" jdbcType="VARCHAR"/>
<result column="rule_condition_desc" property="ruleConditionDesc" jdbcType="VARCHAR"/>
<result column="rule_condition_type" property="ruleConditionType" jdbcType="VARCHAR"/>
<result column="approval_status" property="approvalStatus" jdbcType="VARCHAR"/>
<result column="approver" property="approver" jdbcType="VARCHAR"/>
<result column="approval_history" property="approvalHistory" jdbcType="VARCHAR"/>
<collection property="accountingLineRules" ofType="sac.dal.vo.SacAccountingLineRulesVo">
<id column="line_rules_id" property="lineRuleId" jdbcType="BIGINT"/>
<result column="line_rule_name" property="lineRuleName" jdbcType="VARCHAR"/>
<result column="collect_key" property="collectKey" jdbcType="VARCHAR"/>
<collection property="lineFieldRules" ofType="sac.dal.vo.SacAccountingLineFieldRulesVo">
<id column="line_field_id" property="lineFieldRulesId" jdbcType="BIGINT"/>
<result column="target_field" property="targetField" jdbcType="VARCHAR"/>
<result column="mapping_type" property="mappingType" jdbcType="VARCHAR"/>
<result column="mapping_value" property="mappingValue" jdbcType="VARCHAR"/>
</collection>
</collection>
</resultMap>
<!--根据条件查询规则-->
<select id="queryAccountingRulesByCond" resultMap="accountingRulesMap">
select
t.id rules_id,t.creator,t.bt,t.rule_name,t.coa_id,t.rule_condition_desc,
t.rule_type,t.rule_condition,t.rule_condition_type,t.approval_status,
t.approver,t.approval_history,m.id line_rules_id,m.collect_key,
m.line_rule_name,n.id line_field_id,n.target_field,
n.mapping_type,n.mapping_value
from
(select a.id,a.gmt_modified,a.creator,a.bt,a.rule_name,a.coa_id,
a.rule_type,a.rule_condition_type,a.approval_status,a.rule_condition_desc,
a.approver,a.approval_history,a.rule_condition
<include refid="accountingRulesCommonCode"/>
order by a.id desc
<if test="cond.begin != null and cond.pageSize != null">
limit #{cond.begin,jdbcType=BIGINT}, #{cond.pageSize,jdbcType=BIGINT}
</if>) t
left join
(select b.* from sac_accounting_line_rules b where b.is_deleted = 'n') m
on t.id = m.acct_rule_id
left join
(select c.* from sac_accounting_line_field_rules c where c.is_deleted = 'n') n
on m.id = n.acct_line_rule_id
order by t.gmt_modified desc,t.id desc,t.coa_id asc,m.id desc
</select>
取多个list里面值的交集
List<List<String>> newStandard = new ArrayList<>();
Optional<List<String>> reduce = newStandard.parallelStream().reduce((a, b) -> {
a.retainAll(b);
return a;
});
// 取交集后的字段
List<String> finalField = reduce.orElse(new ArrayList<>());
1)对于可以出现报错的地方,都用日志记录。
Logger logger = LoggerFactory.getLogger(SacExcelJournalSourcesAoImpl.class);
logger.error("", e);
打印的日志,对应SacExcelJournalSourcesAoImpl路径
Logger logger = LoggerFactory.getLogger(""); 自定义名称,需要与日志配置文件相对应
比如:
Logger logger = LoggerFactory.getLogger("bus_event");
打印指定的名称:bus_event
日志配置文件,相对应的name=bus_event
<logger name="bus_event" level="DEBUG" additivity="false">
<appender-ref ref="BUS_EVENT" />
</logger>
Logger logger = LoggerFactory.getLogger("wt_dig");
如果需要输出到指定的文件里面:log4j的配置为:
log4j.logger.wt_dig=INFO, myappenderdao
log4j.additivity.wt_dig=false
log4j.appender.myappenderdao=org.apache.log4j.DailyRollingFileAppender
log4j.appender.myappenderdao.DatePattern='.'yyyy-MM-dd
log4j.appender.myappenderdao.File=C:\\logdemo\\dao.log
log4j.appender.myappenderdao.layout=org.apache.log4j.PatternLayout
log4j.appender.myappenderdao.layout.ConversionPattern=%-6r %d{ISO8601} %-5p %40.40c %x - %m\n
格式化日志 %s,代表字符串
String.format("Can't find field config by bt : %s", bt);
%d,代码数字
String.format("Journal sources excel analysis error, execBatchId : %d", execBatch.getId())
%s 字符串类型 "mingrisoft"
%c 字符类型 'm'
%b 布尔类型 true
%d 整数类型(十进制)99
%x 整数类型(十六进制)FF
%o 整数类型(八进制)77
%f 浮点类型99.99
%a 十六进制浮点类型 FF.35AE
%e 指数类型9.38e+5
%g 通用浮点类型(f和e类型中较短的)
%h 散列码
%% 百分比类型%
%n 换行符
%tx 日期与时间类型(x代表不同的日期与时间转换符
String str=null;
str=String.format("Hi,%s", "王力");
System.out.println(str);
str=String.format("Hi,%s:%s.%s", "王南","王力","王张");
System.out.println(str);
System.out.printf("字母a的大写是:%c %n", 'A');
System.out.printf("3>7的结果是:%b %n", 3>7);
System.out.printf("100的一半是:%d %n", 100/2);
System.out.printf("100的16进制数是:%x %n", 100);
System.out.printf("100的8进制数是:%o %n", 100);
System.out.printf("50元的书打8.5折扣是:%f 元%n", 50*0.85);
System.out.printf("上面价格的16进制数是:%a %n", 50*0.85);
System.out.printf("上面价格的指数表示:%e %n", 50*0.85);
System.out.printf("上面价格的指数和浮点数结果的长度较短的是:%g %n", 50*0.85);
System.out.printf("上面的折扣是%d%% %n", 85);
System.out.printf("字母A的散列码是:%h %n", 'A');
参考链接:https://www.cnblogs.com/Dhouse/p/7776780.html
使用MessageFormat进行格式化代码,对应小数,只会保留2位;
比如123.0098就会变成123.01
必要要使用 {}进行占位,从0开始
String msg = MessageFormat.format(
"current work no is {0},jeCreatedBy is {1},don't allow commit approval", 123.0098,
"textst");
bean拷贝
1、BeanCopier只拷贝名称和类型都相同的属性。
使用案例
BeanCopier beanCopier = BeanCopier.create(SacAccountEntry.class, SacAccountEntryVo.class, false);
beanCopier.copy(entry, accountEntryVo, null);
SacAccountEntry 来源
SacAccountEntryVo 目标
2、BeanUtils的拷贝
BeanUtils.copyProperties(item, config);
item 来源
config 目标
多个集合,取并集/交集
List<Set<String>> newStandard = new ArrayList<>();
Set<String> s1 = new HashSet<>();
s1.add("k1");
s1.add("k2");
Set<String> s2 = new HashSet<>();
s1.add("k1");
s1.add("k2");
s1.add("k5");
newStandard.add(s1);
newStandard.add(s2);
Optional<Set<String>> reduce = newStandard.parallelStream().reduce((a, b) -> {
a.addAll(b);
return a;
});
// 取并集后的字段
Set<String> finalField = reduce.orElse(new HashSet<>());
for (String s : finalField) {
System.out.println(s);
}
System.out.println(">>>>>>>>>>>>>>>>");
List<Set<String>> standard = new ArrayList<>();
Set<String> k1 = new HashSet<>();
k1.add("k1");
k1.add("k2");
Set<String> k2 = new HashSet<>();
k2.add("k1");
k2.add("k2");
k2.add("k5");
Set<String> k3 = new HashSet<>();
k3.add("k2");
standard.add(k1);
standard.add(k2);
standard.add(k3);
Optional<Set<String>> reduceData = standard.parallelStream().reduce((a, b) -> {
a.retainAll(b);
return a;
});
// 取交集后的字段
Set<String> field = reduceData.orElse(new HashSet<>());
for (String s : field) {
System.out.println(s);
}
apach的字符串工具类
tempListAlias 集合;Constants.COMMA 分割符
1、字符拼接
StringUtils.join(tempListAlias, Constants.COMMA)