常用代码块和工具类
一、后端:
1. 字符串相关
1.1 随机生成字符串
import java.util.UUID;
String substring = UUID.randomUUID().toString().substring(0, 5);
1.2 随机生成订单号
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
String orderNumber = IdWorker.getIdStr() // 雪花算法生成
1.3 字符串非空判断
import org.springframework.util.StringUtils;
boolean hasLength = StringUtils.hasLength("string");
2. Java对象复制
2.1.1 对象复制方法一
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
import org.springframework.beans.BeanUtils;
/*
* 两个包中的copyProperties方法目标对象和源对象参数的位置是相反。
* 目标对象中包含源对象的所有字段时:两个包下的copy方法都可以,而且目标对象中多于的对象的值不会被覆盖掉。
* 目标对象中不包含源对象的所有字段时:应选用org.springframework.beans.BeanUtils下的copyProperties方法。
*/
BeanUtils.copyProperties(pageInfo, pageInfoCopy, "records"); // 左边复制到右边
2.1.2 对象复制方法二
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.4</version>
</dependency>
import org.apache.commons.beanutils.BeanUtils;
BeanUtils.copyProperties(pageInfoCopy, pageInfo, "records"); // 右边复制到左边
3. 集合操作
3.1 Map集合 --> Java对象
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.4</version>
</dependency>
import org.springframework.beans.BeanUtils;
Map<String, String[]> parameterMap = req.getParameterMap();
Brand brand = new Brand();
try {
// 用来将一些 key-value 的值(例如 parameterMap)映射到 bean(例如 brand)中的属性。
BeanUtils.populate(brand, parameterMap);
} catch (Exception e) {
e.printStackTrace();
}
3.2 List集合 --> Map集合
// List集合转Map集合
// 以用户名作为key,以User对象作为value
Map<String, User> userMap =
userList.stream().collect(Collectors.toMap(User::getName, Function.identity()));
3.3 List集合 --> String
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
// [images01.jpg, images02.jpg] --> "images01.jpg, images02.jpg"
List<String> list = new ArrayList<>();
list.add("images01.jpg");
list.add("images02.jpg");
String imageStr = StringUtils.join(list, ",");
4. JSON串–>Java对象
4.1 方法一
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
- 1、Java对象转JSON
// 将 Java 对象转换为 JSON 串,只需要使用 Fastjson 提供的 JSON 类中的 toJSONString() 静态方法即可。
String jsonStr = JSON.toJSONString(obj);
- 2、JSON字符串转Java对象
// 将 json 转换为 Java 对象,只需要使用 Fastjson 提供的 JSON 类中的 parseObject() 静态方法即可。
User user = JSON.parseObject(jsonStr, User.class);
4.2 方法二
<!-- Jackson依赖 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
- 1、Java对象转JSON
private static final ObjectMapper objectMapper = new ObjectMapper();
User user = new User("省长", 100);
// 手动序列化
String valueAsString = objectMapper.writeValueAsString(user);
- 2、JSON字符串转Java对象
private static final ObjectMapper objectMapper = new ObjectMapper();
// 取出数据
String userInfoString = redisTemplate.opsForValue().get("user");
// 手动反序列化
User userInfo = objectMapper.readValue(userInfoString, User.class);
5. 时间相关
5.1 时间类型转换
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
String Date = dateFormat.format(new Date());
5.2 apache工具包
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
<!-- 还可以使用Hutool工具类集合 -->
static java.util.Date addDays(java.util.Date date,int amount)
//Adds a number of days to a date returning a new object.
//一个日期对象+n天
static java.util.Date addHours(java.util.Date date,int amount)
//Adds a number of hours to a date returning a new object.
//一个日期对象+n小时
static java.util.Date addMilliseconds(java.util.Date date,int amount)
//Adds a number of milliseconds to a date returning a new object.
//一个日期对象+n毫秒
static java.util.Date addMinutes(java.util.Date date,int amount)
//Adds a number of minutes to a date returning a new object.
//一个日期对象+n分
static java.util.Date addMonths(java.util.Date date,int amount)
//Adds a number of months to a date returning a new object.
//一个日期对象+n月
static java.util.Date addSeconds(java.util.Date date,int amount)
//Adds a number of seconds to a date returning a new object.
//一个日期对象+n秒
static java.util.Date addWeeks(java.util.Date date,int amount)
//Adds a number of weeks to a date returning a new object.
//一个日期对象+N个星期
static java.util.Date addYears(java.util.Date date,int amount)
//Adds a number of years to a date returning a new object.
//一个日期对象+N年
static boolean isSameDay(java.util.Date date1,java.util.Date date2)
//Checks if two date objects are on the same day ignoring time.
//两个日期对象是否相等(只比较年-月-日)
static boolean isSameInstant(java.util.Date date1,java.util.Date date2)
//Checks if two date objects represent the same instant in time.
//比较两个日期是否完全相等(精确到毫秒)
static java.util.Date parseDate(java.lang.String str,java.lang.String[] parsePatterns)
//Parses a string representing a date by trying a variety of different parsers.
//例 :
String[] format={"yyyy-MM-dd"};
System.out.println(DateUtils.parseDate("2009-10-20",format));
6. 文件相关
6.1 文件复制
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
FileInputStream fileInputStream = new FileInputStream("G:\\img\\003.jpg");
FileInputStream fileInputStreamCopy = new FileInputStream("G:\\img\\003Copy.jpg");
IOUtils.copy(fileInputStream,fileInputStreamCopy);
二、前端:
1. JSON数据类型转换
// 数组(数组内存放对象)内的每个对象的指定属性值转JSON字符串
params.flavors = this.dishFlavors.map(obj => ({ ...obj, value: JSON.stringify(obj.value) }))
// 数组(数组内存放对象)内的每个对象的指定属性值转JSON数组
this.dishFlavors = res.data.flavors && res.data.flavors.map(obj => ({
...obj, value: JSON.parse3(obj.value), showOption: false
}))
2. 前后端交互-数据转换
// 前端数组(数组内存放对象)内的每个对象的指定属性转为用','拼接的字符串
const urlList = this.fileList.map(item => item.url).join(',')
// 后端将用','拼接的字符串转为数组
String[] itemIds = itemId.split(",")
// 前端JSON数组(数组内存放对象)转JSON字符串
JSON.stringify(this.formData.data)
// 后端获取JSON字符串内的属性值
JSONArray bhCarInsuranceData = JSONArray.fromObject(data);
insuranceCarId = bhCarInsuranceData.getJSONObject(0).getInt("insuranceCarId")
insuranceStartTime = bhCarInsuranceData.getJSONObject(0).getString("insuranceStartTime")).getTime()
insuranceType = bhCarInsuranceData.getJSONObject(n).getString("insuranceType")
3. 重置表单内容
this.$refs.loginFormRef.resetFields() // 重置表单
三、MybatisPlus:
1. MybatisPlus进行批量添加
@Test
public void testInsertAll() {
Collection<User> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
User user = new User();
String substring = UUID.randomUUID().toString().substring(0, 5) + i;
user.setName(substring);
user.setAge(20+i);
user.setEmail(substring + "@atguigu.com");
list.add(user);
}
// INSERT INTO user ( id, name, age, email ) VALUES ( ?, ?, ?, ? )
boolean saveBatch = userService.saveBatch(list);
System.out.println(saveBatch);
}
2. 拼接查询条件的三种方式
//根据页面提交的用户名username查询数据库
//方法一:
LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Employee::getUsername,employee.getUsername());
Employee emp = employeeService.getOne(queryWrapper);
//方法二:
emp = employeeService.getOne(Wrappers
.<Employee>lambdaQuery()
.eq(Employee::getUsername,employee.getUsername()));
//方法三:
emp = employeeService.lambdaQuery().eq(Employee::getUsername,employee.getUsername()).one();
3.拼接条件更新的三种方式
@Override
public void lessInventory(Long itemId, Integer num) {
Item item = this.lambdaQuery().eq(Item::getId, itemId).one();
// 更新方式一
LambdaUpdateWrapper<Item> wrapper1 = new LambdaUpdateWrapper<>();
wrapper1.eq(Item::getId, itemId);
wrapper1.set(Item::getStatus, item.getStock() - num);
wrapper1.set(Item::getSold, item.getSold() + num);
wrapper1.set(Item::getUpdateTime, new Date());
itemService.update(wrapper1);
// 更新方式二
LambdaUpdateWrapper<Item> wrapper2 = Wrappers.<Item>lambdaUpdate().eq(Item::getId, itemId)
.set(Item::getStatus, item.getStock() - num)
.set(Item::getSold, item.getSold() + num)
.set(Item::getUpdateTime, new Date());
itemService.update(wrapper2);
// 更新方式三
item.setStock(item.getStock() - num); // 库存数量
item.setSold(item.getSold() + num); // 销量
item.setUpdateTime(new Date()); // 更新时间
itemService.updateById(item);
// 更新方式四
itemService.lambdaUpdate().eq(Item::getId, itemId)
.set(Item::getStatus, item.getStock() - num)
.set(Item::getSold, item.getSold() + num)
.set(Item::getUpdateTime, new Date())
.update();
}
四、SpringMVC:
1.获取Request、Response、Session
// 获取RequestAttributes方法一
RequestAttributes attributesOne = RequestContextHolder.getRequestAttributes();
// 获取RequestAttributes方法二
RequestAttributes attributesTwo = RequestContextHolder.currentRequestAttributes();
// 强转为ServletRequestAttributes类型
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) attributesOne;
// 获取HttpServletRequest
HttpServletRequest httpServletRequest = servletRequestAttributes.getRequest();
// 获取HttpServletResponse
HttpServletResponse httpServletResponse = servletRequestAttributes.getResponse();
// 获取HttpSession
HttpSession httpSession = servletRequestAttributes.getSession();
2. 从服务器下载文件
@RequestMapping("/test/down")
public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws Exception {
// 获取ServletContext对象
ServletContext servletContext = session.getServletContext();
// 获取服务器中文件的真实路径
String realPath = servletContext.getRealPath("");
realPath = realPath + File.separator + "img" + File.separator + "Kototo.jpg";
FileInputStream fileInputStream = new FileInputStream(realPath);
// fileInputStream.available():读取输入流所对应文件的字节数
byte[] bytes = new byte[fileInputStream.available()];
fileInputStream.read(bytes);
MultiValueMap<String, String> httpHeaders = new HttpHeaders();
// 设置要下载方式以及下载文件的名字
httpHeaders.add("Content-Disposition", "attachment;filename=Kototo.jpg");
// 设置响应状态码
HttpStatus httpStatus = HttpStatus.OK;
// 创建ResponseEntity对象
ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, httpHeaders, httpStatus);
// 关闭输入流
fileInputStream.close();
return responseEntity;
}
3. 从浏览器上传文件
3.1 导入操作文件的依赖
<!-- 操作文件 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
3.2 配置文件上传解析器
<!--
配置文件上传解析器
id="multipartResolver"必须写
SpringMVC不是通过类型来获取文件上传解析器的,而是通过id获取的
-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"/>
</bean>
3.3 功能实现
@RequestMapping("/test/up")
@ResponseBody
public String testUpFile(MultipartFile photo, HttpSession session) throws Exception {
// 获取ServletContext对象
ServletContext servletContext = session.getServletContext();
// 获取服务器中文件的真实路径
String realPath = servletContext.getRealPath("");
// 拼接文件上传的文件夹路径
realPath = realPath + File.separator + "static" + File.separator + "upload";
// 创建文件上传的文件夹
File file = new File(realPath);
if (!file.exists()) {
// 若目标文件夹不存在,则创建
file.mkdirs();
}
// 获取上传的文件名(带后缀名)
String filename = photo.getOriginalFilename();
// 获取上传的文件的后缀名
String realFilename = filename.substring(0, filename.lastIndexOf("."));
// 获取上传的文件的后缀名(带.)
String fileSuffix = filename.substring(filename.lastIndexOf(".") - 1);
String uuid = UUID.randomUUID().toString();
// 拼接新的文件名,防止文件重名造成文件覆盖
String NewFilename = realFilename + "-" + uuid + fileSuffix;
// 拼接文件上传的最终文件路径
String finalPath = realPath + File.separator + NewFilename;
// 上传文件
photo.transferTo(new File(finalPath));
return "success";
}
4. Mybatis-Plus依赖注意点
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-annotation</artifactId>
<version>3.4.3</version>
<scope>compile</scope>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
五、SpringBoot
1. 获取当前运行的环境
/**
* @Author: ZZP
* @Date: Created in 13:02 2022/6/19
* @Version: 1.0
* @Description:
* 获取当前运行的环境
*/
@Component
public class SpringContextUtil implements ApplicationContextAware {
/**
* spring的应用上下文
*/
private static ApplicationContext applicationContext;
/**
* 初始化时将应用上下文设置进applicationContext
* @param applicationContext
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextUtil.applicationContext = applicationContext;
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 根据bean名称获取某个bean对象
*
* @param name bean名称
* @return Object
* @throws BeansException
*/
public static Object getBean(String name) throws BeansException {
return applicationContext.getBean(name);
}
/**
* 根据bean的class获取某个bean对象
* @param beanClass
* @param <T>
* @return
* @throws BeansException
*/
public static <T> T getBean(Class<T> beanClass) throws BeansException {
return applicationContext.getBean(beanClass);
}
/**
* 获取spring.profiles.active
* @return
*/
public static String getProfile() {
return getApplicationContext().getEnvironment().getActiveProfiles()[0];
}
}
2. 读取配置文件的顺序
将配置文件中的数据封装到我们自定义的实体类对象中的方式(此种方式在微服务里面读取远程配置文件时,可以实现配置热更新)
- 将实体类
bean
的创建交给Spring
管理。
- 1、在类上添加
@Component
注解。- 2、在类上添加
@Configuration
注解。- 3、加上
@EnableConfigurationProperties({DemoProperties.class})
注解将配置类加入到Spring容器中。- 使用
@ConfigurationProperties
注解表示加载配置文件。- 在该注解中也可以使用
prefix
属性指定只加载指定前缀的数据。- 在
BookController
中进行注入。- 另外可结合
@PropertySource
读取自定义配置文件(只要能被spring容器扫描到,放在哪里都可以)@PropertySource({"classpath:demo.properties"})
// 读取自定义的配置文件(非SpringBoot的默认配置文件),value属性指定加载了多个自定义配置文件,加载顺序为从左到右顺序加载,后加载的会覆盖先加载的属性值。如果各配置文件中有相同属性配置,属性优先级为:
远程带有环境的配置
>远程共享配置
>本地带有环境的配置
>本地共享配置
file:./config
下的配置文件优先于类路径下的配置文件类路径下的
./config
下的配置文件优先于类路径下的配置文件
application.properties
>application.yml
>application.yaml
- ./config/application-dev.propertis > ./config/application-dev.yml > ./config/application-dev.yaml >
- application-dev.propertis > application-dev.yml > application-dev.yaml >
- ./config/application.propertis > ./config/application.yml > ./config/application.yaml >
- application.propertis > application.yml > application.yaml >
- 自定义配置文件
六、MySQL
基础字段 关联字段 辅助字段 冗余字段
1、时间相关
1.1 比较时间方法一:
<if test="beginCreateTime != null and endCreateTime != null ">
and DATE_FORMAT(create_time,'%Y-%m-%d %H:%i:%s')
BETWEEN DATE_FORMAT(begin_create_time,'%Y-%m-%d %H:%i:%s')
AND DATE_FORMAT(end_create_time,'%Y-%m-%d %H:%i:%s')
</if>
1.2 比较时间方法二:
<if test="beginCreateTime != null and endCreateTime != null ">
and UNIX_TIMESTAMP(create_time)
BETWEEN UNIX_TIMESTAMP(begin_create_time)
AND UNIX_TIMESTAMP(end_create_time)
</if>
1.3 比较时间方法三:
<if test="beginCreateTime != null and endCreateTime != null ">
and begin_create_time <![CDATA[<]]> create_time
and end_create_time <![CDATA[>]]> create_time
</if>
1.4 获取当前时间函数:
# 1. MySQL中提供了NOW()函数,用于取得当前的日期时间,NOW()汗水、SYSDATE()、CURRENT_TIMESTAMP()等别名如下:
SELECT NOW(), SYSDATE(), CURRENT_TIMESTAMP
# 2. 如果想得到不包括时间部分的当前日期,则可以使用CURDATE()函数,CURDATE()函数还有CURRENT_DATE等别名。如下:
SELECT CURDATE(), CURRENT_DATE
# 3. 如果想得到不包括日期部分的当前时间,则可以使用CURTIME()函数,CURTIME()函数还有CURRENT_TIME等别名
SELECT CURTIME(), CURRENT_TIME
2、查询操作
2.1 mybatis中拼接模糊查询:
<if test="phone != null and phone != ''"> and phone like concat('%', #{phone}, '%')</if>
2.2 保留两位小数和设置默认值:
SELECT
# 如果为null,则赋默认值为0;如果不为null,则小数点保留两位
CAST(IFNULL (SUM(h.`contract_order`), 0) AS DECIMAL (30, 2)) AS salesAmount
FROM
`tb_contract` h
WHERE
h.create_user = 1
AND DATE_FORMAT(h.create_time, '%Y-%m-%d')
BETWEEN DATE_FORMAT('2022-01-01', '%Y-%m-%d') AND DATE_FORMAT('2022-12-31', '%Y-%m-%d')
2.3 UNION 和 UNION ALL 的区别
一、区别1:取结果的交集
1、union:对两个结果集进行并集操作,不包括重复行,相当于distinct,同时进行默认规则的排序;
2、union all:对两个结果集进行并集操作,包括重复行,即所有的结果全部显示,不管是不是重复;
二、区别2:获取结果后的操作
1、union: 会对获取的结果进行排序操作
2、union all: 不会对获取的结果进行排序操作
三、区别3:
1、union看到结果中ID=3的只有一条
select * from student2 where id < 4
union
select * from student2 where id > 2 and id < 6
2、union all 结果中ID=3的结果有两个
select * from student2 where id < 4
union all
select * from student2 where id > 2 and id < 6
四、总结:
union all只是合并查询结果,并不会进行去重和排序操作,在没有去重的前提下,使用union all的执行效率要比union高
2.4 Mybatis中使用IN查询问题
当Mybatis中需要IN关键字进行查询的时候 ,需要使用 foreach 标签,将参数拼接起来,sql如下:
<select id="selectStudentInfoByIds" resultMap="BaseResultMap">
select * from student where id in
<foreach collection="ids" index="index" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
2.5 FIND_IN_SET函数
语法:
FIND_IN_SET(str, strList)
- 第一个参数 str 是要查找的字符串。
- 第二个参数 strList 是要搜索的逗号分隔的字符串列表。
假如字符串 str 在由 N 子链组成的字符串列表 strList 中,则返回值的范围在 1 到 N 之间。
一个字符串列表就是一个由一些被(‘,’)符号分开的子链组成的字符串。如果第一个参数是一个常数字符串,而第二个是type SET列,则 FIND_IN_SET() 函数被优化,使用比特计算。
如果str不在strList 或 strList 为空字符串,则返回值为 0 。如果任意一个参数为 NULL,则返回值为 NULL。
注意:这个函数在第一个参数包含一个逗号(‘,’)时将无法正常运行。
3、MySQL5.0和MySQL8.0的区别
1 区别一:MySQL 使用 GROUP BY 分组 SELECT 后面只能是分组的字段或者聚合函数?
select
d.department_id 部门id, d.department_name 部门,AVG(e.salary) 平均工资,j.grade_level 工资等级
from
employees e,departments d,job_grades j
where
e.department_id=d.department_id
GROUP BY
d.department_name
MySQL 5.7之后,默认启用一个
SQL MODE:ONLY_FULL_GROUP_BY
:SELECT中的列必须再GROUP BY中出现。MySQL 8.0写上面的SQL不报错,是因为把 SQL_MODE 设置为空,或者去掉 ONLY_FULL_GROUP_BY 这个限制了。
可以执行SQL语句,检查确认下是否如此:mysql> select @@sql_mode;
2 区别二:设置密码规则:
#查看密码强度设定:
SHOW VARIABLES LIKE 'validate_password%';
#修改密码强度(mysql8.0以下):
set global validate_password_length=4; #密码长度最低位数,默认是8
set global validate_password_policy=LOW; #密码安全等级低,默认是MEDIUM,便于密码可以修改成root
#修改密码强度(mysql8.0及以上):
set global validate_password.length=4; #密码长度最低位数,默认是8
set global validate_password.policy=LOW; #密码安全等级低,默认是MEDIUM,便于密码可以修改成root
#修改密码:
set password = password('root'); #设置localhost user密码为root
#也可用如下命令修改:
#设置指定user的密码为root
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '新密码'
#刷新权限
flush privileges;
八、Feign远程调用
1 自定义配置
feign:
client:
config:
# 这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置
default: # 避坑:开启全局配置会使ribbon超时配置失效
loggerLevel: FULL # 日志级别
七、便捷工具包
1 apache工具类集合
<!-- apache工具类集合 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
2 Hutool工具类集合
<!-- Hutool工具类集合 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.5.2</version>
</dependency>
3 EasyExcel工具类
<!-- JAVA解析Excel工具EasyExcel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.1.1</version>
</dependency>
4 MinIO工具
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>3.0.10</version>
</dependency>