MyBatis的动态sql的学习
学习要点
动态sql的介绍
if
choose(when,otherwise)
where
set
foreach
bind
主要用的代码,和测试用例
动态sql的介绍
MyBatis采用基于OGCL的表达式来完成动态sql,ogcl的表达式可以被用来任意的sql映射的语句上。
常用的动态元素有:
if
choose(when,otherwise)
where
set
foreach
bind
if
代码示例:
<select id="selectUserByLike" resultType="com.pkk.entity.User" parameterType="int" timeout="20">
select * from USER
<if test="id!=null">
where id=#{id}
</if>
</select>
代码说明:
if标签中,有test元素,是一个判断的区域,在里面可以进行各种判断,上面是判断id是否不为空,当不为空的时候也就是需要添加where id=#{}数据,当为空则查询所有的用户数据。
choose(when,otherwise)
代码示例
<!--choose(when、otherwise)代码示例相当于java的swith-->
<select id="selectUserByChoose" resultType="com.pkk.entity.User" parameterType="int" timeout="20">
select * from USER where 1=1
<choose>
<when test="username!=null">
and username=#{username}
</when>
<when test="id!=null">
and id=#{id}
</when>
<otherwise>
and deptid=#{deptid}
</otherwise>
</choose>
</select>
代码说明:
相当于java的switch
上面的代码意思就是说,当username不为空的时候,就以传过来的username为条件查询,当username为空id不为空的时候,就以传过来的id作为条件查询,最后,username和id都为空的时候,取其反,剩下的都是走deptid为条件。
where
代码示例
<!--where的使用,他会判断何时添加where语句-->
<select id="selectUserByWhere" resultType="com.pkk.entity.User" parameterType="int" timeout="20">
select * from USER
<where>
<if test="id!=null">
and id=#{id}
</if>
<if test="username!=null">
and username=#{username}
</if>
</where>
</select>
代码说明:
如上面代码示例,只有在if条件有一个满足的时候,where标签就会自动给其添加where的sql语句
set
代码示例:
<!--set的使用,主要用于更新数据的时候的条件筛选,会自动添加set的sql语句-->
<update id="updateUserBySet" timeout="20" parameterType="int">
UPDATE USER
<set>
<if test="username!=null">username=#{username},</if>
<if test="password!=null">password=#{password}</if>
</set>
where id =#{id}
</update>
代码说明
用法同where,在更新的时候,如有一个符合条件的可产生set语句
foreach
代码示例
<!--foreach的使用,一般用于构建in条件查询时候使用-->
<select id="selectUserByForeach" resultType="com.pkk.entity.User">
select * from user where id in
<foreach collection="list" index="index" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
</select>
代码讲解
主要用于构建in条件查询的时候使用,open是在数据库的时候,插入的数据的前缀,separator是在构建数据库的时候结尾的符号,separator是每个list元素之后要追加的数据符号
如select * from user where id in ( ? , ? )
其中“(”就是open定义的,“)”就是close定义的,“,”就是separator定义的。
bind
代码示例
<!--bind的使用,可以从ognl表达式中创建一个变变量,并将其绑定到上下文中-->
<select id="selectUserByBind" resultType="com.pkk.entity.User">
<bind name="likeusername" value="'%'+username+'%'"/>
SELECT * FROM USER where username LIKE #{likeusername}
</select>
代码说明
主要是在ognl表达示中产生一个类似一个变量,然后在后面进行引用。
主要用的代码,和测试用例
MyBatris配置文件(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>
<!--指定MyBatis所用的日志具体实现-->
<settings>
<setting name="logImpl" value="LOG4J"/>
<!--lazyLoadingEnabled 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载。默认:true
aggressiveLazyLoading 当启用时,有延迟加载属性的对象在被调用时将会完全加载任意属性。否则,每种属性将会按需要加载。默认:true-->
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
<!--起别名,别名的作用就是用简单明代替全限定类名-->
<typeAliases>
<!--
通过package, 可以直接指定package的名字, mybatis会自动扫描你指定包下面的javabean,
并且默认设置一个别名,默认的名字为: javabean 的首字母小写的非限定类名来作为它的别名。
也可在javabean 加上注解@Alias 来自定义别名, 例如: @Alias(user)
<package name="com.pkk.entity"/>
-->
<typeAlias alias="user" type="com.pkk.entity.User"/>
</typeAliases>
<!--环境配置,即连接的数据库-->
<environments default="mysql">
<environment id="mysql">
<!--使用jdbc的事务提交与回滚设置-->
<transactionManager type="JDBC"/>
<!--配置数据源,POOLED是JDBC连接对象的数据源连接池的实现-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="username" value="root"/>
<property name="password" value="admin"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis"/>
</dataSource>
</environment>
</environments>
<!--mapper告诉了MyBatis去哪里找持久化的映射文件-->
<mappers>
<!--动态sql-->
<mapper resource="com.pkk.mapper/UserMapper.xml"></mapper>
</mappers>
</configuration>
动态sql的配置文件(UserMapper.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.pkk.mapper.UserMapper">
<!--if代码实例-->
<select id="selectUserByIf" resultType="com.pkk.entity.User" parameterType="int" timeout="20">
select * from USER
<if test="id!=null">
where id=#{id}
</if>
</select>
<!--choose(when、otherwise)代码示例相当于java的swith-->
<select id="selectUserByChoose" resultType="com.pkk.entity.User" parameterType="int" timeout="20">
select * from USER where 1=1
<choose>
<when test="username!=null">
and username=#{username}
</when>
<when test="id!=null">
and id=#{id}
</when>
<otherwise>
and deptid=#{deptid}
</otherwise>
</choose>
</select>
<!--where的使用,他会判断何时添加where语句,何时去掉不必要的and和or符号-->
<select id="selectUserByWhere" resultType="com.pkk.entity.User" parameterType="int" timeout="20">
select * from USER
<where>
<if test="id!=null">
and id=#{id}
</if>
<if test="username!=null">
and username=#{username}
</if>
</where>
</select>
<!--set的使用,主要用于更新数据的时候的条件筛选,会自动添加set的sql语句-->
<update id="updateUserBySet" timeout="20" parameterType="int">
UPDATE USER
<set>
<if test="username!=null">username=#{username},</if>
<if test="password!=null">password=#{password}</if>
</set>
where id =#{id}
</update>
<!--foreach的使用,一般用于构建in条件查询时候使用-->
<select id="selectUserByForeach" resultType="com.pkk.entity.User">
select * from user where id in
<foreach collection="list" index="index" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
</select>
<!--bind的使用,可以从ognl表达式中创建一个变变量,并将其绑定到上下文中-->
<select id="selectUserByBind" resultType="com.pkk.entity.User">
<bind name="likeusername" value="'%'+username+'%'"/>
SELECT * FROM USER where username LIKE #{likeusername}
</select>
</mapper>
java类的接口(UserMapper.java)
package com.pkk.mapper;
import com.pkk.entity.User;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* Created by peikunkun on 2018/1/27 0027.
*/
public interface UserMapper<T> {
public List<T> selectUserByIf(HashMap<String, Object> param);
public List<T> selectUserByChoose(HashMap<String, Object> param);
public List<T> selectUserByWhere(HashMap<String, Object> param);
public int updateUserBySet(HashMap<String, Object> param);
public List<T> selectUserByForeach(ArrayList<Integer> param);
public List<T> selectUserByBind(User param);
}
测试类(DynamicSQLTest1.java)
package com.pkk.test.aynamicsql;
import com.pkk.entity.User;
import com.pkk.mapper.UserMapper;
import com.pkk.test.TestUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* Created by peikunkun on 2018/1/27 0027.
* 《动态sql》
*/
public class DynamicSQLTest1 {
private SqlSession session = null;
public static void main(String[] args) {
System.out.println("欢迎使用MyBatis的删除操作");
}
@Before
public void before() {
session = TestUtil.getSqlSession();
}
@Test
public void DynamicSQLTest1_11() {
System.out.println("欢迎使用单元测试方法【DynamicSQLTest1_11()】");
System.out.println("此方法测试描述:【if的使用】");
UserMapper userMapper = session.getMapper(UserMapper.class);
HashMap<String, Object> param = new HashMap<String, Object>();
// param.put("id", "1");
List<User> users = userMapper.selectUserByIf(param);
users.forEach(user -> System.out.println(user));
}
@Test
public void DynamicSQLTest1_43() {
System.out.println("欢迎使用单元测试方法【DynamicSQLTest1_43()】");
System.out.println("此方法测试描述:【choose的使用(包括when,otherwise)】");
UserMapper userMapper = session.getMapper(UserMapper.class);
HashMap<String, Object> param = new HashMap<String, Object>();
// param.put("id", "1");
// param.put("username", "root1918178885");
param.put("deptid", "1");
List<User> users = userMapper.selectUserByChoose(param);
users.forEach(user -> System.out.println(user));
}
@Test
public void DynamicSQLTest1_57() {
System.out.println("欢迎使用单元测试方法【DynamicSQLTest1_57()】");
System.out.println("此方法测试描述:【Where的使用】");
UserMapper userMapper = session.getMapper(UserMapper.class);
HashMap<String, Object> param = new HashMap<String, Object>();
param.put("id", "1");
param.put("username", "root1918178885");
List<User> users = userMapper.selectUserByWhere(param);
users.forEach(user -> System.out.println(user));
}
@Test
public void DynamicSQLTest1_69() {
System.out.println("欢迎使用单元测试方法【DynamicSQLTest1_69()】");
System.out.println("此方法测试描述:【Set的使用】");
UserMapper userMapper = session.getMapper(UserMapper.class);
HashMap<String, Object> param = new HashMap<String, Object>();
param.put("id", "1");
param.put("username", "更新用户名" + Math.random());
param.put("password", "更新密码" + Math.random());
int result = userMapper.updateUserBySet(param);
System.out.println("更新的结果:" + result);
}
@Test
public void DynamicSQLTest1_84() {
System.out.println("欢迎使用单元测试方法【DynamicSQLTest1_84()】");
System.out.println("此方法测试描述:【Foreach的使用】");
UserMapper userMapper = session.getMapper(UserMapper.class);
ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(1);
arrayList.add(5);
List<User> users = userMapper.selectUserByForeach(arrayList);
users.forEach(user -> System.out.println("用户信息:" + user));
}
@Test
public void DynamicSQLTest1_99() {
System.out.println("欢迎使用单元测试方法【DynamicSQLTest1_99()】");
System.out.println("此方法测试描述:【bind的使用】");
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = new User();
user.setUsername("root");
List<User> users = userMapper.selectUserByBind(user);
users.forEach(user1 -> System.out.println("用户信息:" + user1));
}
@After
public void end() {
TestUtil.commitAndCloseSession(session);
}
}
测试工具类TestUtil.java
package com.pkk.test;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;
/**
* Created by peikunkun on 2018/1/21 0021.
*/
public class TestUtil {
/**
* 获取连接
*
* @return
*/
public static SqlSession getSqlSession() {
/*获取当前mybatis配置文件*/
InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("mybatis-config.xml");
/*创建sqlSessionFactory对象*/
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
/*创建SQLSession对象操作持久层对象*/
SqlSession session = sqlSessionFactory.openSession();
return session;
}
/**
* 关闭连接和进行提交
*
* @return
*/
public static void commitAndCloseSession(SqlSession session) {
if (session != null) {
session.commit();
session.close();
}
}
}
user的实体类(User.java)
package com.pkk.entity;
import java.io.Serializable;
import java.util.List;
/**
* @author peikunkun
* @version V1.0
* @Title: MyBatisProject
* @Package com.pkk.entity
* @Description: <>
* @date 2017/12/31 19:31
*/
public class User implements Serializable {
private Integer id;
private String username;
private String password;
private String cardid;
/*用户与订单是一对多的关系,即一个用户可以有多个订单*/
private List<Order> orders;
private Dept dept;
private Card card;
public User() {
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
public User(Integer id, String username, String password) {
this.id = id;
this.username = username;
this.password = password;
}
public List<Order> getOrders() {
return orders;
}
public void setOrders(List<Order> orders) {
this.orders = orders;
}
public String getCardid() {
return cardid;
}
public Card getCard() {
return card;
}
public void setCard(Card card) {
this.card = card;
}
public void setCardid(String cardid) {
this.cardid = cardid;
}
public Dept getDept() {
return dept;
}
public void setDept(Dept dept) {
this.dept = dept;
}
public Integer getId() {
return id;
}
public void setId(Integer 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;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", cardid='" + cardid + '\'' +
", orders=" + orders +
", dept=" + dept +
", card=" + card +
'}';
}
}