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

项目源码下载: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 table CREATE 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 * */
@MyBatisRepository
public 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.0
6--马婉婷--4100.0
7--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.0
30--马攀婷--3300.0
10--马婉婷--4100.0
15--mwt--5000.0

你可能感兴趣的:(Hibernate,框架,xml,mybatis,jdbc)