本文将主要记录在日常开发中遇到的各种问题。以技术类别进行章节划分,作为个人的编码备忘录随时进行查阅,并长期进行置顶。
该模块主要记录JavaCore相关的技术点
BigDecimal.ROUND_HALF_UP: 遇到.5的情况时往上近似,例: 1.5 ->;2 BigDecimal.ROUND_HALF_DOWN : 遇到.5的情况时往下近似,例: 1.5 ->;1
DecimalFormat decimalFormat = new DecimalFormat("0.00%"); BigDecimal decimal = new BigDecimal(count.intValue()).divide(new BigDecimal(allCount), 5, ROUND_HALF_UP); String formatted = decimalFormat.format(sdPercent);
BigDecimal.setScale(5, BigDecimal.ROUND_HALF_UP) -->保留五位小数,最后一位遇到.5的情况时往上近似
这里直接参考别人的文章:
(BigDecimal的用法详解)[ https://www.cnblogs.com/jpfss/p/8072379.html ]
理解、学习与使用 JAVA 中的 OPTIONAL
举个例子:
public static void main(String[] args) { Double d = 2.2; Optional.ofNullable(d).ifPresent(a -> { System.out.println(a); }); Double a = null; System.out.println(Optional.ofNullable(a).orElse(2.2)); } ofNullable:如果对象即可能是 null 也可能是非 null,你就应该使用 ofNullable() 方法:不会抛出NullPointerException ifPresent:检查是否有值的。该方法除了执行检查,还接受一个Consumer(消费者) 参数,如果对象不是空的,就对执行传入的 Lambda 表达式: orElse:如果有值则返回该值,否则返回传递给它的参数值
这部分主要讲并发框架相关
CompletableFuture需要单独总结,这里直接放一个参考链接。 CompletableFuture 使用详解
本模块主要记录集合相关的问题
List<Object> list = new Arraylist<>(); List<Object> subList = list.subList(0, 5); 其中subList(0, 5)取得的是下标为0到4的元素,不包含下标为5的元素.
注意:subList看起来好像是取出了原list的子list,实际上仅仅是取到原list的引用。
subList方法的返回值,只是ArrayList的一个映像而已。
也就是说,当我们使用子集合subList进行元素的修改操作时,会影响原有的list集合。
如果要生成原有list的子集合,还是采用硬复制的方式比较好,也就是新建一个新的list,对原list集合进行解析后装载到新的list中。
集合排序,一般有三种方法。
利用集合框架提供的Collections.sort实现排序,待进行排序的实体需要实现比较器Comparable接口的compareTo方法。
返回当前入参的实体和this对象的属性差(该属性为排序依据),
属性差如果为负数表示当前入参比本身小, 属性差如果为0表示当前入参与本身相等, 属性差如果为正数表示当前入参比本身大,
最后调用Collections.sort(temp);返回的集合排序方式为自然排序。
通过调用
Collections.sort(List
对于JDK1.8,可以通过stream流实现排序,对象本身不需要实现Comparable接口,示例代码如下
//3.利用Java8的stream流和Comparator实现集合排序 list = list.stream().sorted(Comparator.comparing(Person::getAge)).collect(Collectors.toList());
本章节主要记录数据库相关的技术点,包含Dao相关组件的使用,如JPA、Mybatis等
一个推荐的SQL如下:
<update id="updateOne" parameterType="com.inspur.search.data.EntityRelation"> UPDATE ENTITY_RELATION <trim prefix="set" suffixOverrides=","> <if test="srcId!=null">SRC_ID=#{srcId},</if> <if test="srcType!=null">SRC_TYPE=#{srcType},</if> <if test="destId!=null">DEST_ID=#{destId},</if> <if test="destType!=null">DEST_TYPE=#{destType},</if> <if test="relType!=null">REL_TYPE=#{relType},</if> <if test="status!=null">STATUS=#{status},</if> <if test="snId!=null">SN_ID=#{snId},</if> </trim> WHERE id=#{id} </update>
这种方式是动态SQL拼接,使用trim是为了删掉最后字段的“,”
不用单独写SET了,因为set被包含在trim中了
在mybatis中使用truncate语句刷新表。
<update id="truncateTable"> truncate table [表名] </update>
@Param Parameter N/A 如果你的映射器的方法需要多个参数, 这个注解可以被应用于映射器的方法参数来给每个参数一个名字。否则,多参数将会以它们的顺序位置来被命名 (不包括任何 RowBounds 参数) 比如。 #{param1} , #{param2} 等 , 这是默认的。
如果使用 @Param(“person”), 则参数应该被命名为 #{person}。
这里重点总结一个场景,批量insert。对应sql如下:
<insert id="batchInsertIdList" parameterType="java.util.List"> insert into idlist_tmp (id, record_date) values <foreach collection="tmpInfos" item="tmpInfo" separator=","> (#{tmpInfo.id}, #{tmpInfo.recordDate}) </foreach> </insert>
这里通过#{tmpInfo.id}指定insert参数为对象tmpInfo的某个属性
int batchInsert(@Param(value = "tmpInfos") List<TmpInfo> tmpInfos);
这里通过@Param指定insert的sql中的参数引用。
CREATE TABLE `table1` ( `tab1_id` VARCHAR(11) DEFAULT NULL, `create` TIMESTAMP(3) NULL DEFAULT NULL, `create2` DATETIME(3) DEFAULT NULL ) ENGINE=INNODB DEFAULT CHARSET=utf8
设置精度的方式为:
TIMESTAMP(3)与 DATETIME(3)意思是保留3位毫秒数 TIMESTAMP(6)与 DATETIME(6)意思是保留6位毫秒数
修改字段精度的方式为:
ALTER TABLE tb_financial MODIFY CREATE_TIME DATETIME(3) DEFAULT NULL COMMENT '录入时间';
插入日期可以用NOW(3)来控制精确的毫秒数,如:SELECT CURRENT_TIMESTAMP(3);也是可以的
mybatis 批量插入数据
mybatis批量保存的两种方式(高效插入)
语法如下:
select 字段1, 字段2, case 字段3 when 值1 then 新值 when 值2 then 新值 end as 重新命名字段3的名字 from table where …… order by ……
如:
SELECT m.id AS id0, v.id AS id1, v.user_id AS userId, v.app_id AS appId ( CASE WHEN v.label = 0 THEN '清晰' WHEN v.label = 1 THEN '模糊' WHEN v.label = 2 THEN '超清晰' ELSE '其他' END ) AS '清晰度' FROM video_info v, media_info m WHERE v.id = m.id AND m.id IN ( '123123', '123124', '123125' )
参考资料: MySQL 的CASE WHEN 语句使用说明
本章节主要记录各种工具使用的技巧,如IDEA GIT等
IDEA自动导包配置方式如下: 在菜单中选择如下选项: Settings→ Editor→ General→ Auto Import 然后勾选Add unambiguous imports on the fly以及Optimize imports on the fly
解释一下含义:
Add unambiguous imports on the fly: 快速添加明确的导入。 Optimize imports on the fly: 快速优化导入,优化的意思即自动帮助删除无用的导入。
本章节主要记录打包相关的问题
通过参数引用即可解决该问题,在UNIX环境下,通过引号将带空格的参数括起来即可,如:
$ java PrintFileSizes "/home/steve/Test File.txt"
在Linux下快速查到正在侦听的端口号,命令如下:
# 安装工具包,默认已安装,centos下为yum install sudo apt install net-tools # 查看侦听中的端口 sudo netstat -ltnp
举个例子,有启动命令如下
nohup java -jar XXX.jar > /dev/null 2>&1 &
nohup表示:不挂断运行命令,当账户退出或终端关闭时,程序仍然运行。
/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;这里表示”禁止输出”。我们应当在程序内配置日志打印。
其他用法: linux环境下nohup的执行jar
这部分主要整理Spring框架相关的问题,包括SpringBoot
1.1 字符串类型的属性设置默认值 @Value("${some.key:my default value}") private String stringWithDefaultValue; 如果默认值设为空,也将会被设置成默认值。 @Value("${some.key:}") private String stringWithBlankDefaultValue; 1.2 基本类型设置默认值 布尔类型 @Value("${some.key:true}") private boolean booleanWithDefaultValue; 数字类型 @Value("${some.key:42}") private int intWithDefaultValue; 1.3 包装类型设置默认值 布尔类型 @Value("${some.key:true}") private Boolean booleanWithDefaultValue; 数字类型 @Value("${some.key:42}") private Integer intWithDefaultValue; 1.4 数组的默认值使用逗号分割 @Value("${some.key:one,two,three}") private String[] stringArrayWithDefaults; @Value("${some.key:1,2,3}") private int[] intArrayWithDefaults; 1.5 使用 Spring Expression Language (SpEL) 设置默认值 @Value("#{systemProperties['some.key'] ?: 'my default system property value'}") private String spelWithDefaultValue; 这表示:在systemProperties属性文件中,如果没有设置 some.key 的值,my default system property value 会被设置成默认值。
这里记录Jersey相关的内容
jersey获取各个参数的总结
查看WADL服务定义通过下方URL即可访问到。
http://ip:port/应用根路径/application.wadl
这里主要解析Json解析相关的技术点。
在Jackson中将JsonNode转换为Object
mapper.convertValue(jsonNode, MyPojo.class)
Jackson中的TypeReference
一般情况下如果没有TypeReference的话,JsonNode转换过来的是LinkedHashMap而不是对象本身,因此
需要使用TypeReference来进行Json的解析
如:
List<TableColumns> columns = mapper.convertValue(params.get("columns"), new TypeReference<List<TableColumns>>() {}); 对于复杂Json的转换,需要通过TypeReference解析,TypeReference可以正确反序列化嵌套多层的List或Map,例如List<Map<String,String>>
举个实际的例子,
Map<String, MarkDetail> markDetailMap = objectMapper.convertValue(haveMarkDetails, new TypeReference<Map<String,MarkDetail>>() {}); Map<String, String> dataDetailMap = objectMapper.convertValue(dataDetailJsonNode, new TypeReference<Map<String, String>>() {});
可以看到,convertValue的第二个参数是一个TypeReference实例。通过这种方式能够将复杂json类型进行正确解析。
版权声明:
原创不易,洗文可耻。除非注明,本博文章均为原创,转载请以链接形式标明本文地址。