MyBatis之动态SQL
Posted 一梦先知
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyBatis之动态SQL相关的知识,希望对你有一定的参考价值。
利用动态 SQL可以很方便地根据不同条件拼接 SQL 语句
我们先搭建MyBatis配置:
接口类
package com.jd.userinfo.dao; import java.util.List; import org.apache.ibatis.annotations.Param; import com.jd.vo.UserInfo; public interface IUserInfoDao { List<UserInfo> select(@Param("userName")String userName,@Param("age")Integer age); boolean delete(List<Integer> list); boolean update(UserInfo userInfo); }
mybatis_config.xml
<?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> <properties resource="jdbc.properties"></properties> <settings> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> <typeAliases> <typeAlias type="com.jd.vo.UserInfo" alias="UserInfo"/> </typeAliases> <environments default="dev"> <environment id="dev"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.userName}"/> <property name="password" value="${jdbc.password}"/> </dataSource> </environment> </environments> <mappers> <mapper resource="./sql/user_info.xml"/> </mappers> </configuration>
Userinfo.java
package com.jd.vo; public class UserInfo { private int id; private String userName; private String password; private String realName; private String age; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getRealName() { return realName; } public void setRealName(String realName) { this.realName = realName; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } }
user_info.xml
<?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.jd.userinfo.dao.IUserInfoDao"> <resultMap type="com.jd.vo.UserInfo" id="userInfo"> <id property="id" column="id"/> <result property="userName" column="user_name"/> <result property="password" column="password"/> <result property="age" column="age"/> <result property="realName" column="real_name"/> </resultMap>
<!-- ——————————————————————————此处添加待测试动态sql—————————————————————————— -->
</mapper>
测试类
public class Test { public static void main(String[] args) { try { InputStream inputStream = Resources.getResourceAsStream("mybatis_config.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(true);//为true自动提交,默认false开启事务需要手动commit IUserInfoDao userInfoDao = sqlSession.getMapper(IUserInfoDao.class);
//——————————————————————————————————此处添加待测试代码—————————————————————————————————————————————————— sqlSession.close(); } catch (IOException e) { e.printStackTrace(); } } }
<if>:常用于根据条件拼接where 子句
我们在user_info.xml中添加如下代码并测试:可见当满足标签中test属性的条件时,将会拼接if中的语句,否则不会
<select id="select" resultMap="userInfo"> select id,user_name,password,real_name,age from user_info where 1=1 <if test="userName!=null"> and user_name like #{userName} </if> <if test="age!=null"> and age = #{age} </if> </select>
测试代码及测试结果:
List<UserInfo> list = userInfoDao.select("%zzj%", null); System.out.println(list.size());
<where>:元素只会在至少有一个子元素的条件返回 SQL 子句的情况下才去插入“WHERE”子句;而且,若语句的开头为“AND”或“OR”,where 元素也会将它们去除。
我们在user_info.xml中添加如下代码并测试:可见当后面所有语句均不存在时,where不会拼接在sql语句中
<select id="select" resultMap="userInfo"> select id,user_name,password,real_name,age from user_info <where> <if test="userName!=null"> and user_name like #{userName} </if> <if test="age!=null"> and age = #{age} </if> </where> </select>
测试代码及结果:
List<UserInfo> list = userInfoDao.select(null, null); System.out.println(list.size());
<choose>:元素类似 Java 中的 switch 语句
我们在user_info.xml中添加如下代码并测试:所有when标签中按顺序,只要有一个满足条件就会选择该sql语句拼接,其余的不拼接
<select id="select" resultMap="userInfo"> select id,user_name,password,real_name,age from user_info <where> <choose> <when test="userName!=null"> and user_name like #{userName} </when> <when test="age!=null"> and age = #{age} </when> </choose> </where> </select>
测试代码及结果:
List<UserInfo> list = userInfoDao.select("zzj", 12);
System.out.println(list.size());
<set>: 元素可以用于动态包含需要更新的列,而删掉无关的逗号
我们在user_info.xml中添加如下代码并测试:
<update id="update"> update user_info <set> <if test="realName!=null"> real_name=#{realName}, </if> <if test="password!=null"> password=#{password} </if> </set> where id=#{id} </update>
测试代码及结果:
UserInfo userInfo = new UserInfo(); userInfo.setId(1); userInfo.setRealName("Jerry"); System.out.println(userInfoDao.update(userInfo));
<foreach>:foreach元素用于对一个集合进行遍历,构建 IN 条件语句时常用该元素;foreach 元素允许指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量,也允许指定开头与结尾的字符串以及在迭代结果之间放置分隔符。
我们在user_info.xml中添加如下代码并测试实现批量删除:
<delete id="delete"> delete from user_info where id in <!-- 声明可以在元素体内使用的集合项(item)和索引(index)变量,指定开头与结尾的字符串以及在迭代结果之间放置分隔符。 --> <foreach item="id" collection="list" open="(" close=")" separator=","> #{id} </foreach> </delete>
测试代码及结果如下:
List<Integer> list = new ArrayList<Integer>(); list.add(2);
list.add(3); System.out.println(userInfoDao.delete(list));
以上是关于MyBatis之动态SQL的主要内容,如果未能解决你的问题,请参考以下文章