目录
一、动态sql介绍
一个查询的方法的sql语句不一定是固定的,比如电商网站的查询商品,用户使用不同条件查询,sql语句就会添加不同的查询条件。此时就需要用到动态sql了。
二、if
<if>标签内的sql片段在满足条件后才会添加,用法为<if test="">如下:根据不同条件查询用户
(1)持久层接口方法
//动态sql public interface UserMapper1 { List<User> findByif(User user); }
(2)映射文件
<?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="com.gq.mapper.UserMapper1"> <select id="findByif" parameterType="com.gq.pojo.User" resultType="com.gq.pojo.User"> select *from user where 1=1 <if test="username!=null and username.length()!=0"> and username like #{username} </if> <if test="sex!=null and sex.length()!=0"> and sex = #{sex} </if> <if test="address!=null and address.length()!=0"> and address = #{address} </if> </select> </mapper> <!---->
这里为什么要有where 1=1呢,重点是后面一直用and拼接。
对于该映射文件我的理解如下:
从user表中查找有符号if标签中的条件的,有一个就查一个都可以。
(3)测试方法
@Test public void sqlifTest() throws Exception{ InputStream is=Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactoryBuilder sqlSessionFactoryBuilder=new SqlSessionFactoryBuilder(); SqlSessionFactory sqlSessionFactory=sqlSessionFactoryBuilder.build(is); SqlSession session=sqlSessionFactory.openSession(); UserMapper1 userMapper1=session.getMapper(UserMapper1.class); User user=new User(); user.setUsername("%尚学堂%"); List<User> userList=userMapper1.findByif(user); userList.forEach(System.out::println); session.commit(); session.close(); is.close(); }
三、where
<where>可以代替sql中的where 1=1 和第一个and,更符合程序员的开发,所以我们可以将(2)中的映射文件修改成如下:
<?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="com.gq.mapper.UserMapper1"> <select id="findByif" parameterType="com.gq.pojo.User" resultType="com.gq.pojo.User"> select *from user <where> <if test="username!=null and username.length()!=0"> username like #{username} </if> <if test="sex!=null and sex.length()!=0"> and sex =#{sex} </if> <if test="address!=null and address.length()!=0"> and address=#{address} </if> </where> </select> </mapper> <!---->
四、set
(1)持久层接口方法
public interface UserMapper1 { //更新用户 void updatesql(User user); }
(2)映射文件
<update id="updatesql" parameterType="com.gq.pojo.User"> update user <set> <if test="username!=null and username.length()!=0"> username=#{username}, </if> <if test="address!=null and address.length()!=0"> address=#{address}, </if> <if test="sex!=null and sex.length()!=0"> sex=#{sex} </if> <where> id=#{id} </where> </set> </update>
(3)测试方法
@Test public void sqlUpdateTest() throws Exception{ InputStream is=Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactoryBuilder sqlSessionFactoryBuilder=new SqlSessionFactoryBuilder(); SqlSessionFactory sqlSessionFactory=sqlSessionFactoryBuilder.build(is); SqlSession session=sqlSessionFactory.openSession(); UserMapper1 userMapper1=session.getMapper(UserMapper1.class); User user=new User(8,"玉玉","男","安徽"); userMapper1.updatesql(user); session.commit(); session.close(); is.close(); }
五、choose和otherwise
<select id="findchoose" parameterType="com.gq.pojo.User" resultType="com.gq.pojo.User"> select *from user <where> <choose> <when test="username.length() < 5"> username like #{username} </when> <when test="username.length() < 10"> username = #{username} </when> <otherwise> id=1 </otherwise> </choose> </where> </select>
其实这些标签就相当于swithch...case,上面代码的含义是:
用户名长度<5时使用模糊查询,用户名大于等于5并且小于10时使用精确查询,否则就查找id等于1的用户
六、foreach
foreach类似于Java中的for循环,可以遍历数组或者集合,<foreach>有如下属性:
(1)collection:遍历的对象类型
(2)open:开始的sql语句
(3)close:结束的sql语句
(4)separator:遍历每项间的分隔符
(5)item:表示本次遍历获取遍历的元素,遍历List,Set,数组时表示每项元素,遍历map时表示键值对的值。
(6)index:遍历List,数组时表示遍历的索引,遍历map时表示键值对的键
(1)遍历数组
(1)持久层接口方法
//动态sql public interface UserMapper1 { //批量删除用户 void deleteArray(int[] ids); }
(2)映射文件
<delete id="deleteArray" parameterType="int"> delete from user <where> <foreach collection="array" open="id in (" close=")" separator="," item="id"> #{id} </foreach> </where> </delete>
我的理解如下:
正常的sql语句是 delte from user where id in(1,2,3)。
而我们想要批量删除,那我们需要遍历他的id,也就是说id是被遍历的。
collection遍历的对象类型是数组,则为array
open表示开始的sql语句,我们是从where后面开始的,也就是id in (。为什么到这里呢?因为在后面就是具体被遍历的值了,那就是后面的item了,在后面就是)结尾,但很明显)是close。
seperator遍历每项间的分隔符,在id in (1,2,3)中,1,2,3,他们是以逗号分隔的,所以值就是“,”。
item表示遍历获取的元素。
在foreach中将自己遍历到的值补充好,使其成为完整的sql语句。
(3)测试方法
@Test public void sqlfordeleteTest() throws Exception{ InputStream is=Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactoryBuilder sqlSessionFactoryBuilder=new SqlSessionFactoryBuilder(); SqlSessionFactory sqlSessionFactory=sqlSessionFactoryBuilder.build(is); SqlSession session=sqlSessionFactory.openSession(); UserMapper1 userMapper1=session.getMapper(UserMapper1.class); int[] arr={7,8,9}; userMapper1.deleteArray(arr); session.commit(); session.close(); is.close(); }
(2)遍历Collection
因为<foreach>遍历List和Set的方法是一样的,所以我就列举遍历List的用法了。
(1)持久层接口方法
//动态sql public interface UserMapper1 { //批量添加用户 void addListUser(List<User> users); }
(2)映射文件
<insert id="addListUser" parameterType="com.gq.pojo.User"> insert into user(username,sex,address) values <foreach collection="list" separator="," item="users"> (#{users.username},#{users.sex},#{users.address}) </foreach> </insert>
这里我的理解是这样的:
原来的正常sql语句应该是insert into user(username,sex,address) values("李四","男","天津"),("王五","女","重庆"),("赵六","男","沈阳");
collection表示遍历对象类型,这里是list
这里我们循环的是每次插入的那个值,所以应该是从values后面开始循环,并且每次他都自己要有(),中间以逗号分隔,很明显不要使用open和close
(3)测试方法
(3)遍历Map
这里Map中的键值对存储的是查找对象的具体属性,键表示的属性名,值表示的是属性值。
比如说 select *from user where username="张三";
这里的键表示的是如username,sex,address等等
值就是他们的具体值了。
(1)持久层接口方法
//动态sql public interface UserMapper1 { List<User> selectMap(@Param("quMap")Map<String,Object> maps); }
这里用@Param给参数取名字主要是为了后面映射文件中的<Map>遍历中的collection,不同于List和set他们,遍历Map他的collection值并不是map,而是你要给参数取名字,并且它的collection值就等于他
(2)映射文件
<select id="selectMap" parameterType="map" resultType="com.gq.pojo.User"> select *from user <where> <foreach collection="quMap" separator="and" index="key" item="val"> ${key}=#{val} </foreach> </where> </select>
(3)测试方法
@Test public void sqlforMapTest() throws Exception{ InputStream is=Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactoryBuilder sqlSessionFactoryBuilder=new SqlSessionFactoryBuilder(); SqlSessionFactory sqlSessionFactory=sqlSessionFactoryBuilder.build(is); SqlSession session=sqlSessionFactory.openSession(); UserMapper1 userMapper1=session.getMapper(UserMapper1.class); Map<String,Object> map=new HashMap<>(); map.put("address","北京"); List<User> userList=userMapper1.selectMap(map); userList.forEach(System.out::println); session.commit(); session.close(); is.close(); }