Mybatis动态SQL--采用开发案例讲解

来源:互联网 发布:php开源三级分销商城 编辑:程序博客网 时间:2024/05/21 07:06

项目源码下载:http://download.csdn.net/detail/u013821825/9546237

1、Mybatis动态SQL简介:

动态SQL是mybatis框架强大的特性,在一些组合查询页面,需要根据用户输入的查询条件生成不同的查询SQL,如果在JDBC或者hibernate中需要需要手动拼写SQL,容易出错。
使用动态SQL元素与JSTL性类似,允许在XML中构成不同的SQL语句。(判断元素:if、choose;关键字元素:where、set、trim;循环元素:foreach)

案例中会用到数据库记录,这里还是采用之前的数据库,但是需要增加记录。
数据准备:

create tableCREATE TABLE `emp` (   `id` int(10) NOT NULL,   `name` varchar(20) DEFAULT NULL,   `age` int(3) DEFAULT NULL,   `depNo` int(10) DEFAULT NULL,   `salary` double DEFAULT NULL,   PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC/*[8:30:24][  62 ms]*/ INSERT emp(id,NAME,age) VALUES(5,'马攀婷',28) ;/*[8:30:29][  63 ms]*/ INSERT emp(id,NAME,age) VALUES(6,'马婉婷',27) ;/*[8:30:34][  94 ms]*/ INSERT emp(id,NAME,age) VALUES(7,'mwt',22) ;`/*[8:30:09][  47 ms]*/ INSERT emp(id,NAME,age) VALUES(4,'徐绍校',29) ;INSERT INTO `test`.`emp`(`id`,`name`,`age`) VALUES ( '1','xsx','24');INSERT INTO `test`.`emp`(`id`,`name`,`age`) VALUES ( '2','mpt','23');

if元素是最简单的条件判断逻辑,满足条件追加if元素内的SQL。

<select ...> SQL语句1 <if test="条件表达式"> SQL语句2 </select>

if案例:

阅读之前建议先阅读我的整合案例,此文中所有案例均在整合代码基础上开发的。但是在做案例之前对数据库做了修改,添加了字段属性,我会把数据库SQL复制下来。
案例地址:http://blog.csdn.net/u013821825/article/details/51629433
案例源码下载地址:http://download.csdn.net/detail/u013821825/9546000

1、创建封装查询条件的类

package org.xsx.entity;import java.util.List;public class Condition {    private Integer depNo;    private Double salary;    private List<Integer> ids;    public Integer getDepNo() {        return depNo;    }    public void setDepNo(Integer depNo) {        this.depNo = depNo;    }    public Double getSalary() {        return salary;    }    public void setSalary(Double salary) {        this.salary = salary;    }    public List<Integer> getIds() {        return ids;    }    public void setIds(List<Integer> ids) {        this.ids = ids;    }}

2、修改DAO接口类,增加查询方法

package org.xsx.dao;import java.util.List;import org.xsx.annotation.MyBatisRepository;import org.xsx.entity.Condition;import org.xsx.entity.Emp;/** * DAO组件 * @author xusha * */@MyBatisRepositorypublic interface EmpDao {    public List<Emp> findAll();    public List<Emp> findByEmp(Condition cond);}

3、修改Mapper映射配置文件,增加if查询条件

<!-- if 查询部门下所有的员工 --><select id="findByEmp" parameterType="org.xsx.entity.Condition" resultType="org.xsx.entity.Emp">    select * from emp    <if test="depNo != null">        where depNo = #{depNo}    </if></select>

4、新建测试类和测试方法

package org.xsx.test;import java.util.List;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import org.xsx.dao.EmpDao;import org.xsx.entity.Condition;import org.xsx.entity.Emp;public class TestCondition {    @Test    public void testIf() {        String conf = "applicationContext.xml";        ApplicationContext context = new ClassPathXmlApplicationContext(conf);        EmpDao dao = context.getBean(EmpDao.class);        Condition cond = new Condition();        cond.setDepNo(20);        List<Emp> list = dao.findByEmp(cond);        for (Emp e : list) {            System.out.println(e.getId()+"--"+e.getName()+"--"+e.getAge());        }    }}

5、测试结果

5--马攀婷--28


choose元素相当于java中的switch,基本上和JSTL中的choose作用和用法一样,与when、otherwise一起使用。

<select ...>    SQL语句1    <when test="条件表达式">        SQL语句2    </when>    <otherwise>        SQL语句3    </otherwise></select>

案例:
1、修改DAO组件,增加方法

public List<Emp> findBySalary(Condition cond);

2、修改Mapper映射文件

<!-- choose 查询gongzi大于3300的 --><select id="findBySalary" parameterType="org.xsx.entity.Condition" resultType="org.xsx.entity.Emp">    select * from emp    <choose>        <when test="salary > 3000">            where salary>#{salary}        </when>        <otherwise>            where salary>=3000        </otherwise>    </choose></select>

3、测试

@Test    public void testChoose() {        String conf = "applicationContext.xml";        ApplicationContext context = new ClassPathXmlApplicationContext(conf);        EmpDao dao = context.getBean(EmpDao.class);        Condition cond = new Condition();        cond.setSalary(3500.0);        List<Emp> list = dao.findBySalary(cond);        for (Emp e : list) {            System.out.println(e.getId()+"--"+e.getName()+"--"+e.getSalary());        }    }

4、结果

4--徐绍校--4000.06--马婉婷--4100.07--mwt--5000.0


where元素主要用于简化查询语句中where部分的条件判断,where元素可以在元素所在的位置输出一个where关键字,而且还可以将后面条件多余的and或or关键字去除。

<select ...>    select * from table    <where>        动态追加条件    </where></select>

案例:
1、修改DAO组件

public List<Emp> findByDepNoAndSalary(Condition cond);

2、修改Mapper

<!-- where depNo salary --><select id="findByDepNoAndSalary" parameterType="org.xsx.entity.Condition" resultType="org.xsx.entity.Emp">    select * from emp     <where>        <if test="depNo != null">            and depNo=#{depNo}         </if>        <if test="salary != null">            and salary>={salary}         </if>    </where></select>

3、测试方法

@Test    public void testwhere() {        String conf = "applicationContext.xml";        ApplicationContext context = new ClassPathXmlApplicationContext(conf);        EmpDao dao = context.getBean(EmpDao.class);        Condition cond = new Condition();        cond.setDepNo(30);        cond.setSalary(3500.0);        List<Emp> list = dao.findByDepNoAndSalary(cond);        for (Emp e : list) {            System.out.println(e.getDepNo()+"--"+e.getName()+"--"+e.getSalary());        }    }

4、结果

30--徐绍校--4000.0


set元素主要用于跟新操作,和where相似,在元素位置输出一个set关键字,而且可以去除结尾中无关的逗号,用set元素就可以动态跟新我们需要修改的字段。

<update>    update table    <set>        需要更新的字段    </set></update>

案例:
1、修改DAO组件

public void updateEmp(Emp emp);

2、修改Mapper

<!-- set update  emp --><update id="updateEmp" parameterType="org.xsx.entity.Emp">    update emp     <set>        <if test="name!=null">            name=#{name},        </if>        <if test="depNo!=null">            depNo=#{depNo}         </if>    </set>    where id=#{id}</update>

3、修改测试类

@Test    public void testset() {        String conf = "applicationContext.xml";        ApplicationContext context = new ClassPathXmlApplicationContext(conf);        EmpDao dao = context.getBean(EmpDao.class);        Emp emp = new Emp();        emp.setDepNo(21);        emp.setName("justin");        emp.setId(3);        dao.updateEmp(emp);        List<Emp> list = dao.findAll();        for(Emp e:list){            System.out.println(e.getDepNo()+e.getName());        }    }

4、结果

21justin


trim元素

1trim元素可以在自己包含的内容前面加上某些前缀,也可以在其后面加上某些后缀,与之对应的属性是prefix和suffix;2、可以把包含内容的首部某些内容过滤忽略,也可以把尾部某些内容过滤忽略,对于属性是prefixOverrides和suffixOverrides;3、可以简单的利用trim来代替where和set的功能。

案例:
1、重写update和find方法,增加以下方法

public List<Emp> findByDepNoAndSalary2(Condition cond);    public void updateEmp2(Emp emp);

2、修改Mapper

<!-- trim替代where和set --><select id="findByDepNoAndSalary2" parameterType="org.xsx.entity.Condition" resultType="org.xsx.entity.Emp">    select * from emp     <trim prefix="where" prefixOverrides="and">        <if test="depNo!=null">            and depNo=#{depNo}              </if>        <if test="salary != null">            and salary>#{salary}        </if>    </trim> </select><update id="updateEmp2" parameterType="org.xsx.entity.Emp">    update emp     <trim prefix="set" prefixOverrides=",">        <if test="name!=null">            name=#{name}         </if>        <if test="depNo!=null">            depNo=#{depNo}         </if>    </trim>    where id=#{id}</update>

3、测试

@Test    public void testtrim1() {        String conf = "applicationContext.xml";        ApplicationContext context = new ClassPathXmlApplicationContext(conf);        EmpDao dao = context.getBean(EmpDao.class);        Condition cond = new Condition();        cond.setDepNo(10);        cond.setSalary(3500.0);        List<Emp> list = dao.findByDepNoAndSalary2(cond);        for (Emp e : list) {            System.out.println(e.getDepNo()+"--"+e.getName()+"--"+e.getSalary());        }    }@Test    public void testtrim2() {        String conf = "applicationContext.xml";        ApplicationContext context = new ClassPathXmlApplicationContext(conf);        EmpDao dao = context.getBean(EmpDao.class);        Emp emp = new Emp();        emp.setDepNo(20);        emp.setName("justin bibo");        emp.setId(3);        dao.updateEmp2(emp);        List<Emp> list = dao.findAll();        for(Emp e:list){            System.out.println(e.getDepNo()+e.getName());        }    }

4、结果

10--马婉婷--4100.0
20justin bibo


foreach元素实现循环逻辑,用于对一个集合进行迭代,主要用于在构建in条件中。

<select...>    select column from table where column in    <foreach collection="集合" item="迭代变量" open="(" separator"," close=")">        #{迭代变量}    </foreach> </select>

案例:
1、DAO组件

public List<Emp> findByIds(Condition cond);

2、Mapper组件

<!-- foreach --><select id="findByIds"  parameterType="org.xsx.entity.Condition" resultType="org.xsx.entity.Emp">    select * from emp where id in     <foreach collection="ids" open="(" close=")" separator="," item="id">        #{id}    </foreach></select>

3、测试

@Test    public void testforeach() {        String conf = "applicationContext.xml";        ApplicationContext context = new ClassPathXmlApplicationContext(conf);        EmpDao dao = context.getBean(EmpDao.class);        Condition cond = new Condition();        List<Integer> ids = new ArrayList<Integer>();        ids.add(3);        ids.add(5);        ids.add(7);        ids.add(6);        cond.setIds(ids);        List<Emp> list = dao.findByIds(cond);        for (Emp e : list) {            System.out.println(e.getDepNo()+"--"+e.getName()+"--"+e.getSalary());        }    }

4、结果

20--justin bibo--3000.030--马攀婷--3300.010--马婉婷--4100.015--mwt--5000.0
1 0
原创粉丝点击