MyBatis select
1. 前言
本小節(jié),我們將一起學(xué)習(xí) MyBatis select。
在 MyBatis 中,select 標(biāo)簽對(duì)應(yīng)于 SQL 語句中的 select 查詢,我們會(huì)在 select 標(biāo)簽中填充 SQL 查詢語句,然后在代碼中通過對(duì)應(yīng)接口方法來調(diào)用。
2. 定義
慕課解釋:select 標(biāo)簽用于映射 SQL 中的
查詢
語句
3. 實(shí)例
MyBatis select 可分為xml
和注解
兩種使用方式。
3.1 xml 實(shí)例
將 select 查詢寫在 mapper.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.imooc.mybatis.mapper.UserMapper">
<select id="selectUserAgeById" parameterType="java.lang.Integer" resultType="java.lang.Integer">
SELECT age FROM imooc_user WHERE id = #{id}
</select>
</mapper>
其中名為 selectUserAgeById 的 select 標(biāo)簽(一般以 id 做為名稱),接收 Integer 類型的參數(shù)(parameterType),并返回 Integer 類型的結(jié)果(resultType);再看 select 標(biāo)簽中的查詢語句,接收 id 參數(shù),類型為 int,返回 age,類型為 int,二者一一對(duì)應(yīng)。
3.2 參數(shù)符號(hào)
注意,在 select 標(biāo)簽中的 SQL 語句幾乎與真實(shí)的 SQL 語句一致,但它的參數(shù)符號(hào)稍有不同:
#{id}
若以 #{}
作為參數(shù)符號(hào),MyBatis 則會(huì)創(chuàng)建一個(gè)預(yù)處理語句(PreparedStatement),它會(huì)被處理成?
。如果你不希望使用預(yù)處理,那么可以使用${}
參數(shù)符號(hào),MyBatis 會(huì)將其以字符串的形式進(jìn)行拼接,不過我們推薦你使用 #{}
,幾乎所有人也都這樣做。
3.3 注解實(shí)例
將 SQL 語句寫在注解中,如下:
@Select("SELECT username FROM imooc_user WHERE id = #{id}")
String selectUsernameById(Integer id);
注解中的 select 語句無需再添加 id、parameterType 等屬性,只需寫上對(duì)應(yīng)的 SQL 語句,MyBatis 會(huì)自動(dòng)根據(jù)其修飾的方法來推斷出這些參數(shù)。
TIPS: 提示,使用注解來書寫 MyBatis 相對(duì)會(huì)方便一些,但是注解無法發(fā)揮 MyBatis 動(dòng)態(tài) SQL 真正的威力,因此大部分人都還是會(huì)選擇 xml 的方式來書寫 SQL,但是對(duì)于一些 demo 的展示,注解無疑容易上手一些。在后面的學(xué)習(xí)中,我們都會(huì)介紹到注解的使用,但是在實(shí)踐中我們默認(rèn)使用 xml 方式。
4. select 屬性
select 標(biāo)簽支持很多屬性來改變查詢語句的行為。
我們摘取其中常見且重要的屬性,如下表所示:
屬性 | 描述 |
---|---|
id | 在命名空間中唯一的標(biāo)識(shí)符 |
parameterType | 語句的參數(shù)類型,默認(rèn)可選,MyBatis 會(huì)自動(dòng)推斷 |
resultType | 語句返回值類型,如果返回的是集合,那應(yīng)該設(shè)置為集合包含的類型 |
resultMap | 語句返回映射的 id;可以使用 resultType 或 resultMap,但不能同時(shí)使用。 |
flushCache | 設(shè)置為 true 后,只要語句被調(diào)用,都會(huì)導(dǎo)致本地緩存和二級(jí)緩存被清空,默認(rèn)為 false |
useCache | 設(shè)置為 true 后,本條語句的查詢結(jié)果被二級(jí)緩存緩存起來,默認(rèn) select 標(biāo)簽為 true。 |
timeout | 設(shè)置超時(shí)時(shí)間 |
fetchSize | 設(shè)置預(yù)期返回的記錄數(shù)量 |
statementType | STATEMENT,PREPARED 或 CALLABLE 中的一個(gè),默認(rèn)為 PREPARED(預(yù)處理) |
5. 參數(shù)
在上面的實(shí)例中,我們介紹了#{id}
參數(shù),這是參數(shù)的最簡(jiǎn)單情況,對(duì)于復(fù)雜情況,參數(shù)還有其它更多的妙用。
5.1 對(duì)象參數(shù)
有時(shí)候,參數(shù)可以是一個(gè)復(fù)雜的對(duì)象,如 Java 中的一個(gè) User 類。
<select id="selectUserByAgeAndScore" parameterType="com.imooc.mybatis.model.User"
resultType="com.imooc.mybatis.model.User">
SELECT * FROM imooc_user WHERE age = #{age} AND score = #{score}
</select>
selectUserByAgeAndScore 查詢的參數(shù)是一個(gè)復(fù)雜 Java 對(duì)象 User,當(dāng) User 作為參數(shù)對(duì)象時(shí),User 中的屬性都可作為查詢語句的參數(shù),如 age 和 score。
5.2 參數(shù)配置
#{}
不僅可以傳入?yún)?shù)名稱,還可以傳入?yún)?shù)類型和類型處理器。
比如:
#{age,javaType=int,jdbcType=int,typeHandler=IntegerTypeHandler}
其中 javaType 表示 age 的 Java 類型,jdbcType 表示 age 的數(shù)據(jù)庫類型,typeHandler 表示 age 的類型處理器,關(guān)于類型處理器我們將在后面的章節(jié)介紹。
對(duì)于參數(shù)配置,90% 的情況你都只需要傳入?yún)?shù)名即可,因?yàn)?MyBatis 都會(huì)自動(dòng)推斷出配置。
6. 實(shí)踐
介紹了這么多概念,我們一起來實(shí)操鞏固一下。
6.1 例1. 通過年齡和分?jǐn)?shù)查詢用戶
請(qǐng)使用 MyBatis 完成在 imooc_user 表中通過年齡
和分?jǐn)?shù)
查詢用戶的功能。
分析:
按照 MyBatis 的開發(fā)模式,先在對(duì)應(yīng) UserMapper.xml 文件中添加通過年齡和分?jǐn)?shù)查詢用戶的 select 標(biāo)簽,然后在 UserMapper.java 中增加上對(duì)應(yīng)的方法即可。
步驟:
首先,我們?cè)?com.imooc.mybatis 包下新建 model 包,用于保存數(shù)據(jù)庫對(duì)象,并在 model 包下新建 User.java 類:
package com.imooc.mybatis.model;
public class User {
private Long id;
private String username;
private Integer age;
private Integer score;
// 省略了 getter 和 setter 方法,請(qǐng)務(wù)必通過 IDE 生成,否則 MyBatis 無法自動(dòng)映射
}
在 UserMapper.xml 文件中,我們新增 selectUserByAgeAndScore 標(biāo)簽,該 select 標(biāo)簽的作用是:通過年齡和分?jǐn)?shù)查詢用戶。
<select id="selectUserByAgeAndScore" parameterType="com.imooc.mybatis.model.User"
resultType="com.imooc.mybatis.model.User">
SELECT * FROM imooc_user WHERE age = #{age} AND score = #{score}
</select>
然后在 UserMapper.java 接口中,我們新增對(duì)應(yīng)的方法,方法接收復(fù)雜參數(shù) User:
package com.imooc.mybatis.mapper;
import com.imooc.mybatis.model.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper {
User selectUserByAgeAndScore(User user);
}
結(jié)果:
通過如下代碼,我們運(yùn)行 selectUserByAgeAndScore 方法。
// 得到 mapper
UserMapper userMapper = session.getMapper(UserMapper.class);
User condition = new User();
condition.setAge(18);
condition.setScore(100);
// 調(diào)用方法
User user = userMapper.selectUserByAgeAndScore(condition);
// 得到 user
System.out.println(user);
輸出結(jié)果為:
User{id=1, username='peter', age=18, score=100}
注意: 我們無法貼出全部的代碼,這里的代碼都是建立在之前的小節(jié)之上的,如果你感到疑惑,那么請(qǐng)先閱讀環(huán)境搭建小節(jié)和 mapper 小節(jié)。
7. 小結(jié)
- MyBatis 雖然提供了
#{}
和${}
兩種方式來傳遞參數(shù),但無疑#{}
更加實(shí)用。 - select 標(biāo)簽屬性雖然多,但是大部分情況下都不會(huì)針對(duì)某一個(gè) select 標(biāo)簽來定制化,多會(huì)在全局里進(jìn)行配置。
- 互聯(lián)網(wǎng)的應(yīng)用場(chǎng)景多數(shù)為讀多寫少,那么 select 肯定是使用
最為廣泛
的標(biāo)簽了。