项目源码下载: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>
阅读之前建议先阅读我的整合案例,此文中所有案例均在整合代码基础上开发的。但是在做案例之前对数据库做了修改,添加了字段属性,我会把数据库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