编辑
2023-07-07
遇到的问题
00

前因

后端接受前端的时间是yyyy-mm-ss格式,但是使用mybatis查询这个时间的时候,会变成yyyy-MM-ss 08:00:00, 自动加上八小时,不是我想要的0时,就导致查询的时候出现了很多错误数据

解决方式

接受时间的实体,需要加上JsonFormat 注解

java
@ApiModelProperty(value="出院时间开始") @NotNull(message = "出院开始时间不能为空") @DateTimeFormat(pattern = "yyyy-MM-dd") @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8") private Date dischargeTimeBegin; @ApiModelProperty(value="出院时间截止") @NotNull(message = "出院截止时间不能为空") @DateTimeFormat(pattern = "yyyy-MM-dd") @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8") private Date dischargeTimeEnd;

因为jsonformat是对json格式有效,会格式化返回值,他和@DateTimeFormat注解是相辅相成的,具体可以看我的这篇文章

编辑
2023-07-07
实用工具
00

DateUtil

java
package com.lhw.utils; import com.lhw.common.ResultCodeEnum; import com.lhw.exception.BusinessException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; public class DateUtils { /** * 字符串转换为java.util.Date<br> * 支持格式为 yyyy.MM.dd G 'at' hh:mm:ss z 如 '2017-12-12 AD at 22:10:59 PSD'<br> * yy/MM/dd HH:mm:ss 如 '2017/12/12 17:55:00'<br> * yy/MM/dd HH:mm:ss pm 如 '2017/12/12 17:55:00 pm'<br> * yy-MM-dd HH:mm:ss 如 '2017-12-12 17:55:00' <br> * yy-MM-dd HH:mm:ss am 如 '2017-12-12 17:55:00 am' <br> * @param time String 字符串<br> * @return Date 日期<br> */ public static Date stringToDate(String time){ SimpleDateFormat formatter =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { int len = time.length(); time=time.replace(":","") .replace("-","") .replace("/","") .replace(" ",""); ArrayList<String> formatterList=new ArrayList<>(); formatterList.add("yyyyMMdd"); formatterList.add("yyyyMMddHHmm"); formatterList.add("yyyyMMddHHmm"); formatterList.add("yyyyMMddHHmmss"); for (String strFormatter:formatterList ) { if(strFormatter.length()==time.length()) formatter=new SimpleDateFormat(strFormatter); } return formatter.parse(time); } catch (Exception e) { throw new BusinessException(ResultCodeEnum.ERR_0x1000.getCode(), e.getMessage()); } } public static boolean afterDate(Date d1, Date d2) { DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); try { String strFirstDate = dateFormat.format(d1); d1 = dateFormat.parse(strFirstDate); String strSecondDate = dateFormat.format(d2); d2 = dateFormat.parse(strSecondDate); } catch (Exception e) { // 日期型字符串格式错误 throw new BusinessException(ResultCodeEnum.ERR_0x1000.getCode(), "日期型字符串格式错误。"+e.getMessage()); } int betweenDays = 0; Calendar c1 = Calendar.getInstance(); Calendar c2 = Calendar.getInstance(); c1.setTime(d1); c2.setTime(d2); if(c1.after(c2)){ return true; }else return false; } public static boolean beforeDate(Date d1, Date d2) { DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); try { String strFirstDate = dateFormat.format(d1); d1 = dateFormat.parse(strFirstDate); String strSecondDate = dateFormat.format(d2); d2 = dateFormat.parse(strSecondDate); } catch (Exception e) { // 日期型字符串格式错误 throw new BusinessException(ResultCodeEnum.ERR_0x1000.getCode(), "日期型字符串格式错误。"+e.getMessage()); } int betweenDays = 0; Calendar c1 = Calendar.getInstance(); Calendar c2 = Calendar.getInstance(); c1.setTime(d1); c2.setTime(d2); if(c1.before(c2)){ return true; } else return false; } public static int getBetweenDays(Date d1, Date d2) { DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); try { String strFirstDate = dateFormat.format(d1); d1 = dateFormat.parse(strFirstDate); String strSecondDate = dateFormat.format(d2); d2 = dateFormat.parse(strSecondDate); } catch (Exception e) { // 日期型字符串格式错误 throw new BusinessException(ResultCodeEnum.ERR_0x1000.getCode(), "日期型字符串格式错误。"+e.getMessage()); } int betweenDays = 0; Calendar c1 = Calendar.getInstance(); Calendar c2 = Calendar.getInstance(); c1.setTime(d1); c2.setTime(d2); // 保证第二个时间一定大于第一个时间 if(c1.after(c2)){ c1.setTime(d2); c2.setTime(d1); } int betweenYears = c2.get(Calendar.YEAR)-c1.get(Calendar.YEAR); betweenDays = c2.get(Calendar.DAY_OF_YEAR)-c1.get(Calendar.DAY_OF_YEAR); for(int i=0;i<betweenYears;i++){ int tmp=countDays(c1.get(Calendar.YEAR)); betweenDays+=countDays(c1.get(Calendar.YEAR)); c1.set(Calendar.YEAR,(c1.get(Calendar.YEAR)+1)); } return betweenDays; } public static int countDays(int year){ int n=0; for (int i = 1; i <= 12; i++) { n += countDays(i,year); } return n; } public static int countDays(int month, int year){ int count = -1; switch(month){ case 1: case 3: case 5: case 7: case 8: case 10: case 12: count = 31; break; case 4: case 6: case 9: case 11: count = 30; break; case 2: if(year % 4 == 0) count = 29; else count = 28; if((year % 100 ==0) & (year % 400 != 0)) count = 28; } return count; } /** * * @Description: 将日期转换为字符串 * @author yehui * @version 2016年12月27日 下午1:19:15 * @param date * @param format * 转化格式,如:yyyy-MM-dd HH:mm:ss * @return * */ public static String formatDateToString(Date date, String format) { SimpleDateFormat sdf = new SimpleDateFormat(format); String str = sdf.format(date); return str; } public static Date addDays(Date date,int days){ Calendar calendar=Calendar.getInstance(); calendar.setTime(date); calendar.add(Calendar.DAY_OF_YEAR,days); return calendar.getTime(); } }
编辑
2023-07-06
学习记录
00

汇总

23种设计模式被分为三大类:创建型模式、结构型模式、行为型模式

创建型结构型行为型
单例模式适配器模式观察者模式
工厂方法模式装饰器模式模板方法模式
抽象工厂模式代理模式策略模式
建造者模式外观模式命令模式
原型模式桥接模式职责链模式
-组合模式状态模式
-享元模式访问者模式

七大原则:

  1. 开放封闭原则
  2. 单一职责原则
  3. 依赖倒置原则
  4. 接口隔离原则
  5. 里氏替换原则
  6. 迪米特原则
  7. 合成复用原则

创建型

单例模式

单例模式(Singleton Pattern)是一种常用的软件设计模式,它保证一个类只有一个实例,并提供了一个全局访问点。分为饿汉式和懒汉式,饿汉式是直接初始化类对象,而懒汉式是需要使用到对象再初始化

以下是单例模式的示例代码:

java
public class Singleton { private static Singleton instance; private Singleton() { // 私有构造函数,防止其他类从外部创建实例 } public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }

在这个示例中,Singleton 类是一个单例类,它只有一个实例。通过 getInstance() 方法获取单例实例。如果实例不存在,则创建一个新的实例。

单例模式在软件开发中有很多用途。以下是一些常见的应用场景:

数据库连接池:在一个系统中,数据库连接池的实例只需要一个,通过单例模式可以确保每个线程都使用相同的数据库连接池。

日志记录器:日志记录器通常只需要一个实例,通过单例模式可以确保所有的日志信息都写入同一个日志文件中。

配置管理器:在一个系统中,配置管理器只需要一个实例,通过单例模式可以确保所有的配置信息都来自于同一个实例。

线程池:在一个系统中,线程池只需要一个实例,通过单例模式可以确保所有的任务都分配到同一个线程池中执行。

需要注意的是,单例模式并不是适用于所有的场景。在多线程环境下,需要考虑到线程安全问题,可以使用线程安全的单例实现方式。同时,在某些情况下,可能需要根据不同的需求创建多个实例,因此需要根据具体的需求来决定是否使用单例模式。

编辑
2023-07-05
学习记录
00

汇总

序号锁名称应用
1乐观锁CAS
2悲观锁synchronized、vector、hashtable
3自旋锁 CAS
4可重入锁synchronized、Reentrantlock、Lock
5读写锁ReentrantReadWriteLock,CopyOnWriteArrayList、CopyOnWriteArraySet
6公平锁Reentrantlock(true)
7非公平锁synchronized、reentrantlock(false)
8共享锁ReentrantReadWriteLock中读锁
9独占锁synchronized、vector、hashtable、ReentrantReadWriteLock中写锁
10重量级锁synchronized
11轻量级锁锁优化技术
12偏向锁锁优化技术
13分段锁concurrentHashMap
14互斥锁 synchronized
15同步锁synchronized
16死锁相互请求对方的资源
17锁粗化锁优化技术
18锁消除锁优化技术

1、乐观锁

乐观锁

乐观锁是一种乐观思想,假定当前环境是读多写少,遇到并发写的概率比较低,读数据时认为别的线程不会正在进行修改(所以没有上锁)。写数据时,判断当前 与期望值是否相同,如果相同则进行更新(更新期间加锁,保证是原子性的)。

Java中的乐观锁: CAS,比较并替换,比较当前值(主内存中的值),与预期值(当前线程中的值,主内存中值的一份拷贝)是否一样,一样则更新,否则继续进行CAS操作。

如上图所示,可以同时进行读操作,读的时候其他线程不能进行写操作。

2、悲观锁

悲观锁

悲观锁是一种悲观思想,即认为写多读少,遇到并发写的可能性高,每次去拿数据的时候都认为其他线程会修改,所以每次读写数据都会认为其他线程会修改,所以每次读写数据时都会上锁。其他线程想要读写这个数据时,会被这个线程block,直到这个线程释放锁然后其他线程获取到锁。

Java中的悲观锁: synchronized修饰的方法和方法块、ReentrantLock。

如上图所示,只能有一个线程进行读操作或者写操作,其他线程的读写操作均不能进行。

编辑
2023-07-01
前端
00

安装yarn

查询当前镜像

npm get registry

全局安装yarn

npm install -g yarn

看一下yarn版本,运行以下命令

yarn -v

改为淘宝镜像

yarn config set registry https://registry.npm.taobao.org 最新地址

npm config set registry https://registry.npmmirror.com

安装项目依赖

yarn install

运行项目

yarn run dev

打包

yarn run build