Mybatis动态标签
2021-04-13 本文已影响0人
felixfeijs
Mybatis动态标签
汇总
标签名称 | 示意 |
---|---|
select | 定义查询语句 |
insert | 定义增加语句 |
update | 定义修改语句 |
delete | 定义删除语句 |
resultMap | 绑定结果集和对象属性 |
foreach | 用于遍历 |
if | 用于判断属性 |
choose | 用于多条件判断属性 |
where | 进行语句where拼接 |
set | 格式化update语句 |
trim | 去除属性的空格 |
collection | 多对多关联关系 |
association | 一对一关联关系 |
sql | 定义sql常量片段 |
SQL定义标签
select
-
标签示意:定义查询语句
-
属性示意:
- id :唯一的标识符
- parameterType:传给此语句的参数的全路径名或别名(不填写默认以参数数据类型为主)
- resultType :语句返回值类型或别名
- resultMap :返回一个resultMap(resultMap和resultType不能共用)
-
代码示例
<select id="listMap" resultType="java.util.Map">
select * from bss_user
</select>
insert
-
标签示意:增加语句
-
属性示意:
- id :唯一的标识符
- parameterType:传给此语句的参数的全路径名或别名
- useGeneratedKeys: useGeneratedKeys设置为 true 时,表示如果插入的表userId以自增列为主键,则允许 JDBC 支持自动生成主键,并可将自动生成的主键id返回
- keyProperty: 将主键的值注入到实体类指定的属性中
- keyColumn:指定数据库主键的名称
-
代码示例
<insert id="insert" parameterType="com.example.demo.model.User" keyProperty="userId" keyColumn="user_id">
INSERT INTO
`bss_user`
(`nick_name`, `real_name`, `avatar`, `sex`, `phone`, `password`, `create_time`, `update_time`)
VALUES (#{nickName}, #{realName}, #{avatar}, #{sex}, #{phone}, #{password}, now(), NULL);
</insert>
update
-
标签示意:定义修改语句
-
属性示意:
- id :唯一的标识符
- parameterType:传给此语句的参数的全路径名或别名
-
代码示例
<update id="update" parameterType="com.example.demo.model.User">
update `bss_user`
set `nick_name` = #{nickName}
where `user_id` = #{userId}
</update>
delete
-
标签示意:定义删除语句
-
属性示意:
- id :唯一的标识符
- parameterType:传给此语句的参数的全路径名或别名
-
代码示意
<delete id="deleteById" parameterType="java.lang.String">
delete from `bss_user` where `user_id` = #{userId}
</delete>
sql标签
- 标签示意:定义一些常量片段,比如字段
- 属性示意:
- id:定义标签的标识
- 代码示意:
<sql id="Base_Column" lang="" databaseId="">
`user_id`,`nick_name`, `real_name`, `avatar`, `sex`, `phone`, `password`, `create_time`, `update_time`
</sql>
include标签
- 标签示意:引用常量
- 代码示意:
<select id="listMap" resultType="java.util.Map">
select
<include refid="Base_Column"/>
from bss_user
</select>
配置对象属性与查询结果集标签
resultMap
-
标签示意:将字段名和属性对应起来
-
主标签属性示意:
- id :唯一的标识符
- type:传给此语句的参数的全路径名或别名
- extends: 继承指定namespace的指定的id的resultMap
- autoMapping:在映射时自动忽略大小写,默认false
-
子标签示意:
- id:用于设置主键字段与领域模型属性的映射关系,此处主键为ID,对应id
- result:用于设置普通字段与领域模型属性的映射关系
-
子标签属性示意:
- column: 标识数据库表的字段
- property: 标识实体类的属性
- jdbcType:数据库和实体类类型,不写默认以实体类为主
- typeHandler:对当前结果集再处理
-
代码示意
<resultMap id="userMap" type="com.example.demo.model.User" extends="com.example.demo.mapper.WorkMapper.workMap">
<id column="user_id" property="userId"/>
<result column="nick_name" property="nickName"/>
<result column="real_name" property="realName"/>
<result column="avatar" property="avatar"/>
<result column="sex" property="sex"/>
<result column="phone" property="phone"/>
<result column="password" property="password"/>
<result column="create_time" property="createTime"/>
<result column="update_time" property="updateTime"/>
</resultMap>
<select id="listUser" resultMap="userMap">
select
`user_id`,`nick_name`, `real_name`, `avatar`, `sex`, `phone`, `password`, `create_time`, `update_time`
from bss_user
</select>
动态拼接SQL
if标签
- 标签示意:判断对应属性值是否符合条件,如果符合则执行标签内语句
- 属性示意:
- test:进行属性值的比对
- 代码示意:
<update id="update" parameterType="com.example.demo.model.User">
update `bss_user`
set `nick_name` = #{nickName}
<if test="real_name!=null and real_name!=''">`real_name` = #{real_name}</if>
where `user_id` = #{userId}
</update>
foreach标签
- 标签示意:循环遍历参数,进行语句拼接
- 属性示意:
- collection:标识参数参数的属性值list、array
- item:标识每一个元素的别名
- index:指定一个名字,用于表示在迭代过程中,每次迭代到的位置
- open:表示语句以什么开始,比如"("
- close:表示语句以什么结束,比如")"
- separator:表示语句每次迭代以什么分割
- 代码示意:
<select id="listUser" resultMap="userMap">
select
`user_id`,`nick_name`, `real_name`, `avatar`, `sex`, `phone`, `password`, `create_time`, `update_time`
from bss_user where `user_id` in
<foreach collection="list" index="i" separator="," item="item" open="(" close=")">
#{item}
</foreach>
</select>
choose标签
- 标签示意:多条件判断,相当于多个if else
- 子标签示意:
- when: 用于if的判断
- test属性:判断具体的属性
- otherwise:用于else的判断
- when: 用于if的判断
- 代码示意:
<select id="listUser" resultMap="userMap">
select
`user_id`,`nick_name`, `real_name`,`type`,`avatar`, `sex`, `phone`, `password`, `create_time`, `update_time`
from bss_user where `user_id` = #{userId}
<choose>
<when test="type == 1">
and `sex` = 1
</when>
<when test="type == 2">
and `sex` = 2
</when>
<otherwise>
</otherwise>
</choose>
</select>
格式化输出
where标签
- 标签示意:用于格式化调多余的and
- 错误代码示意: 当第一个条件不成立,第二个条件成立的时候就会出现sql语句拼接错误
<select id="listUser" resultMap="userMap">
select
`user_id`,`nick_name`, `real_name`,`type`,`avatar`, `sex`, `phone`, `password`, `create_time`, `update_time`
from bss_user
where
<if test=" userId != null">
`user_id` = #{userId}
</if>
<if test=" phone != null and phone !=''">
and `phone` = #{phone}
</if>
</select>
- 正确代码示意:where会过滤调多余的and
<select id="listUser" resultMap="userMap">
select
`user_id`,`nick_name`, `real_name`,`type`,`avatar`, `sex`, `phone`, `password`, `create_time`, `update_time`
from bss_user
<where>
<if test=" userId != null">
`user_id` = #{userId}
</if>
<if test=" phone != null and phone !=''">
and `phone` = #{phone}
</if>
</where>
</select>
set标签
- 标签示意:动态配置set关键字,并且剔除追加到条件默认的条件不想关的逗号
- 代码示意:
<update id="update" parameterType="com.example.demo.model.User">
update `bss_user`
<set>
<if test="nickName !=null and nickName !=''">`nick_name` = #{nickName},</if>
<if test="realName !=null and realName !=''">`real_name` = #{realName},</if>
<if test="avatar !=null and avatar !=''">`avatar` = #{avatar},</if>
`update_time` = now()
</set>
where `user_id` = #{userId}
</update>
trim标签
- 标签示意:去除多余关键字标签,和拼接对应的关键字
- 属性示意:
- prefix:前缀的值
- prefixOverrides:指定去除多余的前缀内容
- suffix:在trim标签内sql语句加上后缀
- suffixOverrides:指定去除多余的后缀内容
- 代码示意:
<select id="getUser" resultMap="userMap">
select
`user_id`,`nick_name`, `real_name`,`type`,`avatar`, `sex`, `phone`, `password`, `create_time`, `update_time`
from bss_user
<trim prefix="where" prefixOverrides="AND|OR">
<if test="phone!=null and phone!=''">`phone` = #{phone}</if>
<if test="password!=null and password!=''">and `password` = #{password}</if>
</trim>
</select>
关联关系配置
collection
- 定义父类接受vo
package com.example.demo.vo;
import com.example.demo.model.Article;
import lombok.Data;
import java.util.List;
@Data
public class UserArticleVO {
private String userId;
private String nickName;
private String realName;
private String avatar;
private Integer sex;
private Integer type;
private String phone;
private List<Article> articleList;
}
- 定义子类
package com.example.demo.model;
import lombok.Data;
@Data
public class Article {
private String articleId;
private String userId;
private String title;
private String content;
private String createTime;
private String updateTime;
}
- 定义父类sql片段
<sql id="Base_Column">
bu.`user_id`,bu.`nick_name`, bu.`real_name`, bu.`avatar`, bu.`sex`, bu.`phone`, bu.`password`, bu.`create_time`, bu.`update_time`
</sql>
- 定义子类sql片段
<sql id="Base_Column">
ba.`article_id`, ba.`user_id`, ba.`title`, ba.`content`, ba.`create_time`, ba.`update_time`
</sql>
collection(方式一)
- 优点:代码复用性高,主表分页查询正确
- 缺点:子表需要进行多次的sql查询
- 标签示意:映射一对多的关系
- 属性示意:
- property:主表中声明的多的一方的属性名称
- javaType:指定关联的类型(可以不用指定)
- ofType:指定泛型的类型(可以不用指定)
- select:指定对应的select语句,可以使用 namespace+sqlid 的方式
- column:指定父子集关系对应的关联字段(属性)或传输字段(属性)
- 单个值指定方式:
column="user_id"
,子表中使用的是主表中property="userId"
,该属性的名称 - 多个值指定方式:
column="{userId1=user_id,属性名=主表中column的值}"
,子表中使用#{userId1}
,`属性名`` - 总结:单个值可以直接写,多个值用逗号分隔
- 单个值指定方式:
- 代码示意:
- 定义主表查询语句和resultMap
<resultMap id="userArticleMap" type="com.example.demo.vo.UserArticleVO">
<id column="user_id" property="userId"/>
<result column="nick_name" property="nickName"/>
<result column="real_name" property="realName"/>
<result column="avatar" property="avatar"/>
<result column="sex" property="sex"/>
<result column="phone" property="phone"/>
<result column="type" property="type"/>
<collection property="articleList" column="{user_id=user_id}" select="listArticleByUser"/>
</resultMap>
<sql id="Base_Column">
ba.`article_id`, ba.`user_id`, ba.`title`, ba.`content`, ba.`create_time`, ba.`update_time`
</sql>
<select id="listUserArticle" resultMap="userArticleMap">
select
<include refid="com.example.demo.mapper.DemoMapper.Base_Column"/>
from bss_user bu
</select>
- 定义子表的查询语句
<select id="listArticleByUser" resultType="com.example.demo.model.Article">
select
<include refid="Base_Column"/>
from bss_article ba
where ba.user_id = #{userId}
</select>
collection(方式二)
- 优点:只需要执行一次sql的查询
- 缺点:主表分页查询不正确
- 标签示意:映射一对多的关系
- 属性示意:
- property:主表中声明的多的一方的属性名称
- javaType:指定关联的类型(可以不用指定)
- ofType:指定泛型的类型(必须指定)
- select:指定对应的select语句,可以使用 namespace+sqlid 的方式
- column:指定父子集关系对应的关联字段(属性)或传输字段(属性)
- 代码示意:
- 定义查询语句和resultMap
<resultMap id="userArticleMap" type="com.example.demo.vo.UserArticleVO">
<id column="user_id" property="userId"/>
<result column="nick_name" property="nickName"/>
<result column="real_name" property="realName"/>
<result column="avatar" property="avatar"/>
<result column="sex" property="sex"/>
<result column="phone" property="phone"/>
<collection property="articleList" ofType="com.example.demo.model.Article">
<id column="article_id" property="articleId"/>
<result column="title" property="title"/>
<result column="content" property="content"/>
<result column="create_time" property="createTime"/>
</collection>
</resultMap>
<select id="listUserArticle" resultMap="userArticleMap">
select
bu.`user_id`,bu.`nick_name`, bu.`real_name`, bu.`avatar`, bu.`sex`, bu.`phone`,
ba.`article_id`,ba.`title`, ba.`content`, ba.`create_time`
from bss_user bu left join bss_article ba
on bu.user_id = ba.user_id
</select>
association
- 定义UserVo
package com.example.demo.vo;
import com.example.demo.model.Account;
import lombok.Data;
import java.util.Date;
@Data
public class UserVo {
private String userId;
private String nickName;
private String realName;
private String avatar;
private Integer sex;
private Integer type;
private String phone;
private String createTime;
private Account account;
}
- 定义Account
package com.example.demo.model;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class Account {
private String accountId;
private String userId;
private BigDecimal availableAmount = new BigDecimal(0.00);
private BigDecimal frozenAmount = new BigDecimal(0.00);
private int points;
private String createTime;
private String updateTime;
}
association(方式一)
- 优点:代码复用性高
- 缺点:主表查询一次,子表就要查询一次
- 标签示意:映射一对一的关联查询
- 属性示意:
- property:主表中声明的多的一方的属性名称
- javaType:指定关联的JavaBean对象(可以不用指定)
- select:指定对应的select语句,可以使用 namespace+sqlid 的方式
- column:指定父子集关系对应的关联字段(属性)或传输字段(属性)
- 代码示意:
- 定义主表查询语句和resultMap
<resultMap id="userMap" type="com.example.demo.vo.UserVo">
<id column="user_id" property="userId"/>
<result column="nick_name" property="nickName"/>
<result column="real_name" property="realName"/>
<result column="avatar" property="avatar"/>
<result column="sex" property="sex"/>
<result column="phone" property="phone"/>
<result column="type" property="type"/>
<result column="create_time" property="createTime"/>
<association property="account" select="com.example.demo.mapper.AccountMapper.getAccountByUserId" column="user_id"/>
</resultMap>
<sql id="Base_Column">
bu.`user_id`,bu.`nick_name`, bu.`real_name`, bu.`avatar`, bu.`sex`, bu.`phone`, bu.`password`, bu.`create_time`, bu.`update_time`
</sql>
<select id="getUserAccountByUserId" resultMap="userMap">
select
<include refid="Base_Column"/>
from bss_user bu
where bu.`user_id` = #{userId}
</select>
- 定义子表查询语句
<sql id="Base_Column">
bua.`account_id`,bua.`user_id`,bua.`available_amount`,bua.`frozen_amount`,bua.`points`,bua.`create_time`,bua.`update_time`
</sql>
<select id="getAccountByUserId" resultType="com.example.demo.model.Account">
select
<include refid="Base_Column"/>
from bss_account bua
where bua.`user_id` = #{userId}
</select>
association(方式二)
- 优点:只查询一次
- 标签示意:映射一对一的关联查询
- 属性示意:
- property:主表中声明的多的一方的属性名称
- javaType:指定关联的JavaBean对象(必须指定)
- select:指定对应的select语句,可以使用 namespace+sqlid 的方式
- column:指定父子集关系对应的关联字段(属性)或传输字段(属性)
- 代码示意:
- 定义查询语句和resultMap
<resultMap id="userMap" type="com.example.demo.vo.UserVo">
<id column="user_id" property="userId"/>
<result column="nick_name" property="nickName"/>
<result column="real_name" property="realName"/>
<result column="avatar" property="avatar"/>
<result column="sex" property="sex"/>
<result column="phone" property="phone"/>
<result column="type" property="type"/>
<result column="create_time" property="createTime"/>
<association property="account" javaType="com.example.demo.model.Account">
<id column="account_id" property="accountId"/>
<result column="user_id" property="userId"/>
<result column="available_amount" property="availableAmount"/>
<result column="frozen_amount" property="frozenAmount"/>
<result column="points" property="points"/>
<result column="create_time" property="createTime"/>
<result column="update_time" property="updateTime"/>
</association>
</resultMap>
<select id="getUserAccountByUserId" resultMap="userMap">
select
bu.`user_id`,bu.`nick_name`, bu.`real_name`, bu.`avatar`, bu.`sex`, bu.`phone`,
bua.`account_id`,bua.`available_amount`,bua.`frozen_amount`,bua.`points`,bua.`create_time`,bua.`update_time`
from bss_user bu left join bss_account bua on bu.user_id = bua.user_id
where bu.`user_id` = #{userId}
</select>