【MyBatis】MyBatis操作动态sql && MyBatisGenerator

文章目录

mybatis进阶(动态sql)

Mybatis动态sql

一、<if>标签

在注册用户的时候,分为两种字段:必填字段和非必填字段,那如果在添加用户的时候有不确定的字段传入,程序应该如何实现呢?

这个时候就需要使用动态标签来判断了,比如添加的时候性别gender为非必填字段,具体实现如下:

接口定义:

java 复制代码
Integer insertUserByCondition(UserInfo userInfo);

Mapper.xml实现:

xml 复制代码
<insert id="insertUserByCondition">
    INSERT INTO userinfo (
        username,
        `password`,
        age,
        <if test="gender != null">
            gender,
        </if>
        phone)
    VALUES (
        #{username},
        #{age},
        <if test="gender != null">
            #{gender},
        </if>
        #{phone})
</insert>

Q: 可不可以不进行判断,直接把字段设置为 null 呢?

A: 不可以,这种情况下,如果 gender 字段有默认值,就会设置为默认值。

二、<trim>标签

之前的插入用户功能,只是有一个 gender 字段可能是选填项,如果有多个字段,一般考虑使用标签结合标签,对多个字段都采取动态生成的方式。

标签中有如下属性:

  • prefix:表示整个语句块,以 prefix 的值作为前缀
  • suffix:表示整个语句块,以 suffix 的值作为后缀
  • prefixOverrides:表示整个语句块要去除掉的前缀
  • suffixOverrides:表示整个语句块要去除掉的后缀

调整 Mapper.xml 的插入语句为:

xml 复制代码
<insert id="insertUserByCondition">
    INSERT INTO userinfo
    <trim prefix="(" suffix=")" suffixOverrides=",">
        <if test="username !=null">
            username,
        </if>
        <if test="password !=null">
            `password`,
        </if>
        <if test="age != null">
            age,
        </if>
        <if test="gender != null">
            gender,
        </if>
        <if test="phone != null">
            phone,
        </if>
    </trim>
    VALUES
    <trim prefix="(" suffix=")" suffixOverrides=",">
        <if test="username !=null">
            #{username},
        </if>
        <if test="password !=null">
            #{password},
        </if>
        <if test="age != null">
            #{age},
        </if>
        <if test="gender != null">
            #{gender},
        </if>
        <if test="phone != null">
            #{phone}
        </if>
    </trim>
</insert>

在以上 sql 动态解析时,会将第一个部分做如下处理:

  • 基于 prefix 配置,开始部分加上 (
  • 基于 suffix 配置,结束部分加上 )
  • 多个组织的语句都以 , 结尾,在最后拼接好的字符串还会以 , 结尾,会基于 suffixOverrides 配置去掉最后一个 ,
  • 注意 <if test="username !=null"> 中的 username 是传入对象的属性

三、<where>标签

xml 复制代码
<select id="queryByCondition" resultType="com.example.demo.model.UserInfo">
    select id, username, age, gender, phone, delete_flag, create_time, update_time
    from userinfo
    <where>
        <if test="age != null">
            and age = #{age}
        </if>
        <if test="gender != null">
            and gender = #{gender}
        </if>
        <if test="deleteFlag != null">
            and delete_flag = #{deleteFlag}
        </if>
    </where>
</select>

<where> 只会在子元素有内容的情况下才插入where子句 ,而且会自动去除子句的开头的 and or

四、<set>标签

动态的在SQL语句中插入 set 关键字 ,并会删掉额外的逗号。(用于update语句中)

xml 复制代码
<update id="updateUserByCondition">
    update userinfo
    <set>
        <if test="username != null">
            username = #{username},
        </if>
        <if test="age != null">
            age = #{age},
        </if>
        <if test="deleteFlag != null">
            delete_flag = #{deleteFlag},
        </if>
    </set>
    where id = #{id}
</update>

五、<foreach>标签

对集合进行遍历时可以使用该标签。标签有如下属性:

  • collection:绑定方法参数中的集合,如 List、Set、Map 或数组对象
  • item:遍历时的每一个对象
  • open:语句块开头的字符串
  • close:语句块结束的字符串
  • separator:每次遍历之间间隔的字符串

需求:根据多个userid,删除用户数据

接口方法:

java 复制代码
void deleteByIds(List<Integer> ids);

ArticleMapper.xml 中新增删除 sql:

xml 复制代码
<delete id="deleteByIds">
    delete from userinfo
    where id in
    <foreach collection="ids" item="id" separator="," open="(" close=")">
        #{id}
    </foreach>
</delete>

六、<include>标签

问题分析:

  • 在xml映射文件中配置的SQL,有时可能会存在很多重复的片段,此时就会存在很多冗余的代码

我们可以对重复的代码片段进行抽取,将其通过 <sql> 标签封装到一个SQL片段,然后再通过 <include> 标签进行引用。

  • <sql> :定义可重用的SQL片段
  • <include> :通过属性 refid,指定包含的SQL片段
xml 复制代码
<sql id="allColumn">
    id, username, age, gender, phone, delete_flag, create_time, update_time
</sql>

通过 <include> 标签在原来抽取的地方进行引用。操作如下:

xml 复制代码
<select id="queryAllUser" resultMap="BaseMap">
    select
    <include refid="allColumn"></include>
    from userinfo
</select>

<select id="queryById" resultType="com.example.demo.model.UserInfo">
    select
    <include refid="allColumn"></include>
    from userinfo where id= #{id}
</select>

MyBatisGenerator

MyBatisGenerator 是一个 MyBatis 框架设计的代码生成工具 ,它可以根据数据库表结构自动生成相应的 JavaModelMapper 接口以及 SQL 映射文件,简化数据访问层的编码工作,使得开发者可以更专注于业务逻辑的实现。

1. 引入插件

xml 复制代码
<plugin>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-maven-plugin</artifactId>
    <version>1.3.6</version>
    <executions>
        <execution>
            <id>Generate MyBatis Artifacts</id>
            <phase>deploy</phase>
            <goals>
                <goal>generate</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <!--generator配置文件所在位置-->
        <configurationFile>src/main/resources/mybatisGenerator/generatorConfig.xml</configurationFile>
        <!-- 允许覆盖生成的文件, mapxml不会覆盖, 采用追加的方式-->
        <overwrite>true</overwrite>
        <verbose>true</verbose>
        <!--将当前pom的依赖项添加到生成器的类路径中-->
        <includeCompileDependencies>true</includeCompileDependencies>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
        </dependency>
    </dependencies>
</plugin>

2. 添加 generatorConfig.xml 并修改

文件路径和上述配置保持一致:

完善文件内容:

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<!-- 配置生成器 -->
<generatorConfiguration>
    <!-- 一个数据库一个context -->
    <context id="MysqlTables" targetRuntime="MyBatis3Simple">
        <!--禁用自动生成的注释-->
        <commentGenerator>
            <property name="suppressDate" value="true"/>
            <property name="suppressAllComments" value="true" />
        </commentGenerator>
        <!--数据库连接信息-->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                        connectionURL="jdbc:mysql://127.0.0.1:3306/java_blog_spring?serverTimezone=Asia/Shanghai&amp;nullCatalogMeansCurrent=true"
                        userId="root"
                        password="root">
        </jdbcConnection>
        <!-- 生成实体类, 配置路径 -->
        <javaModelGenerator targetPackage="com.example.demo.model"
                            targetProject="src/main/java" >
            <property name="enableSubPackages" value="false"/>
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>
        <!-- 生成mapxml文件 -->
        <sqlMapGenerator targetPackage="mapper"
                         targetProject="src/main/resources" >
            <property name="enableSubPackages" value="false" />
        </sqlMapGenerator>
        <!-- 生成mapxml对应client,也就是接口dao -->
        <javaClientGenerator targetPackage="com.example.demo.mapper"
                             targetProject="src/main/java" type="XMLMAPPER" >
            <property name="enableSubPackages" value="false" />
        </javaClientGenerator>
        <!-- table可以有多个,tableName表示要匹配的数据库表 -->
        <table tableName="user" domainObjectName="UserInfo"
               enableSelectByExample="true"
               enableDeleteByExample="true" enableDeleteByPrimaryKey="true"
               enableCountByExample="true"
               enableUpdateByExample="true">
            <!-- 类的属性是否用数据库中的真实字段名做为属性名, 不指定这个属性会自动转换 _ 为驼峰命名规则-->
            <property name="useActualColumnNames" value="false" />
            <!-- 数据库表主键 -->
            <generatedKey column="id" sqlStatement="Mysql" identity="true" />
        </table>
    </context>
</generatorConfiguration>

3. 生成文件

双击运行就可以了。

相关推荐
一瓢西湖水2 小时前
loader命令导出大批量数据维护SQL
数据库·sql
柒.梧.3 小时前
MyBatis实战精讲:完整用户CRUD操作全解析
mybatis
颜颜yan_3 小时前
时序数据库选型指南:工业物联网时代如何选择数据底座
数据库·物联网·时序数据库
云和数据.ChenGuang3 小时前
Logstash配置文件的**语法解析错误**
运维·数据库·分布式·rabbitmq·jenkins
CICI131414133 小时前
焊接机器人负载能力选择标准
网络·数据库·人工智能
minhuan4 小时前
大模型应用:从交易行为到实时反欺诈:向量数据库驱动的智能风控实践.33
数据库·向量数据库·大模型应用·chromadb数据库
晴天¥4 小时前
Oracle中的安全管理(用户、权限、角色)
数据库·安全·oracle
Jelly-小丑鱼4 小时前
Linux搭建SQLserver数据库和Orical数据库
linux·运维·数据库·sqlserver·oracal·docker容器数据库
JIngJaneIL4 小时前
基于springboot + vue健康管理系统(源码+数据库+文档)
java·开发语言·数据库·vue.js·spring boot·后端