Mybatis(四)动态Sql

2022-04-07 23:28:07 浏览数 (1)

首先介绍动态SQL中的if标签,在介绍这个标签之前,添加一下数据库表。

增加两个表并添加对应数据。这个表后面也会用到,这个地方只用了一个表。

代码语言:sql复制
--添加表
CREATE TABLE if not EXISTS t_emp (
`eid`      int NOT NULL   AUTO_INCREMENT,
`emp_name` VARCHAR(20),
`age`      int,
`sex`      char,
`email`    VARCHAR(20),
`did`      int,
PRIMARY KEY(eid) 
) ENGINE=INNODB;

--添加数据

INSERT INTO t_emp values(1, '张三', 23, '男', '123445@qq.com', 1);
INSERT INTO t_emp values(2, '李四', 13, '女', '199092@qq.com', 1);
INSERT INTO t_emp values(3, '王五', 32, '男', '144442@qq.com', 2);
INSERT INTO t_emp values(4, '赵六', 25, '女', '166666@qq.com', 2);

--添加表
CREATE TABLE if NOT EXISTS t_dept (
`did`   int  NOT NULL AUTO_INCREMENT,
`dept_name` VARCHAR(20),
PRIMARY KEY(did)
) ENGINE=INNODB;

--添加数据
insert into t_dept values(1, '研发部');
insert into t_dept values(2, '市场部');

其次,添加两个表对应的实体类。

代码语言:javascript复制
package com.mlzx.pojo;

/**
 * @author: Eric
 * @description: TODO
 * @date: 2022/4/6 22:47
 * @version: 1.0
 */
public class Emp {
    
    private Integer eid;
    
    private String empName;
    
    private Integer age;
    
    private String sex;
    
    private String email;
    
}
代码语言:javascript复制
package com.mlzx.pojo;

import jdk.nashorn.internal.runtime.OptimisticReturnFilters;

/**
 * @author: Eric
 * @description: TODO
 * @date: 2022/4/6 22:49
 * @version: 1.0
 */
public class Dept {
    private Integer did;
    
    private String depaName;
}


IF条件

下面配置mapper配置信息和接口信息。

代码语言:html复制
<!--List<Emp> getEmpByCondition(Emp emp);-->
    <select id="getEmpByCondition" resultType="Emp">
        select * from t_emp where 1 = 1
        <if test="empName != null and empName != ''">
            and emp_name = #{empName}
        </if>
        <if test="age != null and age != ''">
            and age = #{age}
        </if>
        <if test="sex != null and sex != ''">
            and sex = #{sex}
        </if>
        <if test="email != null and email != ''">
            and email = #{email}
        </if>
    </select>

需要注意的是 1=1这个是必须写的,防止出现 select * from t_emp where and sex = ? 的情况,多出来一个and,会报错。

测试代码

代码语言:javascript复制
    @Test
    public void testGetEmpByCondition(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        List<Emp> empList = mapper.getEmpByCondition(new Emp(null, "", 23, "男", "123445@qq.com" ));
        System.out.println(empList);
    }

测试结果可以正常查询

WHERE条件

为了方便起见,我直接写mapper配置文件中的代码

代码语言:html复制
    <select id="getEmpByCondition" resultType="Emp">
        select * from t_emp
        <where>
            <if test="empName != null and empName != ''">
                emp_name = #{empName}
            </if>
            <if test="age != null and age != ''">
                and age = #{age}
            </if>
            <if test="sex != null and sex != ''">
                and sex = #{sex}
            </if>
            <if test="email != null and email != ''">
                and email = #{email}
            </if>
        </where>
    </select>

在相同的情况下,比如emp_name为空的时候,本来后面会变成where and age = xxx的,但是用<where></where>会把and自动去掉。

需要注意的是,去掉and只可以去掉内容前的,如果and放到age = #{age}后面,就不能自动去掉了。


trim

  • trim用于去掉或添加标签中的内容
  • 常用属性
    • prefix:在trim标签中的内容的前面添加某些内容
    • suffix:在trim标签中的内容的后面添加某些内容
    • prefixOverrides:在trim标签中的内容的前面去掉某些内容
    • suffixOverrides:在trim标签中的内容的后面去掉某些内容
  • 若trim中的标签都不满足条件,则trim标签没有任何效果,也就是只剩下select * from t_emp
代码语言:javascript复制
<!--List<Emp> getEmpByCondition(Emp emp);-->
<select id="getEmpByCondition" resultType="Emp">
	select * from t_emp
	<trim prefix="where" suffixOverrides="and|or">
		<if test="empName != null and empName !=''">
			emp_name = #{empName} and
		</if>
		<if test="age != null and age !=''">
			age = #{age} and
		</if>
		<if test="sex != null and sex !=''">
			sex = #{sex} or
		</if>
		<if test="email != null and email !=''">
			email = #{email}
		</if>
	</trim>
</select>

上面代码中的作用是表示,prefix表示在前面添加where,and|or表示去掉where内容后面的and和or,生成的sql中会自动带着and。

Foreach

  • 属性:
  • collection:设置要循环的数组或集合
    • item:表示集合或数组中的每一个数据
    • separator:设置循环体之间的分隔符,分隔符前后默认有一个空格,如,
    • open:设置foreach标签中的内容的开始符
    • close:设置foreach标签中的内容的结束符
  • 批量删除
代码语言:javascript复制
<!--int deleteMoreByArray(Integer[] eids);-->
<delete id="deleteMoreByArray">
	delete from t_emp where eid in
	<foreach collection="eids" item="eid" separator="," open="(" close=")">
		#{eid}
	</foreach>
</delete>
  • 批量添加
代码语言:javascript复制
<!--int insertMoreByList(@Param("emps") List<Emp> emps);-->
<insert id="insertMoreByList">
	insert into t_emp values
	<foreach collection="emps" item="emp" separator=",">
		(null,#{emp.empName},#{emp.age},#{emp.sex},#{emp.email},null)
	</foreach>
</insert>

sql标签

  • sql片段,可以记录一段公共sql片段,在使用的地方通过include标签进行引入
  • 声明sql片段:<sql>标签
代码语言:javascript复制
<sql id="empColumns">eid,emp_name,age,sex,email</sql>

引用sql片段:<include>标签

代码语言:javascript复制
<!--List<Emp> getEmpByCondition(Emp emp);-->
<select id="getEmpByCondition" resultType="Emp">
    select <include refid="empColumns"></include> from t_emp
</select>

祝你每天开心。

0 人点赞