> 文档中心 > MyBatis动态SQL

MyBatis动态SQL

分页查询:RowBounds,SQL语句实现。

主键回填:表示插入数据的时候,主键列使用数据库主键生成策略(MySQL数据库,主键列必须设置auto_increment;SQLServer数据库必须设置主键列使用identity(起始值,步长));表示将插入数据的主键列的值赋值给对象的这个属性

如果整个应用中所有的表插入数据都要使用主键回填,可以在主配置文件中设置。

        

初始化项目,使用MySQL数据库。

一、if 标签

if 标签单分支判断语句

1. DeptMapper.java

public interface DeptMapper {    List queryByIf(Dept dept);}

2. DeptMapper.xml

deptno,dname,loc as cityselect  from dept_bak where 1=1and deptno = #{deptno}and dname = #{dname}and loc = #{city}

3. DeptMapperTest.java

package com.dyh.test;import com.dyh.dao.DeptMapper;import com.dyh.pojo.Dept;import com.dyh.util.MybatisUtil;import org.apache.ibatis.session.SqlSession;import org.junit.Test;import java.util.List;import static org.junit.Assert.*;public class DeptMapperTest {    SqlSession session;    DeptMapper mapper;    @org.junit.Before    public void setUp() throws Exception { session = MybatisUtil.getConnection(); mapper = session.getMapper(DeptMapper.class);    }    @Test    public void testQueryByIf(){ Dept dept = new Dept(); //dept.setDeptno(1); dept.setDname("财务部"); dept.setCity("南京"); List list = mapper.queryByIf(dept); list.forEach(System.out::println);    }    @org.junit.After    public void tearDown() throws Exception { MybatisUtil.closeConnection();    }}

修改dept对象的属性值,进行测试,运行结果:

 

二、choose、 when、 otherwise标签

choose是多选一,类似于switch……case中加了break。

1. DeptMapper.java

添加如下方法:

List queryByChoose(Dept dept);

2. DeptMapper.xml

select  from dept_bak where 1=1and deptno = #{deptno}and dname = #{dname}and loc = #{city}and deptno = 1

3. TestDeptMapper.java

  @Test    public void testQueryByChoose(){ Dept dept = new Dept(); //dept.setDeptno(1); dept.setDname("财务部"); dept.setCity("南京"); List list = mapper.queryByChoose(dept); list.forEach(System.out::println);    }

测试运行结果

 

三、where标签

使用 where 标签,就不需要提供where 1=1 这样的条件了。 如果判断条件不为空则自动添加 where 关键字,并且会自动去掉第一个条件前面的 and 或or

1. DeptMapper.java

添加如下代码

List queryByWhere(Dept dept);

2. DeptMapper.xml

添加如下代码:

select  from dept_bakand deptno = #{deptno}and dname = #{dname}and loc = #{city}

3. DeptMapperTest.java

添加如下代码:

 @Test    public void testQueryByWhere(){ Dept dept = new Dept(); //dept.setDeptno(1); dept.setDname("财务部"); dept.setCity("南京"); List list = mapper.queryByWhere(dept); list.forEach(System.out::println);    }

四、bind标签

bind 标签允许我们在 OGNL 表达式以外创建一个变量,并可以将其绑定到当前的 SQL 语句中。 一般应用于模糊查询,通过 bind 绑定通配符和查询值。

1. DeptMapper.java

其中添加如下代码:

  /     * 根据部门名称模糊查询,使用bind标签     * @param dname     * @return     */    List queryByLikeBind(String dname);

2. DeptMapper.xml

其中添加如下代码:

select  from dept_bakwhere dname like #{likeDname}

3. DeptMapperTest.java

添加如下代码:

 @Test    public void testQueryLikeByBind(){ List list = mapper.queryByLikeBind("务"); list.forEach(System.out::println);    }

五、set标签

set 标签用在 update 语句中。 借助 if 标签,可以只对有具体值的字段进行更新。 set 标 签会自动添加 set 关键字, 自动去掉最后一个 if 语句的多余的逗号

1. DeptMapper.java

添加如下代码:

 /     * 更新数据,使用set标签     * @param dept     */    void updateDeptUseSet(Dept dept);

2. DeptMapper.xml

添加如下代码:

update dept_bakdname = #{dname},loc = #{city},where deptno = #{deptno}

3. DeptMapperTest.java

添加如下代码:

 @Test    public void testupdateDeptUseSet(){ Dept dept = new Dept(10,"acount","纽约"); dept.setCity(null);// 第二次测试 dept.setDeptno(11); dept.setDeptno(12);// 第三次测试 dept.setCity("伦敦"); dept.setDname(null); mapper.updateDeptUseSet(dept); session.commit();    }

六、foreach标签

foreach 标签的功能非常强大,我们可以将任何可迭代对象如 List、 Set 、 Map 或者数 组对象作为集合参数传递给 foreach 标签进行遍历。它也允许我们指定开头与结尾的字符串以及集合项迭代之间的分隔符。

属性 描述
collection 表示迭代集合的名称或类型。如果使用名称指定,可以使用@Param 注解指定。 该属 性为必选属性。
item 表示本次迭代获取的元素,若 collection 为 List、 Set 或者数组,则表示其中的元素; 若 collection 为 map,则代表 key-value 的 value,该属性为必选属性。
open 表示该语句以什么开始,最常用的是左括弧’(’,注意:Mybatis 会将该字符拼接到 循环元素之前,并且只拼接一次,该属性为可选属性。
close 表示该语句以什么结束,最常用的是右括弧’)’,注意:Mybatis 会将该字符拼接到 循环元素之后,并且只拼接一次,该属性为可选属性。
separator 在每次循环中为 SQL 语句添加 separator 属性指定的字符,但最后一次循环不在添加。 该属性为可选属性。
index 在 List、 Set 和数组中,index 表示当前迭代的序号。 在 Map 中,index 为元素的 Key, item 为元素的 Value。 该属性为可选属性。

1、遍历Collection或数组

1.1 DeptMapper.java

增加如下代码:

 /     * 根据id集合查询     * @param collection  id集合     */    List queryInIdsCollection(Collection collection);    /     * 根据id数组查询     * @param ids     id数组     */    List queryInIdsArray(int[] ids);

1.2 DeptMapper.xml

增加如下代码:

select  from dept_bak where deptno in#{did}select  from dept_bak where deptno in#{did}

1.3 DeptMapperTest.java

添加如下代码:

  @Test    public void testQueryByIdsCollection(){ List list = new ArrayList(); list.add(1); list.add(3); list.add(5); List list1 = mapper.queryInIdsCollection(list); list1.forEach(System.out::println); Set set = new HashSet(); set.add(7); set.add(8); set.add(9); List list2 = mapper.queryInIdsCollection(set); list2.forEach(System.out::println);    }    @Test    public void testQueryByIdsArray(){ int[] ids = new int[]{2,4,6}; List list =mapper.queryInIdsArray(ids); list.forEach(System.out::println);    }

2、遍历Map

应用场景:组合查询,根据用户传递的参数拼接查询条件。

2.1 DeptMapper.java

增加如下代码:

  /     * 组合查询,动态拼接SQL语句     * @param map  : String 数据库中列名 Object 对象的属性值类型     * @return     */    List queryByMap(@Param(value="paramMap") Map map);

2.2 DeptMapper.xml

增加如下代码:

select  from dept_bak where${key} = #{value}

注意:collection后面的属性值表示参数,index获取map中的key值,item获取map中的key对应的value值。${}直接使用字符串,#{}会变成?,执行的时候用参数值替换。

2.3 DeptMapperTest.java

添加如下代码:

 @Test    public void testQueryByMap(){ Map paramMap = new HashMap(); //paramMap.put("deptno", new Integer(9)); paramMap.put("dname", "销售部"); paramMap.put("loc", "深圳"); List list =mapper.queryByMap(paramMap); System.out.println(list.size()); list.forEach(System.out::println);    }

3、使用 foreach 标签完成批量添加

3.1 DeptMapper.java

增加如下代码:

  /     * 批量插入数据     * @param depts   部门集合     */    void batchAdd(@Param(value="depts") List depts);

3.2 DeptMapper.xml

增加如下代码:

insert  into dept_bak(deptno, dname, loc) values(default , #{d.dname}, #{d.city})

最终SQL批量插入的语句,要拼接成下面的效果:

INSERT INTO dept_bak(deptno,dname,loc) VALUES(DEFAULT,'研发部','上海'),(DEFAULT,'策划部','武汉'),(DEFAULT,'销售部','深圳');

3.3 DeptMapperTest.java

增加如下代码:

  @Test    public void testBatchAdd(){ List depts = new ArrayList(); depts.add(new Dept(17, "华山派", "陕西")); depts.add(new Dept(17, "嵩山派", "河南")); depts.add(new Dept(17, "衡山牌", "湖南")); mapper.batchAdd(depts); session.commit();    }

总结

1、if 标签单分支判断语句,test后的值为测试条件;

2、choose……when……otherwise是多选一,类似于switch……case中加了break;

3、使用 where 标签,就不需要提供where 1=1 这样的条件了。 如果判断条件不为空则自动添加 where 关键字,并且会自动去掉第一个条件前面的 and 或or

4、bind 标签允许我们在 OGNL 表达式以外创建一个变量,并可以将其绑定到当前的 SQL 语句中。 一般应用于模糊查询,通过 bind 绑定通配符和查询值。

5、set 标签用在 update 语句中。 借助 if 标签,可以只对有具体值的字段进行更新。 set 标 签会自动添加 set 关键字, 自动去掉最后一个 if 语句的多余的逗号

6、foreach 标签的功能非常强大,我们可以将任何可迭代对象如 List、 Set 、 Map 或者数 组对象作为集合参数传递给 foreach 标签进行遍历。它也允许我们指定开头与结尾的字符串以及集合项迭代之间的分隔符。