文章目录
- mybatis进阶(动态sql)
- 一、`<if>`标签
- 二、`<trim>`标签
- 三、`<where>`标签
- 四、`<set>`标签
- 五、`<foreach>`标签
- 六、`<include>`标签
- MyBatisGenerator
- 1. 引入插件
- 2. 添加 generatorConfig.xml 并修改
- 3. 生成文件
mybatis进阶(动态sql)
Mybatis动态sql
一、<if>标签
在注册用户的时候,分为两种字段:必填字段和非必填字段,那如果在添加用户的时候有不确定的字段传入,程序应该如何实现呢?
这个时候就需要使用动态标签来判断了,比如添加的时候性别gender为非必填字段,具体实现如下:
接口定义:
IntegerinsertUserByCondition(UserInfouserInfo);Mapper.xml实现:
<insertid="insertUserByCondition">INSERT INTO userinfo ( username, `password`, age,<iftest="gender != null">gender,</if>phone) VALUES ( #{username}, #{age},<iftest="gender != null">#{gender},</if>#{phone})</insert>Q:可不可以不进行判断,直接把字段设置为
null呢?A:不可以,这种情况下,如果
gender字段有默认值,就会设置为默认值。
二、<trim>标签
之前的插入用户功能,只是有一个gender字段可能是选填项,如果有多个字段,一般考虑使用标签结合标签,对多个字段都采取动态生成的方式。
标签中有如下属性:
prefix:表示整个语句块,以 prefix 的值作为前缀suffix:表示整个语句块,以 suffix 的值作为后缀prefixOverrides:表示整个语句块要去除掉的前缀suffixOverrides:表示整个语句块要去除掉的后缀
调整 Mapper.xml 的插入语句为:
<insertid="insertUserByCondition">INSERT INTO userinfo<trimprefix="("suffix=")"suffixOverrides=","><iftest="username !=null">username,</if><iftest="password !=null">`password`,</if><iftest="age != null">age,</if><iftest="gender != null">gender,</if><iftest="phone != null">phone,</if></trim>VALUES<trimprefix="("suffix=")"suffixOverrides=","><iftest="username !=null">#{username},</if><iftest="password !=null">#{password},</if><iftest="age != null">#{age},</if><iftest="gender != null">#{gender},</if><iftest="phone != null">#{phone}</if></trim></insert>在以上sql动态解析时,会将第一个部分做如下处理:
- 基于
prefix配置,开始部分加上( - 基于
suffix配置,结束部分加上) - 多个组织的语句都以 , 结尾,在最后拼接好的字符串还会以
,结尾,会基于suffixOverrides配置去掉最后一个, - 注意
<if test="username !=null">中的username是传入对象的属性
三、<where>标签
<selectid="queryByCondition"resultType="com.example.demo.model.UserInfo">select id, username, age, gender, phone, delete_flag, create_time, update_time from userinfo<where><iftest="age != null">and age = #{age}</if><iftest="gender != null">and gender = #{gender}</if><iftest="deleteFlag != null">and delete_flag = #{deleteFlag}</if></where></select><where>只会在子元素有内容的情况下才插入where子句,而且会自动去除子句的开头的and或or。
四、<set>标签
动态的在SQL语句中插入 set 关键字,并会删掉额外的逗号。(用于update语句中)
<updateid="updateUserByCondition">update userinfo<set><iftest="username != null">username = #{username},</if><iftest="age != null">age = #{age},</if><iftest="deleteFlag != null">delete_flag = #{deleteFlag},</if></set>where id = #{id}</update>五、<foreach>标签
对集合进行遍历时可以使用该标签。标签有如下属性:
collection:绑定方法参数中的集合,如 List、Set、Map 或数组对象item:遍历时的每一个对象open:语句块开头的字符串close:语句块结束的字符串separator:每次遍历之间间隔的字符串
需求:根据多个userid,删除用户数据
接口方法:
voiddeleteByIds(List<Integer>ids);ArticleMapper.xml 中新增删除 sql:
<deleteid="deleteByIds">delete from userinfo where id in<foreachcollection="ids"item="id"separator=","open="("close=")">#{id}</foreach></delete>六、<include>标签
问题分析:
- 在xml映射文件中配置的SQL,有时可能会存在很多重复的片段,此时就会存在很多冗余的代码
我们可以对重复的代码片段进行抽取,将其通过<sql>标签封装到一个SQL片段,然后再通过<include>标签进行引用。
<sql>:定义可重用的SQL片段<include>:通过属性refid,指定包含的SQL片段
<sqlid="allColumn">id, username, age, gender, phone, delete_flag, create_time, update_time</sql>通过<include>标签在原来抽取的地方进行引用。操作如下:
<selectid="queryAllUser"resultMap="BaseMap">select<includerefid="allColumn"></include>from userinfo</select><selectid="queryById"resultType="com.example.demo.model.UserInfo">select<includerefid="allColumn"></include>from userinfo where id= #{id}</select>MyBatisGenerator
MyBatisGenerator是一个为MyBatis框架设计的代码生成工具,它可以根据数据库表结构自动生成相应的JavaModel,Mapper接口以及SQL映射文件,简化数据访问层的编码工作,使得开发者可以更专注于业务逻辑的实现。
1. 引入插件
<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 version="1.0" encoding="UTF-8"?><!DOCTYPEgeneratorConfigurationPUBLIC"-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"><!-- 配置生成器 --><generatorConfiguration><!-- 一个数据库一个context --><contextid="MysqlTables"targetRuntime="MyBatis3Simple"><!--禁用自动生成的注释--><commentGenerator><propertyname="suppressDate"value="true"/><propertyname="suppressAllComments"value="true"/></commentGenerator><!--数据库连接信息--><jdbcConnectiondriverClass="com.mysql.jdbc.Driver"connectionURL="jdbc:mysql://127.0.0.1:3306/java_blog_spring?serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true"userId="root"password="root"></jdbcConnection><!-- 生成实体类, 配置路径 --><javaModelGeneratortargetPackage="com.example.demo.model"targetProject="src/main/java"><propertyname="enableSubPackages"value="false"/><propertyname="trimStrings"value="true"/></javaModelGenerator><!-- 生成mapxml文件 --><sqlMapGeneratortargetPackage="mapper"targetProject="src/main/resources"><propertyname="enableSubPackages"value="false"/></sqlMapGenerator><!-- 生成mapxml对应client,也就是接口dao --><javaClientGeneratortargetPackage="com.example.demo.mapper"targetProject="src/main/java"type="XMLMAPPER"><propertyname="enableSubPackages"value="false"/></javaClientGenerator><!-- table可以有多个,tableName表示要匹配的数据库表 --><tabletableName="user"domainObjectName="UserInfo"enableSelectByExample="true"enableDeleteByExample="true"enableDeleteByPrimaryKey="true"enableCountByExample="true"enableUpdateByExample="true"><!-- 类的属性是否用数据库中的真实字段名做为属性名, 不指定这个属性会自动转换 _ 为驼峰命名规则--><propertyname="useActualColumnNames"value="false"/><!-- 数据库表主键 --><generatedKeycolumn="id"sqlStatement="Mysql"identity="true"/></table></context></generatorConfiguration>3. 生成文件
双击运行就可以了。