目录

JavaJava后端程序员开发经常使用的方法函数持续更新

[Java]Java后端程序员开发经常使用的方法函数(持续更新)

文章目录

简述

身为一个后端程序员,当然不可能把所有的东西都背诵下来,正所谓好记性不如烂笔头,我都会把自己经常使用的一些方法记录起来,方便在开发过程中使用。

数据库(MySQL)

查询所有字段

SELECT
	COLUMN_NAME,
	column_comment 
FROM
	INFORMATION_SCHEMA.COLUMNS 
WHERE
	table_name = '你的表名'

查询所有字段并逗号隔开(id,name.code)

SELECT
	group_concat( COLUMN_NAME SEPARATOR ',' ) AS t_info 
FROM
	information_schema.COLUMNS 
WHERE
	table_name = '表名称' 
	AND table_schema = '数据库名称';

增加或者减少指定的天数

UPDATE `equipment_monitor_locations`  set create_time = DATE_ADD(`create_time`,INTERVAL 1 DAY)
 
 UPDATE `equipment_monitor_locations`  set create_time = DATE_SUB(`create_time`,INTERVAL 1 DAY)

查询指定年份的数据

SELECT id, sensor_code FROM user WHERE YEAR(upload_time) = #{year}

数据库表新增信息

增加默认删除状态
 ALTER TABLE `sys_menu`
 ADD `deleted` tinyint(1) DEFAULT '0' COMMENT '删除状态(0:正常 1:删除)';
 台账表格基础操作时间信息
 ALTER TABLE `name`
 ADD create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
 ADD update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间';
 台账表格基础操作人员信息
 ALTER TABLE `name`
 ADD create_person VARCHAR(255) NOT NULL COMMENT '创建人员',
 ADD create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
 ADD update_person VARCHAR(255) NOT NULL COMMENT '更新人员',
 ADD update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
 ADD changes_person VARCHAR(255) NOT NULL COMMENT '变更人员',
 ADD changes_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '变更时间',
 ADD delete_person VARCHAR(255) NOT NULL COMMENT '删除人员',
 ADD delete_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '删除时间';
 改变人员
  ALTER TABLE `name`
 ADD change_person VARCHAR(255) NOT NULL COMMENT '更变人员',
 ADD change_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更变时间';
 
 
 ALTER TABLE `name`
 ADD created_person VARCHAR(255) NOT NULL COMMENT '创建人员',
 ADD created_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间'
 ADD updated_person VARCHAR(255) NOT NULL COMMENT '更新人员',
 ADD updated_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间'
 ADD deleted_person VARCHAR(255) NOT NULL COMMENT '删除人员',
 ADD deleted_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '删除时间';

case

( CASE WHEN ( pmc.manoeuvre_change_state = 1 ) THEN pmc.id ELSE NULL END ) AS num

用 EXISTS 或 NOT EXISTS 代替 IN 或 NOT IN

select *  from test1 
   where EXISTS (select * from test2  where id2 = id1 )

select *  FROM test1  
 where NOT EXISTS (select * from test2  where id2 = id1 )

7位设备编码补零生成

        SELECT
        ( CASE WHEN sum.count < 10000000 THEN LPAD( sum.count, 7, '0' ) ELSE sum.count END ) AS sum_code_num
        FROM
        ( SELECT COUNT(id) AS `count` FROM `device_info`) AS sum

查询相同id下,最新的一条数据

SELECT a.*
FROM alarm_dispose a
INNER JOIN (
  SELECT alarm_id, MAX(alarm_time) as max_alarm_time, MAX(id) AS id
  FROM alarm_dispose
  GROUP BY alarm_id
) b ON a.alarm_id = b.alarm_id AND a.alarm_time = b.max_alarm_time AND a.id = b.id;
SELECT a.*
FROM alarm_dispose a
INNER JOIN (
    SELECT alarm_id, MAX(alarm_time) as max_alarm_time
    FROM alarm_dispose
    GROUP BY alarm_id
) b ON a.alarm_id = b.alarm_id AND a.alarm_time = b.max_alarm_time
WHERE a.id = (
    SELECT MAX(id)
    FROM alarm_dispose c
    WHERE c.alarm_id = a.alarm_id AND c.alarm_time = a.alarm_time
);

Spring Boot

常用注解

数据库事务注解

@Transactional(rollbackFor = Exception.class)

常用实体补充

    import com.fasterxml.jackson.annotation.JsonFormat;
    import org.springframework.format.annotation.DateTimeFormat;
    
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @ApiModelProperty("创建时间")
    private Date createTime;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @ApiModelProperty("更新时间")
    private Date updateTime;

long自动转字符串

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
@JsonSerialize(using = ToStringSerializer.class)

枚举类


import lombok.AllArgsConstructor;
import lombok.Getter;


/**
 * 预警类别
 *
 * @author dpe
 */
@AllArgsConstructor
@Getter
public enum AlarmGradeEnum {

    /**
     * 一级预警
     */
    ONE(1,"一级预警"),
    /**
     * 二级预警
     */
    TWO(2,"二级预警"),
    /**
     * 三级预警
     */
    THREE(3,"三级预警");


    private final Integer code;
    private final String name;


    public static Integer getCode(String name) {
        for (AlarmGradeEnum record : AlarmGradeEnum.values()) {
            if (record.name.equals(name)) {
                return record.code;
            }
        }
        return null;
    }

    public static String getName(Integer code) {
        for (AlarmGradeEnum record : AlarmGradeEnum.values()) {
            if (record.code.equals(code)) {
                return record.name;
            }
        }
        return null;
    }


    public static AlarmGradeEnum get(Integer code) {
        for (AlarmGradeEnum record : AlarmGradeEnum.values()) {
            if (record.code.equals(code)) {
                return record;
            }
        }
        return null;
    }
}

常用函数

    /**
     * 生成随机整数
     *
     * @param min 最小区间
     * @param max 最大区间
     * @return 随机整数
     */
    public int generatingRandomInt(int min, int max) {
        double randomValue = min + (max - min + 1) * Math.random();
        return (int) randomValue;
    }

流处理-list转map

    public Map<String, User> convertListToMap(List<User> userList) {
        if (deviceInfoList == null) {
            return new HashMap<>(); // 返回空Map,或者抛出异常,取决于你的需求
        }

        Map<String, User> userMap = userList.stream()
            .filter(user -> user.getCode() != null) // 判空过滤
            .collect(Collectors.toMap(User::getTermigetCodenalNo, user -> user));

        return userMap;
    }

list转map

        List<SysMenu> sysMenuList = menuMapper.selectList(null);

        HashMap<Long, List<SysMenu>> map = new HashMap<>();

        for (SysMenu item:sysMenuList){
            Long parentId = item.getParentId();
            List<SysMenu> sysMenuMapList = new ArrayList<>();
            if(map.containsKey(parentId)){
                sysMenuMapList = map.get(parentId);
            }
            sysMenuMapList.add(item);
            map.put(parentId, sysMenuMapList);
        }

list排序

自然正序

Comparator.naturalOrder()

自然倒叙

Comparator.reverseOrder()
// 根据list中的一个字段,对集合重新排序(不能处理空值)
List<User> newList = list.stream().sorted(Comparator.comparing(User::getAge)).collect(Collectors.toList());

// 使用 nullsLast() 方法,将空值排在最后:
newList = newList.stream()
    .sorted(Comparator.comparing(User::getAge, Comparator.nullsLast(Comparator.naturalOrder())))
    .collect(Collectors.toList());

// 使用 nullsFirst() 方法,将空值排在最前:
newList = newList.stream()
    .sorted(Comparator.comparing(User::getAge, Comparator.nullsFirst(Comparator.naturalOrder())))
    .collect(Collectors.toList());

时间类型

获取当天的开始时间
DateTime beginOfDay = DateUtil.beginOfDay(new Date());
获取当天的结束时间
DateTime endOfDay = DateUtil.endOfDay(new Date());

数据校验函数

验证手机号码与座机号码
    /**
     * 验证手机号码与座机号码
     *
     * @param phone 号码
     * @return 正确/错误
     */
    public static boolean phoneVerification(String phone) {

        // 验证手机号码
        String mobilePattern = "^1(3[0-9]|4[5-9]|5[0-35-9]|66|7[0-8]|8[0-9]|9[0-35-9])\\d{8}$";
        Pattern patternMobile = Pattern.compile(mobilePattern);
        Matcher matcherMobile = patternMobile.matcher(phone);
        boolean phoneNum = matcherMobile.matches();

        // 验证座机号码
        String telephonePattern = "^(0[1-9]\\d{1,2}-?)?([2-9]\\d{6,7})$";
        Pattern patternTelephone = Pattern.compile(telephonePattern);
        Matcher matcherTelephone = patternTelephone.matcher(phone);
        boolean matcher = matcherTelephone.matches();

        // 验证座机号码(不带区号)
        String telephonePatternShort = "^(0[1-9]\\d{1,2}-?)?([2-9]\\d{6,7})|(\\d{7,8})$";
        Pattern patternTelephoneShort = Pattern.compile(telephonePatternShort);
        Matcher matcherTelephoneShort = patternTelephoneShort.matcher(phone);
        boolean matcherShort = matcherTelephoneShort.matches();

        return phoneNum || matcher || matcherShort;
    }

实体通用字段

@ApiModelProperty(value = "删除状态(0:正常 1:删除)")
     private Integer deleted;

Optional判空

Optional<SosInfo> sosInfoOptional = sosInfoRepository.findById(id);
SosInfo sosInfo = sosInfoOptional.orElse(null);
Optional<DeviceInfo> deviceInfoOptional = deviceInfoRepository.findById(id);
if (deviceInfoOptional.isPresent()) {
    DeviceInfo deviceInfo = deviceInfoOptional.get();
}

测试类

普通测试类

import org.junit.Test;

/**
 * @author fir
 */
public class DataServiceTest {


    @Test
    public void a(){
        System.out.println("asdasda");
    }
}

实体注解

自定义字段,不作为数据库表字段使用

@TableField(exist = false)

雪花算法主键

    @JsonSerialize(using= ToStringSerializer.class)
    @TableId(value = "role_id", type = IdType.ASSIGN_ID)

时间格式转换实体字段

import com.fasterxml.jackson.annotation.JsonFormat;
 import org.springframework.format.annotation.DateTimeFormat;    
 
 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
 @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")

xml文件特殊符号替换符

  &lt; < 小于号 
  &gt; > 大于号 
  &amp; & 和 
  &apos; ' 单引号 
  &quot; " 双引号

数据提交验证

@ApiOperation("添加数据")
 @PostMapping("/insertData")
 public AjaxResult insertData(@Validated Demo demo){
     return AjaxResult.success(iDemoService.insertData(demo));
 }

实体中

// 字符串类型,表示不能超过5个字符(abcde)
     Length(max = 5,message = "名称 不能超过 5 个字符")
     @ApiModelProperty(value = "名称")
     @ExcelProperty(index = 1)
     private String name;
     
     数值类型,表示不能大于1(<=1)
     @Range(max = 1, message = "状态 不能超过 1 个字符")
     @ApiModelProperty(value = "状态(0:未上报,1:已上报,2:变更中)")
     private Integer state;

对于

reason longtext COMMENT ‘内容’

字段长度应为

@Length(max = 65535, message = "内容 不能超过 65535 个字符")
     @ApiModelProperty(value = "内容")
     private String reason;

递归处理树形结构

树形实体

package com.lnsoft.mmbdf.yjglpt.project.dto.mt;
 
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
 import java.util.List;
 
 
 /**
  * 级联选择器对象
  * @author fir
  */
 @Data
 @Builder
 @AllArgsConstructor
 @NoArgsConstructor
 public class TreeIntegerDTO {
 
     @JsonSerialize(using= ToStringSerializer.class)
     @ApiModelProperty(value = "数值")
     private Long value;
 
     @ApiModelProperty(value = "标签")
     private String label;
 
     @ApiModelProperty(value = "可用数值")
     private Object num;
 
     @ApiModelProperty(value = "状态")
     private Object state;
 
     @ApiModelProperty(value = "是否禁用: 是-true 否-false")
     private Boolean disabled;
 
     @ApiModelProperty(value = "子列表")
     private List<TreeIntegerDTO> children;
 }

MyBatis-Plus

查询条件

lqwList.and((qw) -> qw
         .eq(ManoeuvreVideo::getType, 0)
         .or()
         .eq(ManoeuvreVideo::getType, 1));
区间
 lqw.between(ManoeuvreVideo::getTime, start, end);
大于小于
// 大于
     lqw.gt(ManoeuvreVideo::getTime, time);
     // 大于等于
     lqw.ge(ManoeuvreVideo::getTime, time);
     // 小于
     lqw.lt(ManoeuvreVideo::getTime, time);
     // 小于等于
     lqw.le(ManoeuvreVideo::getTime, time);

xml自定义查询

in(foreach)
code
 IN 
     <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
         #{item}
     </foreach>
 
 
     /**
      * 装备演练-地市演练次数查看
      *
      * @return 地市演练次数
      */
     List<PjManoeuvreStatisticsOrgManoeuvre> getStatistics(List<String> list);
if
<if test="type != null and type != ''">
                 t.type = #{type}
</if>

<if test="state != null and state.size > 0">
      AND t.state IN
      <foreach item="state" index="index" collection="state" open="(" separator="," close=")">
        #{state}
      </foreach>
</if>

<if test="array != null and array.length >0">
<if test="list != null and list.size() > 0">
where
<where>
             <if test="type != null and type != ''">
                 t.type = #{type}
             </if>
</where>
like concat('%', #{menuName}, '%')

自定义查询的分页查询

// 逻辑层中
         PageInfo<User> resultInfo;
         Page<User> page = new Page<>(pageNum, pageSize);
         Page<User> userPage = userMapper.getList(page);
         resultInfo = new PageInfo<>(userPage.getTotal(), pageNum, userPage.getRecords());
         
         // deo层中
         Page<User> getList(Page<User> page);
         
         // xml中
         <select id="getList" resultType="com.fir.test.dto.mt.User">
         SELECT name,
                code
         FROM `user`
         </select>

Swagger

常用注释

@ApiImplicitParams({
             @ApiImplicitParam(name = "weightJson", value = "指标权重(Json)格式", dataTypeClass = String.class),
             @ApiImplicitParam(name = "pageNum", value = "页码", defaultValue = "1", dataTypeClass = Integer.class, required = true),
             @ApiImplicitParam(name = "pageSize", value = "页数量", defaultValue = "10", dataTypeClass = Integer.class, required = true)
     })

Hutool 工具

手机号码校验
boolean isMobile = Validator.isMobile("18866661234");
1
身份证号校验
boolean isIdCardNumber = Validator.isCitizenId("43312220160113802X");
1
邮箱校验
boolean isEmail = Validator.isEmail("random@example.com");
1
统一社会信用代码校验
boolean isCreditCode = Validator.isCreditCode("91440300701234567A");
1
车牌号码校验
boolean isPlateNumber = Validator.isPlateNumber("粤B12345");
1
车架号校验
boolean isCarVin = Validator.isCarVin("LFV2A21J9D4112345");

历史问题

Mybatis-plus 逻辑删除字段无效

问题描述:

<dependency>
             <groupId>com.baomidou</groupId>
             <artifactId>mybatis-plus-generator</artifactId>
             <version>3.0.6</version>
         </dependency>

增加yml配置后仍然无效

mybatis-plus:
   global-config:
     db-config:
       logic-delete-field: deleted # 此版本无该配置项
       logic-delete-value: 1
       logic-not-delete-value: 0

实体中一下配置均无效

@TableLogic
 @ApiModelProperty(value = "删除状态(0:正常 1:删除)")
 private Integer deleted;
	@TableLogic(value = "0", delval = "1")	@ApiModelProperty(value = "删除状态(0:正常 1:删除)")	private Integer deleted;

解决方法:

实体

@TableLogic
@ApiModelProperty(value = "删除状态(0:正常 1:删除)")
private Integer deleted;

配置类

import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.JdbcType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.io.IOException;


/**
  * @author dpe
  * @date 2022/02/10 16:34
  **/
@Slf4j
@Configuration
public class MybatisPlusConfig {


    /**
      * 分页插件
      * @return bean
      */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }


    /**
      * 逻辑删除
      *
      * @return 注入器
      */
    @Bean
    public ISqlInjector sqlInjector(){
        return new LogicSqlInjector();
    }
}

错误案例

更多的人推荐,但这种配置是无效的

/**
      * 逻辑删除
      *
      * @return 注入器
      */
     @Bean
     public ISqlInjector sqlInjector(){
         return new DefaultSqlInjector();
     }

Invalid bound statement (not found)

问题描述

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.fir.mybatis.imapper.core.UserMapper.getUser

解决方法

mybatis:
   config-location: classpath:mybatis-config.xml
   mapper-locations: classpath:/mapper/*.xml
 mybatis-plus:
   configuration:
     map-underscore-to-camel-case: true
     auto-mapping-behavior: full
     log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
 #  mapper-locations: classpath*:mapper/*.xml 去掉该条配置

错误原因

在低版本中配置逻辑删除,有修改配置的方法,但在尝试无效之后,没有及时的清理无用的配置,导致问题出现

临时记录

"fileName": "20231220测试视频.mp4",
     "staticResourcesId": 158253