日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

MyBatis(4)动态SQL

發布時間:2025/3/8 数据库 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MyBatis(4)动态SQL 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

MyBatis 的強大特性之一便是它的動態 SQL。如果你有使用 JDBC 或其它類似框架的經驗,你就能體會到根據不同條件拼接 SQL 語句的痛苦。例如拼接時要確保不能忘記添加必要的空格,還要注意去掉列表最后一個列名的逗號。利用動態 SQL 這一特性可以徹底擺脫這種痛苦。

? ? ?

雖然在以前使用動態 SQL 并非一件易事,但正是 MyBatis 提供了可以被用在任意 SQL 映射語句中的強大的動態 SQL 語言得以改進這種情形。

? ? ?

動態 SQL 元素和 JSTL 或基于類似 XML 的文本處理器相似。在 MyBatis 之前的版本中,有很多元素需要花時間了解。MyBatis 3 大大精簡了元素種類,現在只需學習原來一半的元素便可。MyBatis 采用功能強大的基于 OGNL 的表達式來淘汰其它大部分元素。

--->if --->choose(when,otherwise) --->trim(where,set) --->foreach 此文章及以后不帶結果的截圖,影響整體文章的布局美感!!! 其他的一些可以簡單看一下之前的博文! 首先來看看本次工程的目錄吧:

mybatis-config.xml:

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration><properties resource="db.properties" ></properties><environments default="development"><environment id="development"><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="DynamicSQL.xml"/></mappers> </configuration>

?Employee.java(getter&setter&toString)

public class Employee {private int id;private String name;private String gender;private String email;private Department dept; }

?現在基本的布局已經完成!!

?

1)if

A.在DynamicMapper.java接口中

//攜帶了哪個字段的查詢條件就攜帶這個字段的值public List<Employee> getEmpByIf(Employee emp);

?

在Dynamic'SQl.xml文件 <!-- if --><!-- 查詢員工,要求,攜帶了那個字段查詢條件就帶上那個字段的字段值 --><!-- public List<Employee> getEmpByIf(Employee emp); --><select id="getEmpByIf" resultType="com.MrChengs.bean.Employee">select * from testwhere<!-- test:判斷表達式(OGNL) --><!-- OGNL:apache官方文檔有明確的解釋說明 --><!-- 從參數中取值進行判斷不是數據庫中取值 --><!-- 特殊字符應該寫轉義字符 --><if test="id!=null">id=#{id}</if><if test="name!=null and name!=''">and name like #{name}</if><if test="email!=null and email.trim()!=''">and email like #{email}</if></select> 在這個文件的內容簡要的進行說明一下: and name like #{name} 這里的紅色的name是我們查詢的name值,不是數據庫中的name #{name}是把我們手動輸入的紅色name傳遞過去,進行數據庫的查詢 測試類: public SqlSessionFactory getSqlSessionFactory() throws IOException{String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource); return new SqlSessionFactoryBuilder().build(inputStream);}@Testpublic void test() throws IOException {SqlSessionFactory sessionFactory = getSqlSessionFactory();SqlSession session = sessionFactory.openSession();try{DynamicSQLMapper mapper = session.getMapper(DynamicSQLMapper.class);//傳入的紅色name值進行數據庫的查詢Employee emp = new Employee(5, "%Mr%", "boy", "%1287%");List<Employee> emps = mapper.getEmpByIf(emp);System.out.println(emps);}finally{session.close();}}

?查詢之后的顯示代碼

DEBUG 10-02 12:13:49,806 ==> Preparing: select * from test where id=? and name like ? and email like ? (BaseJdbcLogger.java:159) DEBUG 10-02 12:13:49,843 ==> Parameters: 5(Integer), %Mr%(String), %1287%(String) (BaseJdbcLogger.java:159) DEBUG 10-02 12:13:49,873 <== Total: 1 (BaseJdbcLogger.java:159) [Employee [id=5, name=MrChengs, gender=boy, email=1287xxxxxx@xx.com, dept=null]]

?

B.在查詢的時候,如果某些時候某些條件沒帶可能導致sql拼裝有問題 實例: <select id="getEmpByIf" resultType="com.MrChengs.bean.Employee">select * from testwhere<!-- test:判斷表達式(OGNL) --><!-- OGNL:apache官方文檔有明確的解釋說明 --><!-- 從參數中取值進行判斷不是數據庫中取值 --><!-- 特殊字符應該寫轉義字符 --><!--此時我們假設忘記把id傳進來 --><if test="name!=null and name!=''">and name like #{name}</if><if test="email!=null and email.trim()!=''">and email like #{email}</if></select>

?look:

show message:DEBUG 10-02 12:18:30,831 ==> Preparing: select * from test where and name like ? and email like ?
(BaseJdbcLogger.java:159)

?

solution ①:??where 1=1 <select id="getEmpByIf" resultType="com.MrChengs.bean.Employee">select * from test<!-- 加入固定的條件,怎么拼裝都行 -->where 1=1<!-- test:判斷表達式(OGNL) --><!-- OGNL:apache官方文檔有明確的解釋說明 --><!-- 從參數中取值進行判斷不是數據庫中取值 --><!-- 特殊字符應該寫轉義字符 --><if test="name!=null and name!=''">and name like #{name}</if><if test="email!=null and email.trim()!=''">and email like #{email}</if></select>

?

solution ②:使用<where></where>? 只會去掉一個and? 或者or <select id="getEmpByIf" resultType="com.MrChengs.bean.Employee">select * from test<where><!-- test:判斷表達式(OGNL) --><!-- OGNL:apache官方文檔有明確的解釋說明 --><!-- 從參數中取值進行判斷不是數據庫中取值 --><!-- 特殊字符應該寫轉義字符 --><if test="name!=null and name!=''">and name like #{name}</if><if test="email!=null and email.trim()!=''">and email like #{email}</if> </where></select>

?注意使用and

?

2.使用trim標簽進行,字符串截取

先看一個案例的錯誤代碼展示: DynamicSQLMapper.java //測試Trimpublic List<Employee> getEmpByIfTrim(Employee emp);

?在DynamicSQL.xml

<!-- 測試Trim() --><!-- public List<Employee> getEmpByIfTrim(Employee emp); --><select id="getEmpByIfTrim" resultType="com.MrChengs.bean.Employee">select * from testwhere<if test="id!=null">id=#{id} and</if><if test="name!=null and name!=''">name like #{name} and</if><if test="email!=null and email.trim()!=''">email like #{email}</if></select>

?

假設我們此時傳參為name屬性一個 @Testpublic void testgetEmpByIfTrim() throws IOException {SqlSessionFactory sessionFactory = getSqlSessionFactory();SqlSession session = sessionFactory.openSession();try{DynamicSQLMapper mapper = session.getMapper(DynamicSQLMapper.class); Employee emp = new Employee("%Mr%", null, null);List<Employee> emps = mapper.getEmpByIfTrim(emp);System.out.println(emps);}finally{session.close();}}

?拼串結果

DEBUG 10-02 13:31:59,995 ==> Preparing: select * from test where id=? and name like ? and

?

開始使用trim標簽:(一些用法都在注釋中,請注意看注釋)

<!-- 測試Trim() --><!-- public List<Employee> getEmpByIfTrim(Employee emp); --><select id="getEmpByIfTrim" resultType="com.MrChengs.bean.Employee">select * from test
<!-- prefix:前綴, trim標簽體中是整個字符串拼串后的結果 給拼串后的整體字符串加一個前綴--><!-- prefixOverrides:前綴覆蓋, 去點整個前綴前面多余的字符串 --><!-- suffix:后綴, 給拼串后的整個字符串加一個后綴 --><!-- suffixOverrides:后綴覆蓋,去掉整個字符串后面多余的字符串 -->

<trim prefix="where" suffixOverrides="and"><if test="name!=null and name!=''">name like #{name} and</if><if test="email!=null and email.trim()!=''">email like #{email} and</if><if test="gender!=null">gender=#{gender}</if></trim></select>

?測試:

public void testgetEmpByIfTrim() throws IOException {SqlSessionFactory sessionFactory = getSqlSessionFactory();SqlSession session = sessionFactory.openSession();try{DynamicSQLMapper mapper = session.getMapper(DynamicSQLMapper.class);Employee emp = new Employee("%Mr%", null, null);List<Employee> emps = mapper.getEmpByIfTrim(emp);System.out.println(emps);}finally{session.close();}}

?結果拼串:

DEBUG 10-02 13:43:25,216 ==> Preparing: select * from test where name like ? (BaseJdbcLogger.java:159) DEBUG 10-02 13:43:25,266 ==> Parameters: %Mr%(String) (BaseJdbcLogger.java:159)

?注意:在測試id的時候,不寫則默認為零,博主自己測試的時候遇到的,所以把id的查詢條件拿掉了!

3.choose分支選擇 如果帶了id使用id進行查詢,帶了name就是用name進行查詢 只能使用一個進行查詢 接口類的代碼: //測試choosepublic List<Employee> getEmpBychoose(Employee emp);

?DynamicSQL.xml:

<!-- choose --><!-- 如果帶了id使用id進行查詢,帶了name就是用name進行查詢,只能使用一個進行查詢 --><!-- public List<Employee> getEmpBychoose(Employee emp); --><select id="getEmpBychoose" resultType="com.MrChengs.bean.Employee">select * from test<where><choose><when test="name!=null">name like #{name}</when> <when test="email!=null">email = #{email}</when><when test="id!=null">id=#{id}</when> <otherwise>d_id=1</otherwise></choose></where></select>

?測試代碼:

//測試choose @Testpublic void testgetEmpBychoose() throws IOException {SqlSessionFactory sessionFactory = getSqlSessionFactory();SqlSession session = sessionFactory.openSession();try{DynamicSQLMapper mapper = session.getMapper(DynamicSQLMapper.class); Employee emp = new Employee("%Mr%", null, null);emp.setId(5);List<Employee> emps = mapper.getEmpBychoose(emp);System.out.println(emps);}finally{session.close();}}

?結果:

DEBUG 10-02 14:07:35,311 ==> Preparing: select * from test WHERE name like ? (BaseJdbcLogger.java:159) DEBUG 10-02 14:07:35,363 ==> Parameters: %Mr%(String) (BaseJdbcLogger.java:159)

?此時我們不僅傳入了name同時還傳入了id,但是拼串之后是使用name進行查詢的

?

?

3.更新

A.<set></set>版本 在接口中: //更新方法public void updataEmp(Employee emp);

?

?在DynamicSQl.xml文件:

?

<!-- update更新 --><!-- 更新 --><!-- public void updataEmp(Employee emp); --><update id="updataEmp">update test<set><if test="name!=null">name=#{name},</if><if test="email!=null"> email=#{email},</if><if test="gender!=null">gender=#{gender},</if></set>where id=#{id}</update>

?

?使用<set>標簽,可以自動為我們解決存在的? ? ”,“? ?問題

測試: //更新upddate @Testpublic void testgetEmpupdate() throws IOException {SqlSessionFactory sessionFactory = getSqlSessionFactory();SqlSession session = sessionFactory.openSession();try{DynamicSQLMapper mapper = session.getMapper(DynamicSQLMapper.class); Employee emp = new Employee("MrChengsR", "gril", null);emp.setId(7);mapper.updataEmp(emp);System.out.println(emp);session.commit();}finally{session.close();}}

?此時修改數據成功

B.<trim><trim> version 僅僅是修改xml文件,其余的都不變 <update id="updataEmp">update test<trim prefix="set" suffixOverrides=","><if test="name!=null">name=#{name},</if><if test="email!=null"> email=#{email},</if><if test="gender!=null">gender=#{gender},</if></trim>where id=#{id}</update>

?

4.foreach

A)foreach: DynamicSQLMapper.java //foreachpublic List<Employee> getEmpsByCollection(List<Integer> list);

?DynamicSQL.xml

<!-- foreach: --><!-- public List<Employee> getEmpsByCollection(Employee emp); --><select id="getEmpsByCollection" resultType="com.MrChengs.bean.Employee" >select * from test where id in(<!-- collection:指定遍歷的集合 --><!-- list類型的參數會做特殊的處理封裝在map中,map的key叫list --><!-- item:將當前遍歷出的元素賦值給指定的變量 --><!-- #{變量名} 就能取出當前遍歷的元素 --><!-- separator:每個元素之間的分隔符 此時是in(a,b,c,d)這里面的 , --><!-- open:遍歷出所有結果拼接一個開始的字符 --><!-- close:便利的所有結果拼出結尾 --><!-- index:遍歷list是索引,遍歷map就是map的key --><foreach collection="list" item="item_id" separator=",">#{item_id}</foreach>)</select>

?

測試類: @Testpublic void testgetEmpForeach() throws IOException {SqlSessionFactory sessionFactory = getSqlSessionFactory();SqlSession session = sessionFactory.openSession();try{DynamicSQLMapper mapper = session.getMapper(DynamicSQLMapper.class);List<Employee> emps = mapper.getEmpsByCollection(Arrays.asList(5,7,8));for(Employee emp : emps){System.out.println(emp);}}finally{session.close();}}

?得到結果:

DEBUG 10-02 19:16:01,838 ==> Preparing: select * from test where id in( ? , ? , ? ) (BaseJdbcLogger.java:159) DEBUG 10-02 19:16:01,887 ==> Parameters: 5(Integer), 7(Integer), 8(Integer) (BaseJdbcLogger.java:159) DEBUG 10-02 19:16:01,909 <== Total: 3 (BaseJdbcLogger.java:159) Employee [id=5, name=MrChengs, gender=boy, email=xxxxxxxx@qq.com, dept=null] Employee [id=7, name=MrChengs, gender=gril, email=zhangsan@qq.com, dept=null] Employee [id=8, name=MrChen, gender=gril, email=xxxxxx@xx.xxx, dept=null]

?

?

?

B.批量保存

方法1: 接口類中: //批量存取public void addEmps(@Param("emps")List<Employee> employee);

?

?xml文件:

?

<!-- //批量存取--><!-- public void addEmps(@Param("emps")Employee employee); --><insert id="addEmps">insert into test(name,gender,email,d_id)values<foreach collection="emps" separator="," item="emp"> <!-- 傳參數之前是我們new的一個對象,傳參數之后是插入數據庫的數據 -->(#{emp.name},#{emp.gender},#{emp.email},#{emp.dept.id})</foreach></insert>

?

?實現類:

//批量存取 @Testpublic void testgetEmpaddEmps() throws IOException {SqlSessionFactory sessionFactory = getSqlSessionFactory();SqlSession session = sessionFactory.openSession();try{DynamicSQLMapper mapper = session.getMapper(DynamicSQLMapper.class);List<Employee> employee = new ArrayList<Employee>();employee.add(new Employee("Ma", "gril", "Ma@Ma", new Department(1)));employee.add(new Employee("Mb", "boy", "Mb@Mb", new Department(2)));mapper.addEmps(employee);session.commit();}finally{session.close();}} 此時是成功插入數據 方法二: <!-- 方法二 --><!-- 需要加上 --> <!-- jdbc.url=jdbc:mysql://localhost:3306/mybatis?allowMultiQueries=true --><insert id="addEmps"><foreach collection="emps" separator=";" item="emp">insert into test(name,gender,email,d_id)values(#{emp.name},#{emp.gender},#{emp.email},#{emp.dept.id})</foreach></insert>

?其余不變可以進行測試

c.兩個重要的參數 <!-- 兩個重要的參數 --> <!-- _parameter:代表整個參數,單個參數就是這個參數,多個參數就是封裝成的map --> <!-- _databaseId:配置了databaseIdProvider標簽,就是代表當前數據庫的別名 --> _databaseId: mybatis-config.xml <databaseIdProvider type="DB_VENDOR"><property name="MySQL" value="mysql"/><property name="Oracle" value="oracle"/></databaseIdProvider>

?接口類中

//測試兩個屬性public List<Employee> getEmpselect();

?DynamicMapper.xml

<!-- 兩個重要的參數 --><!-- _parameter:代表整個參數,單個參數就是這個參數,多個參數就是封裝成的map --><!-- _databaseId:配置了databaseIdProvider標簽,就是代表當前數據庫的別名 --><!-- public Employee getEmpselect(int id); --><!-- 修改if中的test條件即可實現不同數據庫之間的查詢 --><select id="getEmpselect" resultType="com.MrChengs.bean.Employee" databaseId="mysql"><if test="_databaseId=='mysql'">select * from test</if><if test="_databaseId=='oracle'">select * from test</if></select>

?測試類:

//兩個重要的參數 @Testpublic void testgetEmpselect() throws IOException {SqlSessionFactory sessionFactory = getSqlSessionFactory();SqlSession session = sessionFactory.openSession();try{DynamicSQLMapper mapper = session.getMapper(DynamicSQLMapper.class);List<Employee> emps= mapper.getEmpselect();for(Employee emp : emps){System.out.println();}}finally{session.close();}}

?

此時可以成功查詢數據!! _parameter 在接口類中:把剛剛測試代碼加上id //測試兩個屬性public List<Employee> getEmpselect(int id);

?在xnl文件中:

<!-- public Employee getEmpselect(int id); --><select id="getEmpselect" resultType="com.MrChengs.bean.Employee" databaseId="mysql"><if test="_databaseId=='mysql'">select * from test<if test="_parameter!=null">where id=#{id}</if></if><if test="_databaseId=='oracle'">select * from test</if></select>

?

測試類: @Testpublic void testgetEmpselect() throws IOException {SqlSessionFactory sessionFactory = getSqlSessionFactory();SqlSession session = sessionFactory.openSession();try{ DynamicSQLMapper mapper = session.getMapper(DynamicSQLMapper.class);List<Employee> emps= mapper.getEmpselect(5);System.out.println(emps);}finally{session.close();}} 此時的查詢成功!!! D.bind標簽的使用 接口類中: //測試兩個屬性//public List<Employee> getEmpselect();//public List<Employee> getEmpselect(int id);public List<Employee> getEmpselect(Employee em);

?

xml文件: <select id="getEmpselect" resultType="com.MrChengs.bean.Employee" databaseId="mysql"> <!-- bind:可以將OGNL表達式的值綁定到一個變量中,方便引用這個變量的值 --> ???????????<!-- name :是我們指定的綁定參數--> ???????????<!-- value :指定參數的值 --> <bind name="_name" value="'%'+name+'%'"/> <if test="_databaseId=='mysql'"> select * from test <if test="_parameter!=null"> where name like #{_name} </if> </if> <if test="_databaseId=='oracle'"> select * from test </if> </select>

?測試類:

@Testpublic void testgetEmpselect() throws IOException {SqlSessionFactory sessionFactory = getSqlSessionFactory();SqlSession session = sessionFactory.openSession();try{DynamicSQLMapper mapper = session.getMapper(DynamicSQLMapper.class);//List<Employee> emps= mapper.getEmpselect();//List<Employee> emps= mapper.getEmpselect(5);Employee emp = new Employee();emp.setName("M");List<Employee> emps= mapper.getEmpselect(emp);System.out.println(emps);}finally{session.close();}}

?

?

E.SQL標簽

<!-- <include refid=""></include> --> <!-- SQL:抽取可重用的sql字段,方便后面引用 --> <!-- include:就是引用外部標簽 --> <!-- ???1.sql抽取:經常要查詢的列名,或者插入用的列名抽取出來方便引用 ???????????2.include來引用已經抽取的sql ???????????3.include還可以自定義一些property,sql標簽內部只能使用自定義的屬性 ???????????????? include-property:取值正確方式? ${prop} ???????????????? #{不可以使用這種方式} --> <sql id=""> <!-- 同時這里面還可以使用?? if進行判斷 --> <if test=""></if> </sql>

轉載于:https://www.cnblogs.com/Mrchengs/p/9741325.html

總結

以上是生活随笔為你收集整理的MyBatis(4)动态SQL的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。