【Mybatis】(六)動態SQL
阿新 • • 發佈:2018-12-10
在【Mybatis】(一)第一個mybatis例項中已經建立了資料庫和基本的執行環境,接下來將介紹Mybatis動態SQL。
1、定義EmployeeMapperDynamicSQL介面
package com.lhk.mybatis.dao; import com.lhk.mybatis.bean.Employee; import org.apache.ibatis.annotations.Param; import java.util.List; /** * @author lhk * @create 2018-09-16 20:21 */ public interface EmployeeMapperDynamicSQL { // 查詢員工,要求攜帶了哪個欄位查詢欄位就帶上這個欄位的值,測試where public List<Employee> getEmpByConditionIf(Employee employee); // 查詢員工,測試Trim public List<Employee> getEmpByConditionTrim(Employee employee); // 查詢員工,測試Choose,When,otherwise public List<Employee> getEmpByConditionChoose(Employee employee); // 更新員工資訊 public void updateEmp(Employee employee); // 插入員工資訊 public void insertEmp(Employee employee); // 通過foreach在指定集合中查詢員工id public List<Employee> getEmpByConditionForeach(@Param("ids") List<Integer> id); // 通過foreach批量插入員工資訊 public void addEmp(@Param("emps") List<Employee> employee); }
2、定義EmployeeMapperDynamicSQL.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.lhk.mybatis.dao.EmployeeMapperDynamicSQL"> <!-- • if 判斷 • choose (when, otherwise) 分支選擇(帶了break的switch-case) 如果帶了id就用id查,如果帶了lastName就用lastName查;只會進入其中一個 • trim (where(封裝查詢條件), set(封裝修改條件)) 字串擷取 • foreach --> <resultMap id="Simple" type="com.lhk.mybatis.bean.Employee"> <result column="last_name" property="lastName"></result> </resultMap> <!--查詢員工,要求攜帶了哪個欄位查詢欄位就帶上這個欄位的值 getEmpByConditionIf --> <select id="getEmpByConditionIf" resultMap="Simple"> select * from tb1_employee -- where <where> <!-- 測試where: 1、當if條件不滿足,即where元素中沒有內容,在SQL語句中就不會出現where 2、當if條件滿足,where元素的內容是以and開頭,where會自動去掉開頭的and or,以保證where條件正確 3、where不能解決SQL語句後面多出的and or,要通過trim解決 test:判斷表示式,從引數中取值進行判斷--> <if test="id!=null"> id=#{id} </if> <if test="lastName!=null and lastName!=''"> and last_name like #{lastName} </if> <if test="email!=null and email.trim()!=''"> and email=#{email} </if> <if test="gender==0 and gender==1"> and gender=#{gender} </if> </where> </select> <!--通過Trim方式 getEmpByConditionTrim --> <select id="getEmpByConditionTrim" resultMap="Simple"> select * from tb1_employee -- where <!-- where,set標籤的功能都可以通過Trim來實現 解決SQL語句後面多出的and or,where標籤不能解決 <trim prefix="" 字首,當trim元素內包含內容時,會給內容增加prefix指定的字首 prefixOverrides="" 字首覆蓋,當trim元素內包含內容時,會把內容中匹配的字首字串去掉 suffix="" 字尾,當trim元素內包含內容時,會給內容增加suffix指定的字尾 suffixOverrides="" 字尾覆蓋,當trim元素內包含內容時,會把內容中匹配的字尾字串去掉 </trim> --> <!--自定義字串擷取規則--> <!--在SQL語句前面新增where,去除SQL語句中後面多餘的and --> <trim prefix="where" prefixOverrides="" suffix="" suffixOverrides="and"> <!-- test:判斷表示式,從引數中取值進行判斷--> <if test="id!=null"> id=#{id} and </if> <if test="lastName!=null and lastName!=''"> last_name like #{lastName} and </if> <if test="email!=null and email.trim()!=''"> email=#{email} and </if> <if test="gender==0 and gender==1"> gender=#{gender} </if> </trim> </select> <!--測試分支選擇 getEmpByConditionChoose --> <select id="getEmpByConditionChoose" resultMap="Simple"> select * from tb1_employee <where> <!-- 如果帶了id就用id查,如果帶了lastName就用lastName查;只會進入其中一個 --> <choose> <when test="id!=null"> id=#{id} </when> <when test="lastName!=null"> last_name like #{lastName} </when> <when test="email!=null"> email=#{email} </when> <otherwise> gender=0 </otherwise> </choose> </where> </select> <!-- 測試update updateEmp 只更新要更新的值。為null的值就不更新 set:1、如果該標籤包含的元素中有返回值,就插入一個set 2、如果set後面的字串是以逗號結尾,就刪除這個逗號 3、如果set元素中沒有內容,則仍然會出現SQL錯誤,所以id=#{id}仍有保留的必要 --> <update id="updateEmp"> update tb1_employee <set> <if test="lastName!=null"> last_name=#{lastName}, </if> <if test="email!=null"> email=#{email}, </if> <if test="gender!=null"> gender=#{gender} </if> id=#{id}, </set> where id=#{id} </update> <!--測試insert insertEmp 只插入要插入的值。為null的值就不插入。 在列的部分增加if條件,則values的部分也要增加相同的if條件, 必須保證上下相互對應,完全匹配 --> <insert id="insertEmp"> insert into tb1_employee( <if test="id!=null and id!=''"> id, </if> <if test="lastName!=null and lastName!=''"> last_name, </if> <if test="email!=null and email!=''"> email, </if> <if test="gender!=null and gender!=''"> gender </if> ) <trim suffixOverrides=","> values( <if test="id!=null and id!=''"> #{id}, </if> <if test="lastName!=null and lastName!=''"> #{lastName}, </if> <if test="email!=null and email!=''"> #{email}, </if> <if test="gender!=null and gender!=''"> #{gender} </if> ) </trim> </insert> <!--測試foreach getEmpByConditionForeach--> <!-- collection:指定要遍歷的集合, list型別的引數會特殊處理封裝在map中,map的key就叫list item:將當前遍歷出的元素賦值給指定的變數 separate:每個元素之間的分隔符 open:遍歷出所有的結果拼接一個開始字元 close:遍歷出所有的結果拼接一個結束字元 index:遍歷list的時候,index是list的索引,item是list的值 遍歷map的時候,index是map的key,item是map的值 --> <select id="getEmpByConditionForeach" resultMap="Simple"> select * from tb1_employee where id in <foreach collection="ids" item="item_id" separator="," open="(" close=")"> #{item_id} </foreach> </select> <!-- 批量儲存:addEmp--> <insert id="addEmp"> insert into tb1_employee(last_name,email,gender,d_id) values <foreach collection="emps" item="emp" separator=","> (#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id}) </foreach> </insert> </mapper>
3、定義MybatisDynamicSQLTest測試類
package com.lhk.mybatis.test;
import com.lhk.mybatis.bean.Department;
import com.lhk.mybatis.bean.Employee;
import com.lhk.mybatis.dao.EmployeeMapperDynamicSQL;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author lhk
* @create 2018-09-16 20:46
*/
public class MybatisDynamicSQLTest {
public SqlSessionFactory getSqlSessionFactory() throws IOException {
String resource = "conf/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
return new SqlSessionFactoryBuilder().build(inputStream);
}
/**
* 測試If
*/
@Test
public void testgetEmpByConditionIf() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
EmployeeMapperDynamicSQL mapper = sqlSession.getMapper(EmployeeMapperDynamicSQL.class);
Employee employee = new Employee(2,"%e%"," [email protected]","1");
List<Employee> list = mapper.getEmpByConditionIf(employee);
for (Employee emp : list) {
System.out.println(emp);
}
//查詢的時候如果某些條件沒有,SQL拼裝可能會出問題
//1、給where後面加上1=1,以後的條件都and xxx
//2、mybatis使用where標籤將所有的查詢條件包括在內
//mybatis就會將where標籤中的拼裝的SQL中多的and,or去掉。只會去掉第一個多出來的and,or
}finally {
sqlSession.close();
}
}
/**
* 測試Trim
*/
@Test
public void testGetEmpByConditionTrim() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
EmployeeMapperDynamicSQL mapper = sqlSession.getMapper(EmployeeMapperDynamicSQL.class);
Employee employee = new Employee(null, "%e%", "[email protected]", "1");
List<Employee> list = mapper.getEmpByConditionTrim(employee);
for (Employee emp : list) {
System.out.println(emp);
}
}finally {
sqlSession.close();
}
}
/**
* 測試Choose
*/
@Test
public void testGetEmpByConditionChoose() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
EmployeeMapperDynamicSQL mapper = sqlSession.getMapper(EmployeeMapperDynamicSQL.class);
Employee employee = new Employee(null, null, "[email protected]", "1");
List<Employee> list = mapper.getEmpByConditionChoose(employee);
for (Employee emp : list) {
System.out.println(emp);
}
}finally {
sqlSession.close();
}
}
/**
* 測試set
*/
@Test
public void testUpdateEmp() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
EmployeeMapperDynamicSQL mapper = sqlSession.getMapper(EmployeeMapperDynamicSQL.class);
Employee employee = new Employee(null, null, null, null);
mapper.updateEmp(employee);
sqlSession.commit(); // 提交
}finally {
sqlSession.close();
}
}
/**
* 測試insert
*/
@Test
public void testInsertEmp() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
EmployeeMapperDynamicSQL mapper = sqlSession.getMapper(EmployeeMapperDynamicSQL.class);
Employee employee = new Employee(null, "lll", null, "0");
mapper.insertEmp(employee);
sqlSession.commit(); // 提交
}finally {
sqlSession.close();
}
}
/**
* 測試foreach實現in集合
*/
@Test
public void testGetEmpByConditionForeach() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
EmployeeMapperDynamicSQL mapper = sqlSession.getMapper(EmployeeMapperDynamicSQL.class);
List<Employee> list = mapper.getEmpByConditionForeach(Arrays.asList(2,6));
for (Employee emp : list) {
System.out.println(emp);
}
}finally {
sqlSession.close();
}
}
/**
* 測試foreach實現批量插入
*/
@Test
public void testBatchSave() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
EmployeeMapperDynamicSQL mapper = sqlSession.getMapper(EmployeeMapperDynamicSQL.class);
List<Employee> emps = new ArrayList<>();
emps.add(new Employee(null,"Smith","[email protected]","1",new Department(1)));
emps.add(new Employee(null,"Tom","[email protected]","0",new Department(2)));
mapper.addEmp(emps);
sqlSession.commit(); //提交
}finally {
sqlSession.close();
}
}
}