Mybatis根据Bean生成对应的SQL语句工具类

news2024/10/7 20:32:21

Mybatis根据Bean生成对应配置SQL的语句

  • 前言
    • 为什么不用MyBatis-Plus
    • Mybatis的困扰
    • 插入和更新
    • 查询
  • crud工具类
    • MybatisCrudHelp.java
  • 测试类
    • 需要注意的点

前言

在进入这一节知道MyBatis-Plus的人可能有人要问了:为什么我不用Mybatis-plus

为什么不用MyBatis-Plus

对于这个问题,我的意见请参考以下几篇文章:

MyBatis-Plus: 谨慎入坑
为什么不建议你使用Mybatis-plus

反正用着就不是很得劲。

Mybatis的困扰

大家在使用Mybatis的时候肯定遇到过这样问题:当你接到一个新的业务,设计好了一个表结构,写好bean以后,这个表至少需要增删改查的功能吧?那是不是需要在对应的xml文件里写插入、更新、删除语句。我们现在以一个简单的Student类为例子:

Student.java

@Data
public class Student {
    //学号
    String studentId;
    //姓名
    String name;
    //年龄
    Integer age;
    //性别
    Integer sex;
}

上述的@Datalombok的注解,主要是用于自动根据属性构建一些setter和getter以及一些常见实体类方法

插入和更新

实体类有了那我们就该开始在xml文件里crud的基本语句了,以下只演示插入和更新。
新增

insert into student(
 studentId
 ,name
 ,age
 ,sex
 ) values(
  #{studentId}
  ,#{name}
  ,#{age}
  ,#{sex}
)

更新

update student
<set>
 studentId=#{studentId}
 ,name=#{name}
 ,age=#{age}
 ,sex=#{sex}
</set>
where xxx = #{xxx}

咋一看是不是还没多少?但需要注意的是,新增和更新的时候有的字段还不是必填,那么就还需要进行一个判空的处理。那么上述语句就需要变成以下这样:
新增

insert into student(
  <if test="studentId != null and studentId != ''">studentId</if>
  <if test="name != null and name != ''">,name</if>
  <if test="age != null">,age</if>
  <if test="sex != null">,sex</if>
 ) values(
  <if test="studentId != null and studentId != ''">#{studentId}</if>
  <if test="name != null and name != ''">,#{name}</if>
  <if test="age != null">,#{age}</if>
  <if test="sex != null">,#{sex}</if>
)

更新

update student
<set>
  <if test="studentId != null and studentId != ''">studentId=#{studentId}</if>
  <if test="name != null and name != ''">,name=#{name}</if>
  <if test="age != null">,age=#{age}</if>
  <if test="sex != null">,sex=#{sex}</if>
</set>
where xxx = #{xxx}

是不是已经有点烦了?别急还有更加绝望的。我们来看看查询,在以下的讨论中我们暂且先抛开性能以及是否走索引的情况

查询

如果查询条件可以是所有字段,并且可以任意搭配

比如我要搜索学号包含2023,年龄为18的学生信息,或者是年龄为18,性别为女的学生信息,又或者是姓张,学号包含2023,性别为女的学生信息等等。你总不能每个功能写一个查询语句吧,那也太麻烦了。

所以我们可以这么写:

select 
studentId,name,age,sex
 from student
<where>
  <if test="studentId != null and studentId != ''">studentId like  concat('%',#{studentId},'%')</if>
  <if test="name != null and name != ''"> and name like  concat('%',#{name},'%')</if>
  <if test="age != null"> and age = #{age}</if>
  <if test="sex != null"> and sex = #{sex}</if>
</where>

然后查询的方法里还要加上对应的注解

List<Student> getAllStudentInfo(
	@Param("studentId")String studentId
	, @Param("name")String name
	, @Param("age")Integer age
	, @Param("sex")Integer sex
);

你是不是还是觉得也不是很麻烦?很好,现在我们将上述Student类扩充一下,给它的字段再加一~~~~~点点,扩充到37个属性,让学生信息更完整。体验一下遇到多字段的实体类时,编写SQL的赶脚。

一般十几个、二十几个字段的表的很常见,三十几个的也有,所以这可不是我胖虎为难你们。

import lombok.Data;

import java.sql.Date;

/**
 * @Description
 * @Author 三文鱼先生
 * @Data 2023/5/11 10:35
 */
@Data
public class Student {
    //学号
    String studentId;
    //姓名
    String name;
    //年龄
    Integer age;
    //性别
    Integer sex;
    //国籍
    Integer nationality;
    //港澳台侨信息
    Integer hmtc;
    //身份证
    String idCard;
    //身份证类型
    Integer cardType;
    //政治面貌
    Integer politicCountenance;
    //民族
    String ethnicGroup;
    //籍贯
    String nativePlace;
    //学生类别
    Integer studentType;
    //是否独生子女
    Integer justOnly;
    //是否流动人口
    Integer floating;
    //是否留守儿童
    Integer leftoverChildren;
    //是否残疾
    Integer disability;
    //残疾类型
    String disabilityType;
    //入学时间
    Date admissionDate;
    //入学方式
    Integer admissionType;
    //就读方式
    Integer studyMode;
    //学生来源
    Integer studentSource;
    //健康等级
    Integer healthLevel;
    //宗教信仰
    String religion;
    //就读年级
    Integer grade;
    //班级名称
    String className;
    //学生联系电话
    String studentPhone;
    //住址
    String address;
    //出生日期
    String birthday;
    //邮箱
    String email;
    //学生图片存储地址
    String studentImage;
    //监护人姓名
    String guardianName;
    //监护人电话
    String guardianPhone;
    //与监护人关系
    String relationshipWithGuardian;
    //监护人照片存储地址
    String guardianImage;
    //班主任姓名
    String classTeacher;
    //班主任电话
    String teacherPhone;
    //班主任照片存储地址
    String teacherImage;

}

在这里插入图片描述

好了,怕也没用,现在我们再来写之前提到过的新增、更新、查询的语句。大家可以自己试着写一下(当然啊我就不写了,我不打扰,我走了哈),让代码能够正常运行,并且记录从开始到结束的时间,就知道这个过程有多浪费时间了。写出来大概是以下这样:

新增

insert into student(
  <if test="studentId != null and studentId != ''">studentId</if>
  <if test="name != null and name != ''">,name</if>
  <if test="age != null">,age</if>
  <if test="sex != null">,sex</if>
  <if test="nationality != null">,nationality</if>
  <if test="hmtc != null">,hmtc</if>
  <if test="idCard != null and idCard != ''">,idCard</if>
  <if test="cardType != null">,cardType</if>
  <if test="politicCountenance != null">,politicCountenance</if>
  <if test="ethnicGroup != null and ethnicGroup != ''">,ethnicGroup</if>
  <if test="nativePlace != null and nativePlace != ''">,nativePlace</if>
  <if test="studentType != null">,studentType</if>
  <if test="justOnly != null">,justOnly</if>
  <if test="floating != null">,floating</if>
  <if test="leftoverChildren != null">,leftoverChildren</if>
  <if test="disability != null">,disability</if>
  <if test="disabilityType != null and disabilityType != ''">,disabilityType</if>
  <if test="admissionDate != null and admissionDate != ''">,admissionDate</if>
  <if test="admissionType != null">,admissionType</if>
  <if test="studyMode != null">,studyMode</if>
  <if test="studentSource != null">,studentSource</if>
  <if test="healthLevel != null">,healthLevel</if>
  <if test="religion != null and religion != ''">,religion</if>
  <if test="grade != null">,grade</if>
  <if test="className != null and className != ''">,className</if>
  <if test="studentPhone != null and studentPhone != ''">,studentPhone</if>
  <if test="address != null and address != ''">,address</if>
  <if test="birthday != null and birthday != ''">,birthday</if>
  <if test="email != null and email != ''">,email</if>
  <if test="studentImage != null and studentImage != ''">,studentImage</if>
  <if test="guardianName != null and guardianName != ''">,guardianName</if>
  <if test="guardianPhone != null and guardianPhone != ''">,guardianPhone</if>
  <if test="relationshipWithGuardian != null and relationshipWithGuardian != ''">,relationshipWithGuardian</if>
  <if test="guardianImage != null and guardianImage != ''">,guardianImage</if>
  <if test="classTeacher != null and classTeacher != ''">,classTeacher</if>
  <if test="teacherPhone != null and teacherPhone != ''">,teacherPhone</if>
  <if test="teacherImage != null and teacherImage != ''">,teacherImage</if>
 ) values(
  <if test="studentId != null and studentId != ''">#{studentId}</if>
  <if test="name != null and name != ''">,#{name}</if>
  <if test="age != null">,#{age}</if>
  <if test="sex != null">,#{sex}</if>
  <if test="nationality != null">,#{nationality}</if>
  <if test="hmtc != null">,#{hmtc}</if>
  <if test="idCard != null and idCard != ''">,#{idCard}</if>
  <if test="cardType != null">,#{cardType}</if>
  <if test="politicCountenance != null">,#{politicCountenance}</if>
  <if test="ethnicGroup != null and ethnicGroup != ''">,#{ethnicGroup}</if>
  <if test="nativePlace != null and nativePlace != ''">,#{nativePlace}</if>
  <if test="studentType != null">,#{studentType}</if>
  <if test="justOnly != null">,#{justOnly}</if>
  <if test="floating != null">,#{floating}</if>
  <if test="leftoverChildren != null">,#{leftoverChildren}</if>
  <if test="disability != null">,#{disability}</if>
  <if test="disabilityType != null and disabilityType != ''">,#{disabilityType}</if>
  <if test="admissionDate != null and admissionDate != ''">,#{admissionDate}</if>
  <if test="admissionType != null">,#{admissionType}</if>
  <if test="studyMode != null">,#{studyMode}</if>
  <if test="studentSource != null">,#{studentSource}</if>
  <if test="healthLevel != null">,#{healthLevel}</if>
  <if test="religion != null and religion != ''">,#{religion}</if>
  <if test="grade != null">,#{grade}</if>
  <if test="className != null and className != ''">,#{className}</if>
  <if test="studentPhone != null and studentPhone != ''">,#{studentPhone}</if>
  <if test="address != null and address != ''">,#{address}</if>
  <if test="birthday != null and birthday != ''">,#{birthday}</if>
  <if test="email != null and email != ''">,#{email}</if>
  <if test="studentImage != null and studentImage != ''">,#{studentImage}</if>
  <if test="guardianName != null and guardianName != ''">,#{guardianName}</if>
  <if test="guardianPhone != null and guardianPhone != ''">,#{guardianPhone}</if>
  <if test="relationshipWithGuardian != null and relationshipWithGuardian != ''">,#{relationshipWithGuardian}</if>
  <if test="guardianImage != null and guardianImage != ''">,#{guardianImage}</if>
  <if test="classTeacher != null and classTeacher != ''">,#{classTeacher}</if>
  <if test="teacherPhone != null and teacherPhone != ''">,#{teacherPhone}</if>
  <if test="teacherImage != null and teacherImage != ''">,#{teacherImage}</if>
)

要是我手动写,估计这会我已经能看见天堂了
在这里插入图片描述

更新

update student
<set>
  <if test="studentId != null and studentId != ''">studentId=#{studentId}</if>
  <if test="name != null and name != ''">,name=#{name}</if>
  <if test="age != null">,age=#{age}</if>
  <if test="sex != null">,sex=#{sex}</if>
  <if test="nationality != null">,nationality=#{nationality}</if>
  <if test="hmtc != null">,hmtc=#{hmtc}</if>
  <if test="idCard != null and idCard != ''">,idCard=#{idCard}</if>
  <if test="cardType != null">,cardType=#{cardType}</if>
  <if test="politicCountenance != null">,politicCountenance=#{politicCountenance}</if>
  <if test="ethnicGroup != null and ethnicGroup != ''">,ethnicGroup=#{ethnicGroup}</if>
  <if test="nativePlace != null and nativePlace != ''">,nativePlace=#{nativePlace}</if>
  <if test="studentType != null">,studentType=#{studentType}</if>
  <if test="justOnly != null">,justOnly=#{justOnly}</if>
  <if test="floating != null">,floating=#{floating}</if>
  <if test="leftoverChildren != null">,leftoverChildren=#{leftoverChildren}</if>
  <if test="disability != null">,disability=#{disability}</if>
  <if test="disabilityType != null and disabilityType != ''">,disabilityType=#{disabilityType}</if>
  <if test="admissionDate != null and admissionDate != ''">,admissionDate=#{admissionDate}</if>
  <if test="admissionType != null">,admissionType=#{admissionType}</if>
  <if test="studyMode != null">,studyMode=#{studyMode}</if>
  <if test="studentSource != null">,studentSource=#{studentSource}</if>
  <if test="healthLevel != null">,healthLevel=#{healthLevel}</if>
  <if test="religion != null and religion != ''">,religion=#{religion}</if>
  <if test="grade != null">,grade=#{grade}</if>
  <if test="className != null and className != ''">,className=#{className}</if>
  <if test="studentPhone != null and studentPhone != ''">,studentPhone=#{studentPhone}</if>
  <if test="address != null and address != ''">,address=#{address}</if>
  <if test="birthday != null and birthday != ''">,birthday=#{birthday}</if>
  <if test="email != null and email != ''">,email=#{email}</if>
  <if test="studentImage != null and studentImage != ''">,studentImage=#{studentImage}</if>
  <if test="guardianName != null and guardianName != ''">,guardianName=#{guardianName}</if>
  <if test="guardianPhone != null and guardianPhone != ''">,guardianPhone=#{guardianPhone}</if>
  <if test="relationshipWithGuardian != null and relationshipWithGuardian != ''">,relationshipWithGuardian=#{relationshipWithGuardian}</if>
  <if test="guardianImage != null and guardianImage != ''">,guardianImage=#{guardianImage}</if>
  <if test="classTeacher != null and classTeacher != ''">,classTeacher=#{classTeacher}</if>
  <if test="teacherPhone != null and teacherPhone != ''">,teacherPhone=#{teacherPhone}</if>
  <if test="teacherImage != null and teacherImage != ''">,teacherImage=#{teacherImage}</if>
</set>
where xxx = #{xxx}

写完这个,估计:
在这里插入图片描述

查询

select 
studentId,name,age,sex,nationality,hmtc,idCard,cardType,politicCountenance,ethnicGroup,nativePlace,studentType,justOnly,floating,leftoverChildren,disability,disabilityType,admissionDate,admissionType,studyMode,studentSource,healthLevel,religion,grade,className,studentPhone,address,birthday,email,studentImage,guardianName,guardianPhone,relationshipWithGuardian,guardianImage,classTeacher,teacherPhone,teacherImage
 from student
<where>
  <if test="studentId != null and studentId != ''">studentId like  concat('%',#{studentId},'%')</if>
  <if test="name != null and name != ''"> and name like  concat('%',#{name},'%')</if>
  <if test="age != null"> and age = #{age}</if>
  <if test="sex != null"> and sex = #{sex}</if>
  <if test="nationality != null"> and nationality = #{nationality}</if>
  <if test="hmtc != null"> and hmtc = #{hmtc}</if>
  <if test="idCard != null and idCard != ''"> and idCard like  concat('%',#{idCard},'%')</if>
  <if test="cardType != null"> and cardType = #{cardType}</if>
  <if test="politicCountenance != null"> and politicCountenance = #{politicCountenance}</if>
  <if test="ethnicGroup != null and ethnicGroup != ''"> and ethnicGroup like  concat('%',#{ethnicGroup},'%')</if>
  <if test="nativePlace != null and nativePlace != ''"> and nativePlace like  concat('%',#{nativePlace},'%')</if>
  <if test="studentType != null"> and studentType = #{studentType}</if>
  <if test="justOnly != null"> and justOnly = #{justOnly}</if>
  <if test="floating != null"> and floating = #{floating}</if>
  <if test="leftoverChildren != null"> and leftoverChildren = #{leftoverChildren}</if>
  <if test="disability != null"> and disability = #{disability}</if>
  <if test="disabilityType != null and disabilityType != ''"> and disabilityType like  concat('%',#{disabilityType},'%')</if>
  <if test="admissionDate != null and admissionDate != ''"> and admissionDate like  concat('%',#{admissionDate},'%')</if>
  <if test="admissionType != null"> and admissionType = #{admissionType}</if>
  <if test="studyMode != null"> and studyMode = #{studyMode}</if>
  <if test="studentSource != null"> and studentSource = #{studentSource}</if>
  <if test="healthLevel != null"> and healthLevel = #{healthLevel}</if>
  <if test="religion != null and religion != ''"> and religion like  concat('%',#{religion},'%')</if>
  <if test="grade != null"> and grade = #{grade}</if>
  <if test="className != null and className != ''"> and className like  concat('%',#{className},'%')</if>
  <if test="studentPhone != null and studentPhone != ''"> and studentPhone like  concat('%',#{studentPhone},'%')</if>
  <if test="address != null and address != ''"> and address like  concat('%',#{address},'%')</if>
  <if test="birthday != null and birthday != ''"> and birthday like  concat('%',#{birthday},'%')</if>
  <if test="email != null and email != ''"> and email like  concat('%',#{email},'%')</if>
  <if test="studentImage != null and studentImage != ''"> and studentImage like  concat('%',#{studentImage},'%')</if>
  <if test="guardianName != null and guardianName != ''"> and guardianName like  concat('%',#{guardianName},'%')</if>
  <if test="guardianPhone != null and guardianPhone != ''"> and guardianPhone like  concat('%',#{guardianPhone},'%')</if>
  <if test="relationshipWithGuardian != null and relationshipWithGuardian != ''"> and relationshipWithGuardian like  concat('%',#{relationshipWithGuardian},'%')</if>
  <if test="guardianImage != null and guardianImage != ''"> and guardianImage like  concat('%',#{guardianImage},'%')</if>
  <if test="classTeacher != null and classTeacher != ''"> and classTeacher like  concat('%',#{classTeacher},'%')</if>
  <if test="teacherPhone != null and teacherPhone != ''"> and teacherPhone like  concat('%',#{teacherPhone},'%')</if>
  <if test="teacherImage != null and teacherImage != ''"> and teacherImage like  concat('%',#{teacherImage},'%')</if>

写完这个,估计:
在这里插入图片描述

参数设置为

List<Student> getAllStudentInfo(
 @Param("studentId")String studentId
, @Param("name")String name
, @Param("age")Integer age
, @Param("sex")Integer sex
, @Param("nationality")Integer nationality
, @Param("hmtc")Integer hmtc
, @Param("idCard")String idCard
, @Param("cardType")Integer cardType
, @Param("politicCountenance")Integer politicCountenance
, @Param("ethnicGroup")String ethnicGroup
, @Param("nativePlace")String nativePlace
, @Param("studentType")Integer studentType
, @Param("justOnly")Integer justOnly
, @Param("floating")Integer floating
, @Param("leftoverChildren")Integer leftoverChildren
, @Param("disability")Integer disability
, @Param("disabilityType")String disabilityType
, @Param("admissionDate")Date admissionDate
, @Param("admissionType")Integer admissionType
, @Param("studyMode")Integer studyMode
, @Param("studentSource")Integer studentSource
, @Param("healthLevel")Integer healthLevel
, @Param("religion")String religion
, @Param("grade")Integer grade
, @Param("className")String className
, @Param("studentPhone")String studentPhone
, @Param("address")String address
, @Param("birthday")String birthday
, @Param("email")String email
, @Param("studentImage")String studentImage
, @Param("guardianName")String guardianName
, @Param("guardianPhone")String guardianPhone
, @Param("relationshipWithGuardian")String relationshipWithGuardian
, @Param("guardianImage")String guardianImage
, @Param("classTeacher")String classTeacher
, @Param("teacherPhone")String teacherPhone
, @Param("teacherImage")String teacherImage);

写完这个
在这里插入图片描述

我就问你,头大不大?现在怕不怕? 反正我自己看了都头皮发麻
在这里插入图片描述

是的,在字段变多以后,编写xml中的语句花费的时间将会大大增长,而且这还不算出错的情况,要是写错一个字母或者符号导致运行失败,那么排查、解决错误花费的时也会很多

不过作为程序员,学会偷懒是必备的。写个工具类让它自动根据实体生成对应的语句不就好了?
在这里插入图片描述

crud工具类

作为CRUD程序员那自然是需要一个快速实现上述功能的工具类了。我苦练多年的Java技术,不是想证明我有多么了不起,我是要告诉别人,我CV的技术真的很流批!
在这里插入图片描述

MybatisCrudHelp.java

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author lwl
 * @title
 * @description 用于快速生成实体类的SQL语句
 * @date 2023/5/11
 **/
public class MybatisCrudHelp {
    //所有字段
    public List<String> fieldList = null;
    //所有类型
    public List<String> typeList = null;
    public StringBuilder stringBuilder = new StringBuilder();

    /**
     * @Description  从对应的实体类中得到各个字段的属性和类型
     * @Param cs 类
     * @Param tableName 表名
     * @Return
     * @Author 三文鱼先生
     * @Date 2023/5/11 14:14
     **/
    public void parseClass(Class cs , String tableName) {
        fieldList = getAllParams(cs);
        typeList = getParamsType(cs , fieldList);
    }

    /**
     * @Description 根据实体类和表名 生成对应的SQL语句
     * @Param cs 实体类
     * @Param tableName 表名
     * @Param type 0 - 插入 1-更新 2-查询
     * @Return {@link String}
     * @Author 三文鱼先生
     * @Date 2023/5/11 14:08
     **/
    public String getString(Class cs , String tableName ,int type) {
        parseClass(cs , tableName);
        return getStr(fieldList , typeList , tableName , type);
    }

    /**
     * @Description 获取所有字段的值 凭接成如 a,b,c....
     * @Param cs
     * @Param tableName
     * @Param type
     * @Return {@link String}
     * @Author 三文鱼先生
     * @Date 2023/4/7 10:25
     **/
    public String getAllFieldString(Class cs , String tableName) {
        parseClass(cs , tableName);
        StringBuilder stringBuilder = new StringBuilder();
        for (int i= 0; i < fieldList.size(); i++) {
            if(i !=0 )
                stringBuilder.append(",");
            stringBuilder.append(fieldList.get(i));
        }
        return stringBuilder.toString();
    }

    /**
     * @Description 获取方法查询时的所有条件
     * @Param cs
     * @Param tableName
     * @Return {@link String}
     * @Author 三文鱼先生
     * @Date 2023/4/14 10:36
     **/
    public String getAllFieldTypeWithParamsString(Class cs , String tableName , boolean needTime) {
        parseClass(cs , tableName);
        StringBuilder stringBuilder = new StringBuilder();
        for (int i= 0; i < fieldList.size(); i++) {
           String[] type = typeList.get(i).split("\\.");
           String fType = type[type.length - 1];

           stringBuilder.append("@Param(\"")
                   .append(fieldList.get(i))
                   .append("\")")
                   .append(fType)
                   .append(" ").append(fieldList.get(i)).append("\n");
           if(i != fieldList.size() - 1) {
                stringBuilder.append(", ");
           }
        }

        //需要时间作为查询参数
        if(needTime) {
            stringBuilder.append(", ");
            stringBuilder.append("@Param(\"")
                    .append("beginTime")
                    .append("\")")
                    .append("String")
                    .append(" ")
                    .append("beginTime\n");

            stringBuilder.append(", ");
            stringBuilder.append("@Param(\"")
                    .append("endTime")
                    .append("\")")
                    .append("String")
                    .append(" ")
                    .append("endTime");
        }
        return stringBuilder.toString();
    }

    /**
     * @Description
     * @Param fieldList 所有字段
     * @Param typeList 所有类型
     * @Param tableName 表名称
     * @Param type 类型 0新增 1更新
     * @Return {@link String}
     * @Author 三文鱼先生
     * @Date 2023/4/6 16:00
     **/
    public String getStr(List<String> fieldList,
            List<String> typeList ,
            String tableName,
            int type) {
        //插入
        if(type==0) {
            stringBuilder.delete(0,stringBuilder.length());
            stringBuilder.append("insert into ").append(tableName).append("(\n");
            //写入条件
            for (int i = 0; i < fieldList.size(); i++) {
                if(i == 0)
                    getNullCondition(fieldList.get(i) , typeList.get(i) , false);
                else
                    getNullCondition(fieldList.get(i) , typeList.get(i) , true);
            }
            stringBuilder.append(" ) values(\n");
            //写入值
            for (int i = 0; i < fieldList.size(); i++) {
                if(i == 0)
                    getValue(fieldList.get(i) , typeList.get(i) , false);
                else
                    getValue(fieldList.get(i) , typeList.get(i) , true);
            }
            stringBuilder.append(")\n");
        }
        //更新
        if(type==1) {
            stringBuilder.delete(0,stringBuilder.length());
            stringBuilder.append("update ").append(tableName).append("\n");
            stringBuilder.append("<set>\n");
            //写入更新条件
            //写入值
            for (int i = 0; i < fieldList.size(); i++) {
                if(i == 0)
                    getValueUpdate(fieldList.get(i) , typeList.get(i) , false);
                else
                    getValueUpdate(fieldList.get(i) , typeList.get(i) , true);
            }
            stringBuilder.append("</set>");
        }
        //查询语句
        if(type == 2) {
            stringBuilder.delete(0,stringBuilder.length());
            stringBuilder.append("select \n");
            //所有返回字段
            for (int i= 0; i < fieldList.size(); i++) {
                if(i !=0 )
                    stringBuilder.append(",");
                stringBuilder.append(fieldList.get(i));
            }
            stringBuilder
                    .append("\n from ").append(tableName).append("\n");
            //所有值
            stringBuilder.append("<where>\n");
            for (int i= 0; i < fieldList.size(); i++) {
                if(i == 0)
                    getQuery(fieldList.get(i) , typeList.get(i) , false);
                else
                    getQuery(fieldList.get(i) , typeList.get(i) , true);
            }

			//默认加入时间范围查询条件
            stringBuilder.append("  <if test=\"")
                    .append("beginTime")
                    .append(" != null")
                    .append(" and ")
                    .append("beginTime")
                    .append(" != ''")
                    .append("\">")
                    .append(" and ")
                    .append("beginTime")
                    .append(" >= ")
                    .append("#{beginTime}")
                    .append("</if>\n");

            stringBuilder.append("  <if test=\"")
                    .append("endTime")
                    .append(" != null")
                    .append(" and ")
                    .append("endTime")
                    .append(" != ''")
                    .append("\">")
                    .append(" and ")
                    .append("#{endTime}")
                    .append(" >= ")
                    .append("endTime")
                    .append("</if>\n");


            stringBuilder.append("</where>\n");
        }
        return stringBuilder.toString();
    }

    /**
     * @Description 获取字段的空的字段那一行
     * 如<if test="field != null and field != ''">field</if>
     * @Param field 字段名称
     * @Param type 字段类型
     * @Param needSymbol 字段前是否需要,标点符号
     * @Return
     * @Author 三文鱼先生
     * @Date 2023/4/6 15:49
     **/
    public void getNullCondition(String field , String type , boolean needSymbol) {
//        System.out.println(field + "  " + type);
        stringBuilder.append("  <if test=\"");
        stringBuilder.append(field)
                .append(" != null");
        //非数字字段要进行判空
        if(!type.equals("class java.lang.Integer")) {
            stringBuilder.append(" and ")
                    .append(field)
                    .append(" != ''");
        }
        stringBuilder.append("\">");
        if(needSymbol)
            stringBuilder.append(",");
        stringBuilder.append(field)
                .append("</if>\n");
    }

    /**
     * @Description 获取字段的空的字段那一行
     * 如<if test="field != null and field != ''">#{field}</if>
     * @Param field 字段名称
     * @Param type 字段类型
     * @Param needSymbol 字段前是否需要,标点符号
     * @Return
     * @Author 三文鱼先生
     * @Date 2023/4/6 15:49
     **/
    public void getValue(String field , String type , boolean needSymbol) {
        stringBuilder.append("  <if test=\"");
        stringBuilder.append(field)
                .append(" != null");
        //非数字字段要进行判空
        if(!type.equals("class java.lang.Integer")) {
            stringBuilder.append(" and ")
                    .append(field)
                    .append(" != ''");
        }
        stringBuilder.append("\">");
        if(needSymbol)
            stringBuilder.append(",");
        stringBuilder.append("#{")
                .append(field)
                .append("}</if>\n");
    }

    /**
     * @Description 获取查询字段的拼接
     * @Param field 字段名
     * @Param type 字段类型
     * @Param needSymbol 是否需要 ,
     * @Return
     * @Author 三文鱼先生
     * @Date 2023/5/11 14:11
     **/
    public void getQuery(String field , String type , boolean needSymbol) {
        stringBuilder.append("  <if test=\"");
        stringBuilder.append(field)
                .append(" != null");
        //非数字字段要进行判空
        if(!type.equals("class java.lang.Integer")) {
            stringBuilder.append(" and ")
                    .append(field)
                    .append(" != ''");
            stringBuilder.append("\">");
            if(needSymbol)
                stringBuilder.append(" and ");
            //oracle的模糊查询
//            stringBuilder
//                    .append(field)
//                    .append(" like '%'||#{")
//                    .append(field)
//                    .append("}||'%'</if>\n");

            //mysql的模糊查询
                stringBuilder
                    .append(field)
                    .append(" like  concat('%',#{")
                    .append(field)
                    .append("},'%')</if>\n");
        }
        else {
            stringBuilder.append("\">");
            if(needSymbol)
                stringBuilder.append(" and ");
            stringBuilder
                    .append(field)
                    .append(" = #{")
                    .append(field)
                    .append("}</if>\n");
        }

    }

    /**
     * @Description  更新语句的字符拼接
     * @Param field 字段
     * @Param type 字段类型
     * @Param needSymbol 是否需要 ,
     * @Return
     * @Author 三文鱼先生
     * @Date 2023/5/11 14:10
     **/
    public void getValueUpdate(String field , String type , boolean needSymbol) {
        stringBuilder.append("  <if test=\"");
        stringBuilder.append(field)
                .append(" != null");
        //非数字字段要进行判空
        if(!type.equals("class java.lang.Integer")) {
            stringBuilder.append(" and ")
                    .append(field)
                    .append(" != ''");
        }
        stringBuilder.append("\">");
        if(needSymbol)
            stringBuilder.append(",");
        stringBuilder.append(field)
                .append("=")
                .append("#{")
                .append(field)
                .append("}</if>\n");
    }


    /**
     * @Description 获取所有对象属性值
     * @Param cs 类名
     * @Return {@link List< String>}
     * @Author 三文鱼先生
     * @Date 2023/5/11 14:11
     **/
    public List<String>  getAllParams(Class cs) {
        List<String> list = new ArrayList<>();
        Field[] fs = cs.getDeclaredFields();
        for (Field f : fs) {
            list.add(f.getName());
        }
        return list;
    }

    /**
     * @Description 获取数据的对应字段的类型
     * @Param cs 类名
     * @Param paramsList 字段的list
     * @Return {@link List< String>}
     * @Author 三文鱼先生
     * @Date 2023/5/11 14:12
     **/
    public List<String> getParamsType(Class cs , List<String> paramsList) {
        List<String> typeClass = new ArrayList<>();
        //对象的所有属性
        Field[] fields = cs.getDeclaredFields();
        //临时的属性 - 类型映射
        Map<String , Class> map = new HashMap();
        //获取属性名称及类型
        for (Field field : fields) {
            map.put(field.getName(), field.getType());
        }
        //遍历属性List获取对应的类型List
        for (String s : paramsList) {
            typeClass.add(map.get(s).toString());
        }
        return typeClass;
    }

}

测试类

现在就来测试一下吧。

public class Test {
    public static void main(String[] args) {
        Class<Student> myClass = Student.class;
        String tableName = "student";
        MybatisCrudHelp crudHelp = new MybatisCrudHelp();
        System.out.println("-------------新增语句-------------------");
        System.out.println(crudHelp.getString(myClass, tableName, 0));
        System.out.println("-------------更新语句-------------------");
        System.out.println(crudHelp.getString(myClass, tableName, 1));
        System.out.println("-------------所有字段-------------------");
        System.out.println(crudHelp.getAllFieldString(myClass , tableName));
        System.out.println("-------------查询语句-------------------");
        System.out.println(crudHelp.getString(myClass, tableName, 2));
        System.out.println("-------------查询方法内的所有条件-------------------");
        System.out.println(crudHelp.getAllFieldTypeWithParamsString(myClass, tableName , false));
    }
}

测试结果控制台输出如下:

-------------新增语句-------------------
insert into student(
 	省略具体参考上面的插入语句
)

-------------更新语句-------------------
update student
<set>
	省略
</set>
-------------所有字段-------------------
studentId,name,age,sex,nationality,hmtc,idCard,cardType,politicCountenance,ethnicGroup,nativePlace,studentType,justOnly,floating,leftoverChildren,disability,disabilityType,admissionDate,admissionType,studyMode,studentSource,healthLevel,religion,grade,className,studentPhone,address,birthday,email,studentImage,guardianName,guardianPhone,relationshipWithGuardian,guardianImage,classTeacher,teacherPhone,teacherImage
-------------查询语句-------------------
select 
studentId,name,age,sex,nationality,hmtc,idCard,cardType,politicCountenance,ethnicGroup,nativePlace,studentType,justOnly,floating,leftoverChildren,disability,disabilityType,admissionDate,admissionType,studyMode,studentSource,healthLevel,religion,grade,className,studentPhone,address,birthday,email,studentImage,guardianName,guardianPhone,relationshipWithGuardian,guardianImage,classTeacher,teacherPhone,teacherImage
 from student
<where>
	省略
  <if test="beginTime != null and beginTime != ''"> and beginTime >= #{beginTime}</if>
  <if test="endTime != null and endTime != ''"> and #{endTime} >= endTime</if>
</where>

-------------查询方法内的所有条件-------------------
@Param("studentId")String studentId
//省略
, @Param("teacherImage")String teacherImage

虽然看起来很方便,但还是有一些值得注意的点。

需要注意的点

查询语句中会自动带上时间范围
在这里插入图片描述
这是因为我遇到大部分查询都是需要的,大家不需要的话可以在工具类中去掉。

更新语句没有where条件
在这里插入图片描述
这是因为不同的表或者业务的更新逻辑都不同,加个参数我又觉得麻烦,所以索性不写,大家按自己的逻辑加上即可。

更新或者新增的参数不能为空
如果为空对象会报sql语句错误,所以最好新增或者更新之前对对象做一个判空的操作

这样的话我们就可以从大部分的基础SQL中解脱出来了。
在这里插入图片描述

开始写bug吧!
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/513871.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JAVAEE】单例模式的介绍及实现(懒汉模式和饿汉模式)

目录 1.单例模式 1.1概念 1.2单例模式的实现方式 怎么去设计一个单例 饿汉模式 懒汉模式 懒汉模式-多线程版 解决懒汉模式多线程不安全问题-synchronized 解决懒汉模式多线程不安全问题-volatile 1.单例模式 1.1概念 单例是一种设计模式。 啥是设计模式 ? 设计模式…

机器学习——弹性网估计

机器学习——弹性网估计 文章目录 机器学习——弹性网估计[toc]1 模型介绍2 模型设定3 弹性网估计 1 模型介绍 弹性网估计属于惩罚回归&#xff0c;常见的惩罚回归包括岭回归(ridge)、套索回归(lasso)和弹性网(elasticnet)回归等。 岭回归用于缓解高维数据可能的多重共线性问…

aws exam

Route 53 Route 53 是AWS的一个服务&#xff0c;它的主要功能如下&#xff0c;下面会一一介绍每个功能 Domain registration&#xff08;域名注册&#xff09;DNS management&#xff08;DNS管理&#xff09;Health check&#xff08;健康检查&#xff09;Routing polices&am…

K8S系列之NetworkPolicy

什么是NetworkPolicy IP 地址或端口层面&#xff08;OSI 第 3 层或第 4 层&#xff09;控制网络流量&#xff0c; 则你可以考虑为集群中特定应用使用 Kubernetes 网络策略&#xff08;NetworkPolicy&#xff09;。 NetworkPolicy 是一种以应用为中心的结构&#xff0c;允许你设…

浅析EasyCVR视频汇聚技术在城市智慧文旅数智平台中的应用意义

一、背景分析 根据文化和旅游部4月21日公布的2023年一季度国内旅游数据情况抽样调查统计结果显示&#xff0c;2023年一季度&#xff0c;国内旅游总人次12.16亿&#xff0c;比上年同期增加3.86亿&#xff0c;同比增长46.5%。其中&#xff0c;城镇居民国内旅游人次9.44亿&#x…

消息和消息队列、以及作用场景(一)

“消息”是在两台计算机间传送的数据单位。消息可以非常简单&#xff0c;例如只包含文本字符串&#xff1b;也可以更复杂&#xff0c;可能包含嵌入对象。 “消息队列”是在消息的传输过程中保存消息的容器。 目前的消息队列有很多&#xff0c;例如&#xff1a;Kafka、RabbitMQ…

包装三年经验拿21K,试用期没过完就被裁了....

最近翻了一些网站的招聘信息&#xff0c;把一线大厂和大型互联网公司看了个遍&#xff0c;发现市场还是挺火热的&#xff0c;虽说铜三铁四&#xff0c;但是软件测试岗位并没有削减多少&#xff0c;建议大家有空还是多关注和多投简历&#xff0c;不要闭门造车&#xff0c;错过好…

Redis命令详解

Redis是一个高性能的内存键值数据库&#xff0c;它支持多种数据结构&#xff0c;包括字符串、哈希、列表、集合、有序集合等。Redis通过提供一组命令来实现对数据的操作&#xff0c;这些命令可以通过Redis客户端发送给Redis服务器&#xff0c;从而对数据库进行操作。 Redis的一…

阿里云刘伟光:2 万字解读金融级云原生

作者&#xff1a;刘伟光&#xff0c;阿里云智能新金融&互联网行业总裁、中国金融四十人论坛常务理事&#xff0c;毕业于清华大学电子工程系 01 前言 2015年云原生理念提出的时候&#xff0c;彼时全球金融百年发展形成的信息化到数字化的背后&#xff0c;金融级的技术服务…

好用工具第1期:手机电脑同屏QtScrcpy

QtScrcpy 可以通过 USB / 网络连接Android设备&#xff0c;并进行显示和控制。无需root权限。 同时支持 GNU/Linux &#xff0c;Windows 和 MacOS 三大主流桌面平台。 QtScrcpy 是一个开源项目, 项目地址是: https://github.com/barry-ran/QtScrcpy 它专注于: 精致 (仅显示设…

Java 责任链模式详解

责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为型设计模式&#xff0c;它用于将请求的发送者和接收者解耦&#xff0c;使得多个对象都有机会处理这个请求。在责任链模式中&#xff0c;有一个请求处理链条&#xff0c;每个处理请求的对象都是一个…

mysql数据库基础知识,mysql数据库简介(一看就懂,一学就会)

目录 一、MySQL学习路线二、MySQL常见操作1、查看所有数据库show databases。2、MySQL 创建数据库3、删除数据库4、选择数据库use databasename5、查看该数据库下所有表show tables6、创建数据库表7、删除数据库 三、增删改查1、插入数据2、查询数据3、where子句4、更新语句5、…

微前端应用(qiankun+umi+antd)

1.微前端介绍以应用选型 1.1什么是微前端? 微前端是一种前端架构模式&#xff0c;它将前端应用程序拆分成多个小型的、独立开发、独立部署的子应用&#xff0c;然后将这些子应用组合成一个大型的、复杂的前端应用。每个子应用都有自己的技术栈、独立的代码库、独立的开发、测…

Linux快捷命令

目录 一、快捷排序——sort 常用选项&#xff1a; 示例 二、快捷去重——uniq 常用选项&#xff1a; 示例&#xff1a; ​编辑 ​编辑 ​编辑 三、快捷替换——tr 用于windows的编写的脚本格式转换为Linux格 方法一&#xff1a; 方法二&#xff1a; 四、快速裁…

JAVA double精度丢失问题

double类型精度丢失问题&#xff1a; 0.1*0.1使用计算器计算是0.01&#xff0c;代码里却是0.010000000000000002 public class HelloWorld {public static void main(String []args) {double number1 0.1;double number2 0.1;double result number1 * number2 ;System.o…

CSP-S 2022 提高级 第一轮 阅读程序(1) 第16-21题

【题目】 CSP-S 2022 提高级 第一轮 阅读程序&#xff08;1&#xff09; 第16-21题 01 #include <iostream> 02 #include <string> 03 #include <vector> 04 05 using namespace std; 06 07 int f(const string &s, const string &t) 08 { …

关于cartographer建立正确关系树的理解

正确的TF关系map----odom----base_link----laser base_link是固定在机器人本体上的坐标系&#xff0c;通常选择飞控 其中map–odom 的链接是由cartographer中lua文件配置完成的 map_frame "map", tracking_frame "base_link", published_frame "b…

Ubuntu 20.04 安装 mysql8 并配置远程访问

文章目录 一、使用 apt-get 安装 mysql 服务二、初始化 mysql 数据库管理员用户密码三、配置远程访问 一、使用 apt-get 安装 mysql 服务 # 更新软件源 apt-get install update# 安装mysql服务 apt-get install mysql-server# 使用mysqladmin工具查看mysql版本 mysqladmin --v…

一文解析Linux进程的睡眠和唤醒

Linux进程的睡眠和唤醒 在Linux中&#xff0c;仅等待CPU时间的进程称为就绪进程&#xff0c;它们被放置在一个运行队列中&#xff0c;一个就绪进程的状 态标志位为 TASK_RUNNING。一旦一个运行中的进程时间片用完&#xff0c; Linux 内核的调度器会剥夺这个进程对CPU的控制权&…

燃气巡检二维码

对燃气公司的输气管道和阀井等设施的巡检工作的管理目标是能降低成本、提高工作效率以及管理水平。但用纸质记录的方式进行燃气设备巡检有以下缺点&#xff1a; 1、难保证巡检真实性 无法客观、方便地掌握巡检人员巡检的到位情况&#xff0c;因而无法有效地保证巡检工作人员按计…