前言:近期收到一个需求,大体是通过数据库查询来校验是否之前已经做过相关的业务。其中,比较不同的大致有两点:月份的计算和名称的匹配。记录学习一下,希望大家不要踩坑。
一:Oracle相关
1:月份计算
需求:页面录入的日期与数据库中的月份进行比对,小于等于8个月的单子即符合,注意:不考虑天数。
1:to_char月份计算
将日期to_char之后直接进行两个月份数字的计算,得到的即为月份差。如果是负数加abs()取绝对值即可。
但是很快,我就发现了问题,如果在同一年,这样是行得通的。但是如果跨年的话,就不能这样使用,会出现计算错误。
2:month_between月份计算
一开始我是想用这个的,因为感觉有些问题所以放弃了,但其实是可以解决的。
month_between如果用原始时间去比较的话,会出现小数点,例如:
虽然这不是问题,但是对于我这个需求而言是不符合的(只计算月份)。
所以最后使用的方式是,转换日期格式,先将日期转为年、月的格式,再转换日期格式计算。
此方式跨年计算也是正常的。但是代码不太好看,大家可以参考一下。
2:Oracle分页查询
Oracle经典三层分页查询:内层控制排序,中间层固定行号,最外层控制条数。
区别是之前查资料发现一个优化方面的东西。
select * from
(select r.* , rownum rn from
(select* from qt _policy_apply e order by e.id desc) r
where rownum <= 50)
where rn > 0
大致意思就是,这样写oracle会进行优化,可以将中间层的rownum<=50带入到内层中查询,查询结果一旦超过rownum行数限制就停止查询,效率会提高。而如果将两个条件放一起,则不能实现带入内层查询,效率偏低。
二:String字符串操作
1:去除指定字符串
对于去除指定的字符串,可以有很多方式,例如拆成char数组循环去除,subString截取等,这里使用subString实现该业务。
//需要注意:要去除的字符串必须在原字符串包含,否则indexOf为-1,会越界
StringBuilder newStr = new StringBuilder("qwertyuio");
List<String> assignList = Arrays.asList("qw","t","io");
for (String assignStr : assignList){
if(newStr.toString().contains(assignStr)){
if (newStr.indexOf(assignStr) == 0) {
//在开头
newStr= new StringBuilder(newStr.substring(assignStr.length()));
} else if (newStr.indexOf(assignStr) == newStr.length() - assignStr.length()) {
//在结尾
newStr = new StringBuilder(newStr.substring(0, newStr.lastIndexOf(assignStr)));
} else if (newStr.indexOf(assignStr) < (newStr.length() - assignStr.length())) {
//在中间
String frontStr = newStr.substring(0, newStr.indexOf(assignStr));
String lastStr = newStr.substring(newStr.indexOf(assignStr) + assignStr.length());
newStr = new StringBuilder(frontStr + lastStr);
}
}
}
System.out.println(newStr);
这里介绍下用的subString,对于参数的不同,subString所表达的含义不同。
如:subString(2),单个参数,代表删除从0 - 2位置的字符串。
subString(2,6),两个参数,代表截取2 - 6位置的字符串。
这里主要是截止于indexOf和字符串长度进行的各段的截取操作,但是要注意,需要截取的字符串一定要先判断是否在原字符串中包含,不包含的话indexOf会得到-1,而操作-1位置会发生异常。
2:匹配指定数量的字符串
需求:用姓名去匹配数据库中的姓名,如果有三个连续的字符合,即为重复的数据。
具体实现有几种方式,双层for循环、indexOf、contains等。
1:双层for循环方式
此种方式可以实现,但是代码不太美观。因为要判断连续的三个字符合,所以循环时,如果有一个字不符合,外层加1,内层从头开始,所以变量大多要定义在外边,在每个节点完成后对变量更新,代码不直观且可能有性能问题。
2:使用contains判断方式
在实际项目使用中,要注意检验字段不为空且字符串长度是否符合要求,如我这里要求长度大于等于3才继续。
对于核心代码,我们需要注意的是:不要数组下标越界
//匹配指定数量字符串,实际使用需要判空及判断字符串长度是否符合
String strA = "qwertyuio";
String strB = "11tyu22";
char[] charArrayB = strB.toCharArray();
//遍历长度小的字符串,长度-2,防止下标越界,用于后续连续字符串拼接
for (int i = 0; i < strB.length() - 2; i++) {
//获取三个连续的字
String adjacentStr = String.valueOf(charArrayB[i]) + charArrayB[i + 1] + charArrayB[i + 2];
if (strA.contains(adjacentStr)) {
System.out.println("符合条件");
}
}
遍历长度小的字符串,组装连续的字符串,判断另一个字符串是否包含,包含即符合。
3:char类型转String
char类型是基本类型,比较直接使用==,比较的是两个字符的ASCII表对应的整数。
并且,char类型转String类型时候,可以直接加" "空字符串,也可以String.valueOf()转换,但是注意要在开头添加,如果在结尾添加,会将char字符对应的编码相加后再转换字符串。
到这里就结束了,学习是一个不断积累的过程,不断的努力才是王道。如果哪里有问题,欢迎大家指正。