您的位置:首页 > 数据库

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

2016-06-11 14:21 417 查看
项目源码下载: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元素

1、trim元素可以在自己包含的内容前面加上某些前缀,也可以在其后面加上某些后缀,与之对应的属性是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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息