MyBatis(三)——动态SQL
文章目錄
- 1. 簡介
- 2. 搭建環(huán)境
- 2.1 在MySQL中創(chuàng)建blog表
- 2.2 編寫實體類
- 2.3 編寫實體類對應(yīng)Mapper接口
- 2.4 編寫Mapper接口對應(yīng)的Mapper.xml文件
- 2.5 編寫測試類
- 3. if
- 4. where
- 5. set
- 6. choose
- 7. foreach
1. 簡介
動態(tài)SQL就是指根據(jù)不同的條件生成不同的SQL語句
傳統(tǒng)的使用JDBC的方法,在組合復(fù)雜的的SQL語句的時候,需要去拼接,稍不注意哪怕少了個空格,都會導(dǎo)致錯誤。Mybatis的動態(tài)SQL功能正是為了解決這種問題, 其通過 if, choose, when, otherwise, trim, where, set, foreach標(biāo)簽,可組合成非常靈活的SQL語句,從而提高開發(fā)人員的效率。
2. 搭建環(huán)境
2.1 在MySQL中創(chuàng)建blog表
CREATE TABLE `blog` (`id` varchar(50) NOT NULL COMMENT '博客id',`title` varchar(100) NOT NULL COMMENT '博客標(biāo)題',`author` varchar(30) NOT NULL COMMENT '博客作者',`create_time` datetime NOT NULL COMMENT '創(chuàng)建時間',`views` int(30) NOT NULL COMMENT '瀏覽量' ) ENGINE=InnoDB DEFAULT CHARSET=utf82.2 編寫實體類
package com.zz.pojo;import lombok.Data;import java.util.Date;@Data public class Blog {private String id;private String title;private String author;private Date createDate;private int views;}可選擇在idea中連接數(shù)據(jù)庫
解決辦法:在mybatis-config.xml中開啟駝峰命名
同時也開啟日志
2.3 編寫實體類對應(yīng)Mapper接口
package com.zz.mapper;import com.zz.pojo.Blog;public interface BlogMapper {//新增一個博客int addBlog(Blog blog); }2.4 編寫Mapper接口對應(yīng)的Mapper.xml文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.zz.mapper.BlogMapper"><insert id="addBlog" parameterType="Blog">insert into mybatis.blog (id, title, author, create_time, views)values (#{id},#{title},#{author},#{createDate},#{views}); </insert></mapper>2.5 編寫測試類
可選擇在util目錄下創(chuàng)建IDUtils工具類,因為在真實開發(fā)中id一般是隨機(jī)的數(shù)字,調(diào)用IDUtils類,保證生成的id都不相同。
package com.zz.utils;import java.util.UUID;public class IDUtils {public static String getId(){return UUID.randomUUID().toString().replaceAll("-","");} }編寫測試類,往數(shù)據(jù)庫中添加八篇博客
package com.zz.mapper;import com.zz.pojo.Blog; import com.zz.utils.IDUtils; import com.zz.utils.MyBatisUtils; import org.apache.ibatis.session.SqlSession; import org.junit.Test;import java.util.Date;public class BlogMapperTest {@Testpublic void testAddBlog(){SqlSession session = MyBatisUtils.getSession();BlogMapper mapper = session.getMapper(BlogMapper.class);Blog blog01 = new Blog();//調(diào)用IDUtils包,保證id都不相同blog01.setId(IDUtils.getId()); //真實開發(fā)中id一般是隨機(jī)的數(shù)字(uuid)blog01.setTitle("Hello MyBatis");blog01.setAuthor("大佬");blog01.setCreateDate(new Date());blog01.setViews(9999);mapper.addBlog(blog01);Blog blog02 = new Blog();//調(diào)用IDUtils包,保證id都不相同blog02.setId(IDUtils.getId()); //真實開發(fā)中id一般是隨機(jī)的數(shù)字(uuid)blog02.setTitle("Hello JDBC");blog02.setAuthor("大佬");blog02.setCreateDate(new Date());blog02.setViews(9999);mapper.addBlog(blog02);Blog blog03 = new Blog();//調(diào)用IDUtils包,保證id都不相同blog03.setId(IDUtils.getId()); //真實開發(fā)中id一般是隨機(jī)的數(shù)字(uuid)blog03.setTitle("Hello MySQL");blog03.setAuthor("大佬");blog03.setCreateDate(new Date());blog03.setViews(9999);mapper.addBlog(blog03);Blog blog04 = new Blog();//調(diào)用IDUtils類,保證id都不相同blog04.setId(IDUtils.getId()); //真實開發(fā)中id一般是隨機(jī)的數(shù)字(uuid)blog04.setTitle("Hello Spring");blog04.setAuthor("大佬");blog04.setCreateDate(new Date());blog04.setViews(9999);mapper.addBlog(blog04);session.commit(); //提交事務(wù)} }運(yùn)行結(jié)果:
至此,環(huán)境搭建完畢!
3. if
接口BlogMapper的代碼:
package com.zz.mapper;import com.zz.pojo.Blog;import java.util.List; import java.util.Map;public interface BlogMapper {//新增一個博客int addBlog(Blog blog);//通過作者名和博客名來查詢博客//如果作者名為空,則根據(jù)博客名來查詢List<Blog> getBlogByIf(Map map); }接口的配置文件BlogMapper.xml 代碼:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.zz.mapper.BlogMapper"><insert id="addBlog" parameterType="Blog">insert into mybatis.blog (id, title, author, create_time, views)values (#{id},#{title},#{author},#{createDate},#{views}); </insert><select id="getBlogByIf" resultType="Blog" parameterType="map">select * from mybatis.blog where<if test="title!=null">title=#{title}</if><if test="author!=null">and author=#{author}</if></select></mapper>測試類BlogMapperTest 代碼:
- 當(dāng)在map中只添加title時
運(yùn)行結(jié)果:
- 當(dāng)在map中添加title和author時
運(yùn)行結(jié)果:
可以看出:根據(jù)不同的條件生成不同的SQL語句,即動態(tài)SQL
4. where
使用場景:如果我們需要拼接where條件,又不希望客戶端傳遞錯誤信息,這時需要使用where 標(biāo)簽。
作用:如果后面有語句,就自動添加where;如果后面語句開頭是and 或者or,它可以自動去掉。
接口的配置文件BlogMapper.xml 代碼:
注意:在author 前添加了 and
測試類BlogMapperTest 的代碼:
- 當(dāng)在map中什么都不添加,為空時
運(yùn)行結(jié)果:
可以看出:查詢出了所有的博客
- 當(dāng)在map中只添加author時
運(yùn)行結(jié)果:
可以看出,把配置文件中的 and 去掉了
5. set
如果里面的條件滿足,自動拼接set標(biāo)簽;后面如果有多余的逗號,可以自動去除
接口BlogMapper的代碼:
//更新博客int updateBlog(Map map);接口的配置文件BlogMapper.xml 代碼:
注意:在title 后添加了逗號
<insert id="updateBlog" parameterType="map">update mybatis.blog<set><if test="title !=null">title = #{title},</if><if test="author !=null">author = #{author}</if></set>where id= #{id}</insert>測試類BlogMapperTest 的代碼:
map中必須添加id,否則會報錯
- 當(dāng)在map中只添加id和author時
運(yùn)行結(jié)果:
- 當(dāng)在map中添加id,author和title時
運(yùn)行結(jié)果:
- 當(dāng)在map中只添加id和title時
運(yùn)行結(jié)果:
可以發(fā)現(xiàn):title 后面的逗號去掉了
where標(biāo)簽和set 標(biāo)簽的底層都是trim標(biāo)簽
6. choose
好比java中的switch
接口BlogMapper的代碼:
//查詢博客 但是只要有一個條件滿足即可 List<Blog> queryBlogByChoose(Map map);接口的配置文件BlogMapper.xml 代碼:
<select id="queryBlogByChoose" parameterType="map" resultType="Blog">select * from mybatis.blog<where><choose><when test="title!=null">title = #{title}</when><when test="author!=null">and author = #{author}</when><otherwise>and views= #{views}</otherwise></choose></where></select>測試類BlogMapperTest 的代碼:
- 當(dāng)在map中什么都不添加時
運(yùn)行結(jié)果:
- 當(dāng)在map中只添加title時
運(yùn)行結(jié)果:
- 當(dāng)在map中只添加author時
運(yùn)行結(jié)果:
- 當(dāng)在map中添加title和author時
運(yùn)行結(jié)果:
可以看出:雖然傳入了兩個參數(shù),但只顯示了一個
7. foreach
相當(dāng)于子查詢 where in(1,2,3)
collection 表示輸入的參數(shù) map
item 表示遍歷出來的每一項
open 表示打開
close 表示關(guān)閉
separator 表示分割符
通過item 遍歷出來的標(biāo)簽可以在foreach中使用
接口BlogMapper的代碼:
List<Blog> queryBlogByForeach(Map map);接口的配置文件BlogMapper.xml 代碼:
<!--子查詢 where in(1,2,3)--><select id="queryBlogByForeach" parameterType="map" resultType="Blog">select * from mybatis.blog<where><foreach collection="ids" item="id" open="and (" close=")" separator="or">id = #{id}</foreach></where></select>測試類BlogMapperTest 代碼:
//測試foreach@Testpublic void testForeach(){SqlSession session = MyBatisUtils.getSession();BlogMapper mapper = session.getMapper(BlogMapper.class);Map<String,List> map = new HashMap();List<String> ids = new ArrayList<String>();ids.add("bac368d88b4a4d8eb6bd1b539a3338a0");ids.add("321c98e9beea45d092c39b2cfe0fc370");ids.add("cfbc34f0a1dd40fdba91e99dfe4c365a");map.put("ids",ids);mapper.queryBlogByForeach(map);session.commit();}運(yùn)行結(jié)果:
可以看出:就相當(dāng)于SQL中的 select * from mybatis.blog where and (id=xxx or id=xxx or id=xxx)
總結(jié)
以上是生活随笔為你收集整理的MyBatis(三)——动态SQL的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MyBatis(二)——多对一、一对多
- 下一篇: Spring(三)——HelloSpri