(一) 动态sql介绍
1. 动态sql的概念
顾名思义,SQL 是动态拼接成的,根据传入的变量值进行逻辑操作并动态拼接,方便实现多条件下的数据库操作。在业务逻辑复杂,即简单 SQL 无法完成时,需要拼接时就要使用动态SQL。
2. 动态sql解决的问题
动态sql主要解决根据条件判断附加条动态sql主要解决多条件变化查询,实现自动判断记录字段是否需要更新,根据条件判断附加条sql条件,实现批量添加数据、批量修改数据、批量修删除数据等,优化sql语句,提高执行效率。
(二) 构建测试环境
1. 创建maven项目
添加依赖
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
创建bean
public class User implements Serializable {
private Integer id;
private String name;
private String gender;
private Integer age;
private Date birthday;
public User() {}
public User(String name, String gender, Integer age, Date birthday) {
this.name = name;
this.gender = gender;
this.age = age;
this.birthday = birthday;
}
//生成getter和setter方法
}
创建接口
public interface UserMapper {
}
2.编写框架配置文件和sql映射文件
编写框架配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 配置 mybatis的环境 -->
<environments default="development">
<!-- 配置环境 -->
<environment id="development">
<!-- 配置事务的类型 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置连接数据库的信息:用的是数据源【连接池】-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis001"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 注册UserDao接品映射文件位置 -->
<mappers>
<mapper resource="cn/edu/mapper/UserMapper.xml"/>
</mappers>
</configuration>x
sql映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.edu.mapper.UserMapper">
</mapper>
(三) where标签
1.where标签简介
where标签用于代替sql中的where关键字,可以根据条件判断是否附加where关键字。如果where标签中有条件成立就会附加where关键字,如果没有成立的条件就不会附加where关键字. 可以去掉离他最近一个无关的and 或or关键字.where标签的书写格式为<where>添写附加条件</where>
1.where标签可以被解析为where 关键字
2.可以去掉离他最近的一个无用的and
2.where标签使用
1)编写接口方法findByUser
/**
? ? * 根据User中的字段进行查询
? ? * @return
? ? */
? ?List<User> getUserByNameAndSex(Map map);
2) 使用where标签进行sql处理
<!--where 标签的使用-->
<select id="getUserByNameAndSex" parameterType="map" resultType="user">
? select * from user
? ?<where>
? ? ? and uname like '%${username}%' and sex=#{usex}
? ?</where>
</select>
3) 测试findByUser方法
@Test
?public void demo01(){
? ? ? ?SqlSession sqlSession = MybatisUtils.getSqlSession();
? ? ? ?UserMapper mapper = sqlSession.getMapper(UserMapper.class);
? ? ? ?Map map=new HashMap<String,Object>();
? ? ? ?map.put("username","赵");
? ? ? ?map.put("usex","男");
? ? ? ?List<User> userList = mapper.getUserByNameAndSex(map);
? ? ? ?System.out.println(userList.size());
? ? ? ?sqlSession.close();
? }
?
(四) if标签标签的应用
1. if标签简介
if标签表示逻辑条件判断,如果条件成立就附加<if></if>之间的sql语句,如果条件不成立就不附加<if></if>之间的sql语句。书写格式为:<if test="表达式">sql语句</if>
2. if标签使用
1)编写接口方法findByUser
/**
? ? * 根据User中的字段进行查询
? ? * @return
? ? */
? ?List<User> getUserDy01(Map map);
2) 使用if标签进行sql处理
<!--if uname ? ? sex nan-->
<select id="getUserDy01" parameterType="map" resultType="user">
? select * from user
? ?<where>
? ? ?<if test="uname!=null and uname!=''">
? ? ? ? uname like '%${uname}%'
? ? ?</if>
? ? ?<if test="sex!=null and sex!=''">
? ? ? ? and sex=#{sex}
? ? ?</if>
? ?</where>
</select>
3) 测试findByUser方法
@Test
public void demo02(){
? ? SqlSession sqlSession = MybatisUtils.getSqlSession();
? ? UserMapper mapper = sqlSession.getMapper(UserMapper.class);
? ? Map map=new HashMap<String,Object>();
? ? //map.put("uname","赵");
? ? //map.put("sex","男");
?
? ? List<User> userList = mapper.getUserDy01(map);
? ? System.out.println(userList.size());
? ? sqlSession.close();
}
?
(五) set标签的应用
1. set标签简介
set标签用于更新语句中,代替set关键字,可以有效对指定字段进行更新,提升sql的执行效率。,当set标签中有条件成立时就会附加set标签,set标签会去除无关的逗号。set标签中一般嵌套if标签进行使用其格式为
<set>
<if test="name">
name=#{name},
</if>
<if test="age">
age=#{age},
</if>
......
</set>
1.set标签用于更新语句中
2.set标签解析为set关键字
3.set可以去除跟新语句中无用的逗号
4.通常是和if标签一起使用
2. set标签使用
1) 编写接口方法updateUser
/**
? ? * 更新user
? ? * @param user
? ? */
? int updateUserById(User user);
2) 使用set标签进行sql处理
<update id="updateUserById" parameterType="user">
? ? update user
? ? <set>
? ? ? ? <if test="uid!=null">
? ? ? ? ? uid=#{uid},
? ? ? ? </if>
? ? ? ? <if test="uname!=null and uname!=''">
? ? ? ? ? ? uname=#{uname},
? ? ? ? </if>
? ? ? ? <if test="sex!=null and sex!=''">
? ? ? ? ? ? sex=#{sex},
? ? ? ? </if>
? ? ? ? <if test="password!=null and password!=''">
? ? ? ? ? ? password=#{password},
? ? ? ? </if>
? ? ? ? <if test="birthday!=null">
? ? ? ? ? ? birthday=#{birthday}
? ? ? ? </if>
? ? </set>
? ? where uid=#{uid}
</update>
3) 测试updateUser方法
@Test
public void demo03(){
? ? SqlSession sqlSession = MybatisUtils.getSqlSession();
? ? UserMapper mapper = sqlSession.getMapper(UserMapper.class);
?
? ? User user=new User("","女","",null);
? ? user.setUid(6);
?
? ? int i=mapper.updateUserById(user);
? ? System.out.println(i);
? ? sqlSession.close();
}
通过产生的sql语句可以看出,当set标签中有条件成立时就会附加set关键字,字段为null时该列不会被更新。set可以忽略与sql无关的逗号。
(六) trim标签
1. trim标签简介
trim标签为万能标签,可用于set或where等。prefix表示要附加的前缀关键字,suffix表示要附加的后缀关键字,prefixOverrides表示要忽略前置字符,suffixOverrides表示要忽略后置字符。
格式:
<trim prefix="where" prefixOverrides=",">
? ? <if test="name!=null">
? ? ? ? name=#{name}
? ? </if>
? ? <if test="age!=null">
? ? ? ? age=#{age}
? ? </if>
? ? <if test="name!=null">
? ? ? ? gender=#{gender}
? ? </if>
</trim>
2. trim标签使用
1) 修改where标签和set标签
1)应用于where
<select id="getUserDy01" parameterType="map" resultType="user">
? ? select * from user
? ? <trim prefix="where" prefixOverrides="and">
? ? ? ? <if test="uname!=null and uname!=''">
? ? ? ? ? ? and uname like '%${uname}%'
? ? ? ? </if>
? ? ? ? <if test="sex!=null and sex!=''">
? ? ? ? ? ? and sex=#{sex}
? ? ? ? </if>
? ? </trim>
</select>
2)用于set标签
<update id="updateUserById" parameterType="user">
? ? update user
? ? <trim prefix="set" suffixOverrides="," suffix="where uid=#{uid}">
? ? ? ? <if test="uid!=null">
? ? ? ? ? ? uid=#{uid},
? ? ? ? </if>
? ? ? ? <if test="uname!=null and uname!=''">
? ? ? ? ? ? uname=#{uname},
? ? ? ? </if>
? ? ? ? <if test="sex!=null and sex!=''">
? ? ? ? ? ? sex=#{sex},
? ? ? ? </if>
? ? ? ? <if test="password!=null and password!=''">
? ? ? ? ? ? password=#{password},
? ? ? ? </if>
? ? ? ? <if test="birthday!=null">
? ? ? ? ? ? birthday=#{birthday}
? ? ? ? </if>
? ? </trim>
</update>
2) 测试方法测试updateUser和findUsersByCondition方法
@Test
public void demo02(){
? ? SqlSession sqlSession = MybatisUtils.getSqlSession();
? ? UserMapper mapper = sqlSession.getMapper(UserMapper.class);
? ? Map map=new HashMap<String,Object>();
? ? map.put("uname","赵");
? ? //map.put("sex","男");
?
? ? List<User> userList = mapper.getUserDy01(map);
? ? System.out.println(userList.size());
? ? sqlSession.close();
}
?
@Test
public void demo03(){
? ? SqlSession sqlSession = MybatisUtils.getSqlSession();
? ? UserMapper mapper = sqlSession.getMapper(UserMapper.class);
?
? ? User user=new User("","女","",null);
? ? user.setUid(6);
?
? ? int i=mapper.updateUserById(user);
? ? System.out.println(i);
? ? sqlSession.close();
}
(七) choose标签
1. choose标签简介
choose标签作用条件判断来拼接指定的条件,它和if不太相同,choose似类于java中的switch语句用法,直要有条件成立,其它判断将得不到执行,如果所有条件都不成立则执行otherwise标签中的内容。
格式:
<choose>
<when test=条件1>
执行的代码;
</when>
<when test=条件2>
执行的代码;
</when>
......
<otherwise>
? 执行的代码;
</when>
</otherwise>
</choose>
注意:直要有条件成立,其它判断将得不到执行
2. choose标签使用
1) 编写接口方法getInfoByUser
/**
? ? * 查询符合条件的所有user对象
? ? * @param user
? ? * @return
? ? */
? ?List<User> getUserDy02(Map map);
2) 使用choose标签进行sql处理
<!--choose:只要一个判断条件成立,其他判断不会执行-->
<select id="getUserDy02" parameterType="map" resultType="user">
? ? select * from user
? ? <where>
? ? ? ? <choose>
? ? ? ? ? ? <when test="uname!=null and uname!=''">
? ? ? ? ? ? ? ? uname like '%${uname}%'
? ? ? ? ? ? </when>
? ? ? ? ? ? <when test="sex!=null and sex!=''">
? ? ? ? ? ? ? ? and sex=#{sex}
? ? ? ? ? ? </when>
? ? ? ? ? ? <otherwise>
? ? ? ? ? ? ? ? 1=1
? ? ? ? ? ? </otherwise>
? ? ? ? </choose>
? ? </where>
</select>
3.测试接口方法getInfoByUser
@Test
public void demo04(){
? ? SqlSession sqlSession = MybatisUtils.getSqlSession();
? ? UserMapper mapper = sqlSession.getMapper(UserMapper.class);
? ? Map map=new HashMap<String,Object>();
? ? //map.put("uname","赵");
? ? //map.put("sex","男");
?
? ? List<User> userList = mapper.getUserDy02(map);
? ? System.out.println(userList.size());
? ? sqlSession.close();
}
?
(八) foreach标签
1. foreach标签简介
foreach标签表示循环,对sql中有重复的部分可以使用此循环来动态拼接sql语句。可以实现批量添加、批量删除、批量更新操作。foreach标签中有很多的属性,请参考下面的Foreach标签属性表。
Foreach标签属性表
| 属性名称 | 含义 |
|---|
| collection | 指定你要使用的集合类型 | | item | 集合中每个元素。 | | open | 在起始时,需要附加字符串,只附加一次。 | | close | 在结束时,需要附加字符,只附加一次。 | | separator | 在每个循环结时需要附加的字符串。 | | index | 每个循环的索引值。 |
2. foreach标签使用
1) 在接口中创建 addBatchUser、updateBatchUser、deleteBatchUser
/**
? ? * 批量添加
? ? * @param userList
? ? */
? ?int saveMulti(List<User> userList);
?
? ?/**
? ? * 批量更新
? ? * @param userList
? ? */
? ?int delMulti(List<Integer> ids);
?
? /**
? ? * 批量删除
? ? * @param ids
? ? */
? ?int updateMulti(List<User> ulist);
2) 使用forcach标签进行sql处理
<!--批量删除 1,4,6-->
<delete id="delMulti" parameterType="list">
? delete from user where uid in
? ? <foreach collection="list" item="userid" separator="," open="(" close=")">
? ? ? #{userid}
? ? </foreach>
</delete>
?
<!--批量添加-->
<insert id="saveMulti" parameterType="list">
? insert into user values
? ? <foreach collection="list" item="user" separator=",">
? ? ? ? (null,#{user.uname},#{user.sex},#{user.password},#{user.birthday})
? ? </foreach>
</insert>
?
<!--批量更新-->
<update id="updateMulti" parameterType="list">
? ?<foreach collection="list" item="user" separator=";">
? ? ? update user set uname=#{user.uname},sex=#{user.sex} where uid=#{user.uid}
? ?</foreach>
</update>
3) 测试
//批量删除
@Test
public void demo05(){
? ? SqlSession sqlSession = MybatisUtils.getSqlSession();
? ? UserMapper mapper = sqlSession.getMapper(UserMapper.class);
?
? ? List<Integer> ids=new ArrayList<Integer>();
? ? ids.add(1);
? ? ids.add(4);
? ? ids.add(6);
? ? int i = mapper.delMulti(ids);
? ? System.out.println(i);
? ? sqlSession.close();
}
?
//批量添加
@Test
public void demo06(){
? ? SqlSession sqlSession = MybatisUtils.getSqlSession();
? ? UserMapper mapper = sqlSession.getMapper(UserMapper.class);
?
? ? List<User> ulist=new ArrayList<User>();
? ? ulist.add(new User("张","女","aaaa",new Date()));
? ? ulist.add(new User("张plus","女","aaaa",new Date()));
? ? ulist.add(new User("张++","女","aaaa",new Date()));
? ? int i = mapper.saveMulti(ulist);
? ? System.out.println(i);
? ? sqlSession.close();
}
?
//批量更新
@Test
public void demo08(){
? ? SqlSession sqlSession = MybatisUtils.getSqlSession();
? ? UserMapper mapper = sqlSession.getMapper(UserMapper.class);
?
? ? List<User> ulist=new ArrayList<User>();
? ? ulist.add(new User(2,"张d","女","aaaa",new Date()));
? ? ulist.add(new User(3,"张plus","女","aaaa",new Date()));
? ? ulist.add(new User(5,"张++","女","aaaa",new Date()));
? ? int i = mapper.updateMulti(ulist);
? ? System.out.println(i);
? ? sqlSession.close();
}
?
注意:mysql本身不支持批量更新,如果需要批量更新时在url中附加allowMultiQueries=true
<property name="url" value="jdbc:mysql:///mybatis002?allowMultiQueries=true"/>
##
|