一、json、实体、数组、集合等类型相互转换
1、接收的类型为有实体类接收的json数据:
接收从前端传过来的JSON数据,使用@RequestBody接收。如果传过来的是一个String类型的实体类数据的话,可以使用下面方法将其进行转换成对象,还有一种情况是,实体类里面嵌套了List,另外一个实体,也可以像例子2这样处理:
//例子1
User user=new User();
user = JSONObject.toJavaObject(JSONObject.parseObject(userStr),User.class);
//toJavaObject方法的源代码
public static <T> T toJavaObject(JSON json, Class<T> clazz) {
return TypeUtils.cast(json, clazz, ParserConfig.getGlobalInstance());
}
//例子2
//实体类
public class DepositSettingDto {
@ApiModelProperty("xxx")
@NotNull(message = "xxx不能為空")
private Long
private Integer
private Integer cycleDay;
......
@ApiModelProperty(value = "xxxxxxx")
@Valid
List<DepositDetail> depositDetails;
}
DepositSettingDto jsonObject = JSONObject.parseObject(depositSettingDto, DepositSettingDto.class);
2、将从数据库查询出来的数据转换成JSONArrays
List<OperatorReport> operatorReports = operatorReportMapper.listSelective(paramMap);
ArrayList<Map<String, Object> > sortList = new ArrayList<>();
for (OperatorReport ele : operatorReports) {
Map<String, Object> map = new HashMap<>();
map.put("ch",ele.getCh());
map.put("type",ele.getReportType());
String reportData = ele.getReportData();
map.put("data",JSONArray.parseArray(reportData));
map.put("title",ele.getTitle());
map.put("sort", String.format("%s.%s",ele.getSort1(),ele.getSort2()));
sortList.add(map);
}
return JSONArray.parseArray(JSON.toJSONString(sortList));
3、将jsonList数据装换成arrayList
先将String类型的json数据转换成JSONArray
JSONArray jsonArray=JSONArray.parseArray(GZIPUtils.unzip(moxie));
然后将结果遍历
for (Object ele : jsonArray) {
UserContacts userContacts = new UserContacts();
//使用JSONObject接收转换
JSONObject jsonObject = JSONObject.parseObject(ele.toString());
userContacts.setUserId(userId);
userContacts.setSumDuration(0);
userContacts.setTotalCount(0);
//再使用getJSONArray方法取出相对应的字段值,再放到封装类中保存
JSONArray phoneArray = jsonObject.getJSONArray("phone");
if (phoneArray!=null){
JSONObject phoneJson = phoneArray.getJSONObject(0);
String number = phoneJson.getString("number");
userContacts.setPhone(number.replace(" ", ""));
}
Object name = jsonObject.get("name");
if (name!=null){
userContacts.setName(name.toString());
}
try {
userContactsMapper.saveShard(tableName1, userContacts);
}catch (Exception ex) {
logger.error(String.format("保存通讯录出现异常:%s", telList),ex);
}
}
4、Map 转Json字符串
Map map = new HashMap();
map.put("success", "true");
map.put("photoList", photoList);
map.put("currentUser", "zhang");
//net.sf.json.JSONObject 将Map转换为JSON方法
JSONObject json = JSONObject.fromObject(map);
//org.json.JSONObject 将Map转换为JSON方法
JSONObject json =new JSONObject(map);
5、JSONList转对象List
// 方式二:使用TypeReference<T>类。由于其构造方法使用了protected修饰,故创建其子类
ArrayList<Student> studentList2 = JSONArray.parseObject(jsonArrayString, new TypeReference<ArrayList<Student>>() {
});
System.out.println("方式二:" + studentList2);
// 方式三:使用Gson的思想
List<Student> studentList3 = JSONArray.parseArray(jsonArrayString, Student.class);
System.out.println("方式三:" + studentList3);
6、构造类型转换
String jsonString = JSON.toJSONString(segments);
TypeReference typeReference = new TypeReference<List<List<Long>>>() {
};
List<List<Long>> newSegments = JSON.parseObject(jsonString, typeReference.getType());
newSegments.sort(Comparator.comparing(segment -> segment.get(0)));
7、java BigDecimal去掉小数点后的零
new BigDecimal("100.000").stripTrailingZeros().toPlainString()
二、项目中mybatis使用的一些常用技巧
1、在mybatis配置文件中编写sql的时候,如果想给某个字段默认值,可以在字段上加上
<sql id="Base_Column_List">
ID, ifnull(PREPAYMENT_FEE,0) as PREPAYMENT_FEE
</sql>
2、在mybatis中进行模糊查询
<if test="realName !='' and realName !=null">
u.real_name like concat("%",#{realName,jdbcType=VARCHAR},"%")
</if>
3、在mybatis中,接收List类型的参数放到in中查询
<select id="queryDaysAcount" resultType="ct.lsm.admin.customer.model.dto.CustomerDto">
select a.customer_id as id,DATEDIFF(NOW(),a.createTiem) as days from (select customer_id,max(create_time) as createTiem from lsm_customer_login_log where customer_id in
<foreach item="item" index="index" collection="list" open="(" separator="," close=")">
#{item}
</foreach>
GROUP BY customer_id) a
</select>
4、在mybatis中,时间段查询
<if test="startTime != null">
and DATE_FORMAT(r.repay_time,'%Y-%m-%d') >= #{startTime,jdbcType=TIMESTAMP}
</if>
<if test="endTime != null">
and DATE_FORMAT(r.repay_time,'%Y-%m-%d') <= #{endTime,jdbcType=TIMESTAMP}
</if>
5、查看数据库中保存的时间戳,转成时间方便查看
select operate_type,FROM_UNIXTIME(work_time/1000,'%Y-%m-%d %H:%i:%s') from driver_work_time_record where driver_id=6852285 and work_time BETWEEN 1600840800000 and NOW() ORDER BY work_time desc
6、查看重复记录
select * from driver_fatigue_driving_long_stay_alarm a where (a.driver_id) in (select driver_id from driver_fatigue_driving_long_stay_alarm group by driver_id having count(*) > 1)
三、Map 排序
1、HashMap、Hashtable、LinkedHashMap排序
(转自:https://www.cnblogs.com/lzq198754/p/5780165.html)
注:
TreeMap也可以使用此方法进行排序,但是更推荐下面的方法。
Map<String, String> map = new HashMap<String, String>();
map.put("a", "c");
map.put("b", "b");
map.put("c", "a");
// 通过ArrayList构造函数把map.entrySet()转换成list
List<Map.Entry<String, String>> list = new ArrayList<Map.Entry<String, String>>(map.entrySet());
// 通过比较器实现比较排序
Collections.sort(list, new Comparator<Map.Entry<String, String>>() {
public int compare(Map.Entry<String, String> mapping1, Map.Entry<String, String> mapping2) {
return mapping1.getKey().compareTo(mapping2.getKey());
}
});
for (Map.Entry<String, String> mapping : list) {
System.out.println(mapping.getKey() + " :" + mapping.getValue());
}
2、TreeMap排序
TreeMap默认按key进行升序排序,如果想改变默认的顺序,可以使用比较器:
Map<String, String> map = new TreeMap<String, String>(new Comparator<String>() {
public int compare(String obj1, String obj2) {
return obj2.compareTo(obj1);// 降序排序
}
});
map.put("a", "c");
map.put("b", "b");
map.put("c", "a");
for (String key : map.keySet()) {
System.out.println(key + " :" + map.get(key));
}
3、按value排序(通用)
Map<String, String> map = new TreeMap<String, String>();
map.put("a", "c");
map.put("b", "b");
map.put("c", "a");
// 通过ArrayList构造函数把map.entrySet()转换成list
List<Map.Entry<String, String>> list = new ArrayList<Map.Entry<String, String>>(map.entrySet());
// 通过比较器实现比较排序
Collections.sort(list, new Comparator<Map.Entry<String, String>>() {
public int compare(Map.Entry<String, String> mapping1, Map.Entry<String, String> mapping2) {
return mapping1.getValue().compareTo(mapping2.getValue());
}
});
for (String key : map.keySet()) {
System.out.println(key + " :" + map.get(key));
}
4、常用API
clear() | 从 Map 中删除所有映射 |
remove(Object key) | 从 Map 中删除键和关联的值 |
put(Object key, Object value) | 将指定值与指定键相关联 |
putAll(Map t) | 将指定 Map 中的所有映射复制到此 map |
entrySet() | 返回 Map 中所包含映射的 Set 视图。Set 中的每个元素都是一个 Map.Entry 对象,可以使用 getKey() 和 getValue() 方法(还有一个 setValue() 方法)访问后者的键元素和值元素 |
keySet() | 返回 Map 中所包含键的 Set 视图。删除 Set 中的元素还将删除 Map 中相应的映射(键和值) |
values() | 返回 map 中所包含值的 Collection 视图。删除 Collection 中的元素还将删除 Map 中相应的映射(键和值) |
get(Object key) | 返回与指定键关联的值 |
containsKey(Object key) | 如果 Map 包含指定键的映射,则返回 true |
containsValue(Object value) | 如果此 Map 将一个或多个键映射到指定值,则返回 true |
isEmpty() | 如果 Map 不包含键-值映射,则返回 true |
size() | 返回 Map 中的键-值映射的数目 |
ArrayList 遍历
List<String> list = new ArrayList<>();
list.add("xiaohei");
list.add("xiaoming");
list.add("huanhai");
list.add("lidazao");
list.add("chenping");
// String[] strings=new String[list.size()];
// list.toArray(strings);
Iterator<String> iterable = list.iterator();
while (iterable.hasNext()) {
System.out.println(iterable.next());
}
Map 遍历
Map<String, Object> map = new HashMap<>();
map.put("1", 12312);
map.put("2", "q34das");
map.put("3", 724309);
// for (String key : map.keySet()) {
// System.out.println("key=" + key + " value=" + map.get(key));
// }
//第三种:推荐,尤其是容量大时
for (Map.Entry<String, Object> entry : map.entrySet()) {
System.out.println("key=" + entry.getKey() + " value=" + entry.getValue());
}
四、MySQL使用技巧
1、当查询某个字段为空的时候处理方式:
(case when l.due_time is NOT NULL then l.due_time when l.due_time is NULL then r.repay_time end) dueTime,
<!--或者-->
ifnull(l.due_time,l.due_time) as dueTime,
2、查询当天数据
select count(distinct(user_id)) as loginUserCount, count(id) as loginCount from cl_user_login_log
where create_time BETWEEN DATE_FORMAT(NOW(),'%Y-%m-%d 00:00:00') AND DATE_FORMAT(NOW(),'%Y-%m-%d 23:59:59')
在查询某个值为什么的时候,取另一个值的时候,可以使用case when ..... then ..... else ....end 来实现
select id,user_id,create_time,count(id) as borrowAmount,case when state=30 then count(id) else 0 end as borrowRepayAmout from cl_borrow GROUP BY user_id ORDER BY id
3、分组查询最新一条记录
select a.borrow_id,a.due_time,a.amount from cl_borrow_repay_log a inner join (select borrow_id,max(id) id from cl_borrow_repay_log group by borrow_id)b on a.borrow_id=b.borrow_id and a.id=b.id order by a.borrow_id
4、MySQL的and和or优先级
例:
select * from table where 条件1 AND 条件2 OR 条件3
等价于
select * from table where ( 条件1 AND 条件2 ) OR 条件3
select * from table where 条件1 AND 条件2 OR 条件3 AND 条件4
等价于
select * from table where ( 条件1 AND 条件2 ) OR ( 条件3 AND 条件4 )
5、MySQL中的时间转换指定格式问题
select COUNT(1) as successOrderCount from cl_urge_repay_log l,cl_urge_repay_order o where l.borrow_id=o.borrow_id and l.state=40 and DATE_FORMAT(l.create_time,"%Y-%m-%d")=DATE_FORMAT("2019-07-23 14:53:35.807",'%Y-%m-%d')
这两者查询的结果是不一致的,在指定时间格式的时候,=号两边的类型要一致
select COUNT(1) as successOrderCount from cl_urge_repay_log l,cl_urge_repay_order o where l.borrow_id=o.borrow_id and l.state=40 and DATE_FORMAT(l.create_time,"%Y-%m-%d")=DATE_FORMAT("2019-07-23 14:53:35.807",'%y-%m-%d')
6、如果只需要取年月日,可以使用CURDATE()函数取当前时间,不需要再使用DATE-FORMAT(NOW(),'%Y-%m-%d')
SELECT IFNULL(SUM(amount),0),DATE(create_time) FROM cl_borrow_repay WHERE DATE(create_time) = CURDATE()
7、MySQL 为日期增加一个时间间隔:date_add()
now() //now函数为获取当前时间
select date_add(now(), interval 1 day); - 加1天
select date_add(now(), interval 1 hour); -加1小时
select date_add(now(), interval 1 minute); - 加1分钟
select date_add(now(), interval 1 second); -加1秒
select date_add(now(), interval 1 microsecond);-加1毫秒
select date_add(now(), interval 1 week);-加1周
select date_add(now(), interval 1 month);-加1月
select date_add(now(), interval 1 quarter);-加1季
select date_add(now(), interval 1 year);-加1年
MySQL adddate(), addtime()函数,可以用date_add() 来替代。
2. MySQL 为日期减去一个时间间隔:date_sub()
MySQL date_sub() 日期时间函数 和date_add() 用法一致。
MySQL 中subdate(),subtime()函数,建议,用date_sub()来替代。
8、判断数据库中某个字段是否包含某个字符(是否INSTR函数判断)
cycle值为1,2
case when INSTR(l.cycle,",")>0 then 0 else c.money end as repay_amount,
9、postgres重置自增长id列(reset sequence)
ALTER SEQUENCE seq RESTART WITH 1;
说明:seq是对应要重置自增长列名字
五、项目代码中常用技巧或处理方式
1、实现某个值是动态显示
可以在数据库中存一段文字,然后在需要替换的位置用特殊符号填写,在需要使用到的时候,再替换即可。
case LSM_REGISTER:
return msgSmsTplEntity.getTpl().replace("{$vCode}",vCode);
尊敬的用户,您的登陆验证码为:{$vCode}
2、分页
在使用PageHelper插件进行PageHelper.startPage设一定是紧跟着查询才有效,并在sql上面一行。
PageHelper.startPage(current, pageSize);
Page<FriendTicketCountDto> page=(Page<FriendTicketCountDto>)accelerationTicketService.getFriendTicketCount(userId);
3、将一串字符串放到数组里面
String borrowCredit = Global.getValue("borrow_credit");//1500,6000
String[] credits = borrowCredit.split(",");
double maxCredit = Double.parseDouble(credits[credits.length-1]);
double minCredit = Double.parseDouble(credits[0]);
易错点:
@Autowired按byType自动注入,而@Resource默认按 byName自动注入
4、生成随机验证码
private String randomSmsCode(int len) {
Random random = new Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < len; i++) {
byte value = (byte)random.nextInt(10);
sb.append(value);
}
return sb.toString();
}
在查询数据的时候或者需要修改的时候,需要对结果集进行判断是否为空,否则会很容易出现报空指针异常。
要养成这个习惯。
if (user != null && user.getId() != null) {
//用户基本信息
ManagerUserModel model = userBaseInfoService.getBaseModelByUserId(userId);
model.setLivingImg(model.getLivingImg() != null ? serverHost + "/readFile.htm?path=" + model.getLivingImg() : "");
model.setFrontImg(model.getFrontImg() != null ? serverHost + "/readFile.htm?path=" + model.getFrontImg() : "");
model.setBackImg(model.getBackImg() != null ? serverHost + "/readFile.htm?path=" + model.getBackImg() : "");
model.setOcrImg(model.getOcrImg() != null ? serverHost + "/readFile.htm?path=" + model.getOcrImg() : "");
5、String.spilt()的使用
在java.lang包中有String.split()方法,返回是一个数组
我在应用中用到一些,给大家总结一下,仅供大家参考:
1、如果用“.”作为分隔的话,必须是如下写法,String.split("\\."),这样才能正确的分隔开,不能用String.split(".");
2、如果用“|”作为分隔的话,必须是如下写法,String.split("\\|"),这样才能正确的分隔开,不能用String.split("|");
“.”和“|”都是转义字符,必须得加"\\";
3、如果在一个字符串中有多个分隔符,可以用“|”作为连字符,比如,“acount=? and uu =? or n=?”,把三个都分隔出来,可以用String.split("and|or");
使用String.split方法分隔字符串时,分隔符如果用到一些特殊字符,可能会得不到我们预期的结果。
6、JSON数据按某个值排序
public JSONArray sortJsonArray(JSONArray jsonArray){//第一排序是6个月通话次数,第二排序是6个月通话时长,倒序排
JSONArray sortJsonArray = new JSONArray();
List<JSONObject> jsonValue = new ArrayList<JSONObject>();
for (int i = 0; i < jsonArray.size(); i++){
jsonValue.add(jsonArray.getJSONObject(i));
}
Collections.sort(jsonValue, new Comparator<JSONObject>() {
private static final String key = "call_cnt_6m";
private static final String key2="call_time_6m";
@Override
public int compare(JSONObject o1, JSONObject o2) {
int va1 = o1.getIntValue(key);
int va2 = o2.getIntValue(key);
int va3 = o1.getIntValue(key2);
int va4 = o2.getIntValue(key2);
if (va1==va2){
return va3-va4;
}else {
return va1-va2;
}
}
});
for(int i = 0; i < jsonArray.size(); i++){
sortJsonArray.add(jsonValue.get(i));
}
return sortJsonArray;
}
7.Java 8 的Stream流一些高级操作
//joining拼接:
String s = list.stream().map(Person::getName).collect(joining(","));
//groupingBy 分组
//groupingBy 用于将数据分组,最终返回一个 Map 类型
//Person年龄一样的,放到一组里面
Map<Integer, List<Person>> map = list.stream().collect(groupingBy(Person::getAge));
//多级分组
Map<Integer, Map<T, List<Person>>> map = list.stream().collect(groupingBy(Person::getAge, groupingBy(...)));
8.List集合排序逆转
List<DriverWorkTimeResponse> driverWorkTimeResponseList = response.getData().getData();
if(CollectionUtils.isEmpty(driverWorkTimeResponseList)){
return null;
}
List<String> memberList = new ArrayList<>();
Set<ZSetOperations.TypedTuple<String>> typedTupleSet = new HashSet<ZSetOperations.TypedTuple<String>>();
//因为上面那个查询方法是倒叙的,所以这翻转一下
Collections.reverse(driverWorkTimeResponseList);
9.stream().sorted()用法
//下面代码以自然序排序一个list
list.stream().sorted()
//自然序逆序元素,使用Comparator 提供的reverseOrder() 方法
list.stream().sorted(Comparator.reverseOrder())
//使用Comparator 来排序一个list
list.stream().sorted(Comparator.comparing(Student::getAge))
//把上面的元素逆序
list.stream().sorted(Comparator.comparing(Student::getAge).reversed())
六、Linux命令
1、linux切换超级管理员权限
如果需要持续超级用户权限,安装的软件多时 ,先终端运行 sudo su,提示输入密码,获取持续超级权限,上例命令,就可以直接用 apt-get install libpcre3. 其实sudo 中su就是super user的简写。还有sudo -i 也可以获取超级用户权限。
2、如果需要下载服务器上某个文件
sz cashloan.log
3、搜索日志
?插入是否成功
搜索查找:n 上一页 N 下一页
翻页 ctrl+f 下一页 ctrl+b 上一页 或者直接按 f 或b xshell版本不一样,快捷键也不一样
回到最后一页 shift+g
实时查看日志并筛选某个值
tail -n 行数 -f 文件夹路径以及 名字,用于查看log 后面可以追加 | grep +名字 用于过滤
tail -n 40 -f /data/weblog/java/ruqi-account-server/info.log |grep 小明
在vim模式下 yy可以直接复制整行文字,在打开一个文件的时候,直接按p粘贴所复制的内容
新建文件 touch test
按i进入插入模式
:wq 保存并退出
:q! 强制退出并忽略所有更改
:e! 放弃所有修改,并打开原来文件。
查看文件大小: ll -h
修改该文件的权限:
chmod 777 Test.sh
补充:chmod是分配文件权限,一般后面会带三个数字,例如 chmod abc Test.sh (abc代表三个数字,三个数字其实是对应的二进制)
a:是文件所有者的权限 b:与文件所有者同属一个用户组的其他按用户的权限 c:其他用户组的权限
权限一共有三种 r(可读) w(可写) x(可执行) 其中 有可读r权限,则r是4 有可写w权限,则w是2 有可执行x权限,则x是1 (其实是二进制111,r是第一个1代表十进制4 , w是第二个1代表2,x是第三个1代表1)
所以一共有四种权限分配(默认都是可读的) ① rw- (可读可写不可执行): 二进制是110 转化为十进制是4+2 = 6
② r-x(可读不可写可执行):二进制是101 转化为十进制是4+1 = 5
③ rwx(可读可写可执行) :二进制是111 转化为十进制是4+2+1 = 7
④ r--(只可读):二进制100 转化为十进制是4
例如 chmod 777 Test.sh(所有人都有可读可写可执行的权限)
chmod 765 Test.sh(文件所有者有所有权限,同用户组的有读写权限,不同组的其他用户有读和执行权限)
杀僵尸进程
查看僵尸进程:ps -A -ostat,ppid,pid,cmd |grep -e '^[Zz]' 或者top
kill -9 端口号
七、常用软件安装
1、redis设置登陆密码
config set requirepass 123456
2、码云上新建仓库
一、仓库就已经新建好了
二、在本地项目目录下,右键选择gitBash,使用git init将本地目录变成git本地仓库,使用git status可以查看本地目录的状态信息
git init
git status
三、将你本地仓库与码云上的远程仓库关联起来
git remote add origin https://gitee.com/fasda6/demo.git
四、在你准备上传你的项目之前,最好更新一下项目,确保没有和远程仓库的代码有冲突
git pull --rebase origin master
五、把你的项目复制到这个目录下,用命令添加你要上传的项目,再提交到本地暂存区,最后把本地仓库项目提交到远程仓库。
git add . 添加目录下所有发生改变的文件
git commit -m '注释信息'
git push -u origin master 本地仓库代码提交至远程仓库
windows命令行
使用 Win键+其他键组合:
Win键:打开“开始”菜单
Win键+E:打开我的电脑
Win键+R:打开运行对话框
Win键+D:显示桌面
Win键+M:最小化所有窗口
Win键+X:Windows移动中心,调节音量,屏幕亮度
Win键+Home:除了正在选择的窗口,其他窗口最小化
Win键+PAUSE BREAK:打开“系统属性”对话框
Win键+【+/-】:打开Windows放大、缩小功能
Win键+Pause:显示系统属性对话框
Win键+TAB:Aero三维效果切换程序
Win键+数字键:让位于任务栏上的程序打开(数字为序号)
Win键+P:选择一个演示文稿显示模式,可以用来关闭屏幕
Win键+L:锁定计算机,需要输入密码或者选择其他用户
Win键+T:多次按可以在多个程序间顺序切换
Win键+F:计算机搜索,可以搜索计算机里面所有文件
Win键+【←/→】:在屏幕左/右半个屏幕最大化
Win键+【↑/↓】:最大化/最小化
Springboot项目不能直接读取Resource下的文件,
String data = "";
ClassPathResource cpr = new ClassPathResource("config/contractTpl/ht.html");
try {
byte[] bdata = FileCopyUtils.copyToByteArray(cpr.getInputStream());
data = new String(bdata, StandardCharsets.UTF_8);
} catch (IOException e) {
logger.warn("IOException", e);
}
springboot设置浏览器预览或者强制下载
//设置头信息使浏览器下载文件或预览
//强制浏览器下载
response.setHeader("content-disposition", "attachment;filename=" + realName);
//浏览器尝试打开,支持office online或浏览器预览pdf功能
response.setHeader("content-disposition", "inline;filename=" + realName);
记一次数据库锁表解决方法
mysql查询中,一直报Lock wait timeout exceeded; try restarting transaction;
解决方法:
1:查找提交事务的线程
select * from information_schema.innodb_trx;
2:kill掉正在执行的线程
kill thread_id;注意:thread_id 是 trx_mysql_thread_id 的值
3:增加锁等待的时间(可有可无)
innodb_lock_wait_timeout=500
获取IP与域名方法二,使用java工具类实现,调用方式getIP(URI.create(“需要处理的url地址“);
private static URI getIP(URI uri) {
URI effectiveURI = null;
try {
effectiveURI = new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(), null, null, null);
} catch (Throwable var4) {
effectiveURI = null;
}
return effectiveURI;
}
(后续未完,待更新......)