文章目錄:
1.什么是動態SQL?
2.MyBatis中的動態SQL
2.1 動態SQL——if標簽
2.1.1 語法格式
2.1.2 應用舉例
2.2 動態SQL——where標簽
2.2.1 語法格式
2.2.2 應用舉例
2.3 動態SQL——foreach標簽
2.3.1 語法格式
2.3.2 應用舉例1(簡單型別)
2.3.2 應用舉例2(物件型別)
2.4 動態SQL——sql標簽
2.4.1 語法格式
2.4.2 應用舉例
1.什么是動態SQL?
動態 SQL,通過 MyBatis 提供的各種標簽對條件作出判斷以實作動態拼接SQL 陳述句,這里的條件判斷使用的運算式為 OGNL 運算式,常用的動態 SQL標簽有<if>、<where>、<foreach>、<sql>等,
MyBatis 的動態 SQL 陳述句,與 JSTL 中的陳述句非常相似,
動態 SQL,主要用于解決查詢條件不確定的情況:在程式運行期間,根據用戶提交的查詢條件進行查詢,提交的查詢條件不同,執行的 SQL 陳述句不同,若將每種可能的情況均逐一列出,對所有條件進行排列組合,將會出現大量的SQL 陳述句,此時,可使用動態 SQL 來解決這樣的問題,
使用動態SQL時,dao介面中方法的形參要使用Java物件,
2.MyBatis中的動態SQL
2.1 動態SQL——if標簽
2.1.1 語法格式
<if test="boolean判斷結果"> <!--要么為true、要么為false-->
sql陳述句的部分
</if>
<!-- 對于該標簽的執行,當 test 的值為 true 時,會將其包含的 SQL 片段斷拼接到其所在的 SQL 陳述句中, -->
2.1.2 應用舉例
package com.bjpowernode.dao;
import com.bjpowernode.entity.Student;
import java.util.List;
/**
*
*/
public interface StudentDao {
//if
List<Student> selectIf(Student student);
}
<!-- if
test: 使用物件的屬性值作為條件
-->
<select id="selectIf" resultType="com.bjpowernode.entity.Student">
select *
from student
where id=-1
<if test="name!=null and name!=''">
or name=#{name}
</if>
<if test="age>0">
or age=#{age}
</if>
</select>
<!--
<if/>標簽的中存在一個比較麻煩的地方:需要在 where 后手工添加 id=-1的子句,
因為,若 where 后的所有<if/>條件均為 false,而 where 后若又沒有 id=-1 子句,則 SQL 中就會只剩下一個空的 where,SQL 出錯,
所以,在where 后,需要添加子句 id=-1,以防止這種情況的發生,但當資料量很大時,會嚴重影響查詢效率,
-->
@Test
public void testSelectIf() {
SqlSession session = MyBatisUtil.getSqlSession();
StudentDao studentDao=session.getMapper(StudentDao.class);
Student student=new Student();
student.setName("張起靈");
student.setAge(20);
List<Student> students=studentDao.selectIf(student);
students.forEach( stu -> System.out.println("stu === " + stu) );
session.close();
}
根據上面三個代碼塊,將其中的內容轉為等價的 sql 陳述句如下:👇👇👇
select *
from student
where id=-1 or name="張起靈" or age=20

2.2 動態SQL——where標簽
2.2.1 語法格式
<where>
其他動態sql
</where>
2.2.2 應用舉例
package com.bjpowernode.dao;
import com.bjpowernode.entity.Student;
import java.util.List;
/**
*
*/
public interface StudentDao {
//where
List<Student> selectWhere(Student student);
}
<!-- where -->
<select id="selectWhere" resultType="com.bjpowernode.entity.Student">
select *
from student
<where>
<if test="name!=null and name!=''">
or name=#{name}
</if>
<if test="age>0">
or age=#{age}
</if>
</where>
</select>
<!--
使用<where/>標簽,在有查詢條件時,可以自動添加上 where 子句;沒有查詢條件時,不會添加 where 子句,
需要注意的是,第一個<if/>標簽中的SQL 片斷,可以不包含 and,不過,寫上 and 也不錯,where標簽會將離它最近的 and 或者 or 刪掉,
但其它<if/>中 SQL 片斷的 and,必須要求寫上,否則 SQL 陳述句將拼接出錯
-->
@Test
public void testSelectWhere() {
SqlSession session = MyBatisUtil.getSqlSession();
StudentDao studentDao=session.getMapper(StudentDao.class);
Student student=new Student();
student.setName("張起靈");
student.setAge(20);
List<Student> students=studentDao.selectWhere(student);
students.forEach( stu -> System.out.println("stu === " + stu) );
session.close();
}
根據上面三個代碼塊,將其中的內容轉為等價的 sql 陳述句如下:👇👇👇
select *
from student
where id=-1 or name="張起靈" or age=20

2.3 動態SQL——foreach標簽
2.3.1 語法格式
<foreach collection="集合型別" open="開始的字符" close="結束的字符" item="集合中的成員" separator="集合成員之間的分隔符">
#{item的值}
</foreach>
<!--
如果dao介面中方法的形參是陣列,則collection="array"
如果dao介面中方法的形參是List,則collection="list"
#item的值}:獲取集合成員的值
-->
2.3.2 應用舉例1(簡單型別)
package com.bjpowernode.dao;
import com.bjpowernode.entity.Student;
import java.util.List;
/**
*
*/
public interface StudentDao {
//for-each 1
List<Student> selectForeachOne(List<Integer> idlist);
}
<!-- foreach第一種方式,回圈簡單型別的List: List<Integer> -->
<select id="selectForeachOne" resultType="com.bjpowernode.entity.Student">
select *
from student
<if test="list!=null and list.size>0">
where id in
<foreach collection="list" open="(" close=")" separator="," item="stuid">
#{stuid}
</foreach>
</if>
</select>
@Test
public void testSelectForeachOne() {
SqlSession session = MyBatisUtil.getSqlSession();
StudentDao studentDao=session.getMapper(StudentDao.class);
List<Integer> idlist=new ArrayList<>();
idlist.add(1001);
idlist.add(1002);
idlist.add(1003);
List<Student> students=studentDao.selectForeachOne(idlist);
students.forEach( stu -> System.out.println("stu === " + stu));
session.close();
}
根據上面三個代碼塊,將其中的內容轉為等價的 sql 陳述句如下:👇👇👇
select *
from student
where id in (1001,1002,1003)

2.3.2 應用舉例2(物件型別)
package com.bjpowernode.dao;
import com.bjpowernode.entity.Student;
import java.util.List;
/**
*
*/
public interface StudentDao {
//for-each 2
List<Student> selectForeachTwo(List<Student> studentList);
}
<!-- foreach第二種方式,回圈物件型別的List: List<Student> -->
<select id="selectForeachTwo" resultType="com.bjpowernode.entity.Student">
select *
from student
<if test="list!=null and list.size>0">
where id in
<foreach collection="list" open="(" close=")" separator="," item="stu">
#{stu.id}
</foreach>
</if>
</select>
@Test
public void testSelectForeachTwo() {
SqlSession session = MyBatisUtil.getSqlSession();
StudentDao studentDao=session.getMapper(StudentDao.class);
List<Student> list=new ArrayList<>();
Student s1=new Student();
s1.setId(1001);
Student s2=new Student();
s2.setId(1002);
Student s3=new Student();
s3.setId(1003);
list.add(s1);
list.add(s2);
list.add(s3);
List<Student> students=studentDao.selectForeachTwo(list);
students.forEach( stu-> System.out.println("stu === " + stu));
session.close();
}
根據上面三個代碼塊,將其中的內容轉為等價的 sql 陳述句如下:👇👇👇
select *
from student
where id in (1001,1002,1003)

2.4 動態SQL——sql標簽
2.4.1 語法格式
<sql id="...">
sql陳述句
</sql>
<include refid="sql標簽的id屬性值"></include>
<!--
<sql/>標簽用于定義 SQL 片斷,以便其它 SQL 標簽復用,
而其它標簽使用該 SQL 片斷,需要使用<include/>子標簽,
該<sql/>標簽可以定義 SQL 陳述句中的任何部分,所以<include/>子標簽可以放在動態 SQL 的任何位置,
-->
2.4.2 應用舉例
package com.bjpowernode.dao;
import com.bjpowernode.entity.Student;
import java.util.List;
/**
*
*/
public interface StudentDao {
//代碼片段
List<Student> selectSql(List<Student> studentList);
}
<!-- 定義代碼片段 -->
<sql id="selectStudent">
select id,name,age from student
</sql>
<sql id="studentFieldList">
where id in
</sql>
<select id="selectSql" resultType="com.bjpowernode.entity.Student">
<include refid="selectStudent"></include>
<if test="list!=null and list.size>0">
<include refid="studentFieldList"></include>
<foreach collection="list" open="(" close=")" separator="," item="student">
#{student.id}
</foreach>
</if>
</select>
@Test
public void testSelectSql() {
SqlSession session = MyBatisUtil.getSqlSession();
StudentDao studentDao=session.getMapper(StudentDao.class);
List<Student> list=new ArrayList<>();
Student s1=new Student();
s1.setId(1001);
Student s2=new Student();
s2.setId(1002);
Student s3=new Student();
s3.setId(1003);
list.add(s1);
list.add(s2);
list.add(s3);
List<Student> students=studentDao.selectSql(list);
students.forEach( stu-> System.out.println("stu === " + stu));
session.close();
}
根據上面三個代碼塊,將其中的內容轉為等價的 sql 陳述句如下:👇👇👇
select id,name,age
from student
where id in (1001,1002,1003)

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/267072.html
標籤:java
上一篇:@Import注解:匯入配置類的四種方式&原始碼決議
下一篇:ClassCastException:: cannot be cast to class java.lang.Comparable的處理方法
