常用代码块和工具类

常用代码块和工具类

一、后端:
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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值