MyBatis中XML映射器的實(shí)現(xiàn)
XML映射器
MyBatis 的真正強(qiáng)大在于它的語句映射,這是它的魔力所在。由于它的異常強(qiáng)大,映射器的 XML 文件就顯得相對(duì)簡(jiǎn)單。如果拿它跟具有相同功能的 JDBC 代碼進(jìn)行對(duì)比,你會(huì)立即發(fā)現(xiàn)省掉了將近 95% 的代碼。MyBatis 致力于減少使用成本,讓用戶能更專注于 SQL 代碼。
SQL 映射文件只有很少的幾個(gè)頂級(jí)元素(按照應(yīng)被定義的順序列出):
cache– 該命名空間的緩存配置。cache-ref– 引用其它命名空間的緩存配置。resultMap– 描述如何從數(shù)據(jù)庫(kù)結(jié)果集中加載對(duì)象,是最復(fù)雜也是最強(qiáng)大的元素。parameterMap– 老式風(fēng)格的參數(shù)映射。此元素已被廢棄,并可能在將來被移除!請(qǐng)使用行內(nèi)參數(shù)映射。文檔中不會(huì)介紹此元素。sql– 可被其它語句引用的可重用語句塊。insert– 映射插入語句。update– 映射更新語句。delete– 映射刪除語句。select– 映射查詢語句。
CRUD操作
select
查詢語句是 MyBatis 中最常用的元素之一——光能把數(shù)據(jù)存到數(shù)據(jù)庫(kù)中價(jià)值并不大,還要能重新取出來才有用,多數(shù)應(yīng)用也都是查詢比修改要頻繁。 MyBatis 的基本原則之一是:在每個(gè)插入、更新或刪除操作之間,通常會(huì)執(zhí)行多個(gè)查詢操作。因此,MyBatis 在查詢和結(jié)果映射做了相當(dāng)多的改進(jìn)。一個(gè)簡(jiǎn)單查詢的 select 元素是非常簡(jiǎn)單的。
根據(jù)id查詢用戶
public interface UserMapper {
//查詢user表數(shù)據(jù)
List<User> selectUser();
//根據(jù)id查詢用戶
User selectUserById(int id);
}
UserMapper.xml
<!--
id : 與mapper層的接口做映射
parameterType : 參數(shù)類型
resultType : 返回的類型對(duì)象
-->
<select id="selectUserById" resultType="com.sin.pojo.User" parameterType="int">
select * from user where id = #{id}
</select>
#{id}告訴 MyBatis 創(chuàng)建一個(gè)預(yù)處理語句(PreparedStatement)參數(shù),在 JDBC 中,這樣的一個(gè)參數(shù)在 SQL 中會(huì)由一個(gè)“?”來標(biāo)識(shí),并被傳遞到一個(gè)新的預(yù)處理語句中,
類似于
// 近似的 JDBC 代碼,非 MyBatis 代碼... String selectPerson = "SELECT * FROM PERSON WHERE ID=?"; PreparedStatement ps = conn.prepareStatement(selectPerson); ps.setInt(1,id);
測(cè)試用例
@Test
public void selectUserById(){
SqlSession session = MyBatisUtil.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
System.out.println(mapper.selectUserById(2));
}
根據(jù)名字和密碼查詢
方法一:使用對(duì)象
UserMapper.java
- 參數(shù)傳入對(duì)象
//根據(jù)用戶名和密碼查詢 User findByUserAndPwd(User user);
UserMapper.xml
<select id="findByUserAndPwd" resultType="com.sin.pojo.User" parameterType="com.sin.pojo.User">
select * from user where name = #{name} and pwd = #{pwd}
</select>
測(cè)試用例
@Test
public void selectByUserAndPwd(){
SqlSession session = MyBatisUtil.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = new User();
user.setName("張三");
user.setPwd("321321");
System.out.println(mapper.findByUserAndPwd(user));
}
方法二:使用Map
UserMapper.java
//根據(jù)用戶名和密碼查詢 User findByUserAndPwd2(Map<String,Object> map);
UserMapper.xml
<select id="findByUserAndPwd2" resultType="com.sin.pojo.User"
parameterType="java.util.Map">
select * from user where name = #{name} and pwd = #{pwd}
</select>
測(cè)試用例
@Test
public void selectByUserAndPwd2(){
SqlSession session = MyBatisUtil.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
Map<String,Object> map = new HashMap<>();
map.put("name","張三");
map.put("pwd","321321");
System.out.println(mapper.findByUserAndPwd2(map));
}
方法三:方法種傳遞參數(shù)
UserMapper.java
- 在接口方法的參數(shù)前加
@Param屬性 - Sql語句編寫的時(shí)候,直接取
@Param中設(shè)置的值即可,不需要單獨(dú)設(shè)置參數(shù)類型
//根據(jù)用戶名和密碼查詢
User findByUserAndPwd3(@Param("username") String username, @Param("pwd") String pwd);
UserMapper.xml
<select id="findByUserAndPwd3" resultType="com.sin.pojo.User">
select * from user where name = #{username} and pwd = #{pwd}
</select>
測(cè)試用例
@Test
public void selectByUserAndPwd3(){
System.out.println(mapper.findByUserAndPwd3("張三","321321"));
}
<select id="selectPerson" parameterType="int" parameterMap="deprecated" resultType="hashmap" resultMap="personResultMap" flushCache="false" useCache="true" timeout="10" fetchSize="256" statementType="PREPARED" resultSetType="FORWARD_ONLY">
Select 元素的屬性
| 屬性 | 描述 |
|---|---|
| id | 在命名空間中唯一的標(biāo)識(shí)符,可以被用來引用這條語句。 |
| parameterType | 將會(huì)傳入這條語句的參數(shù)的類全限定名或別名。這個(gè)屬性是可選的,因?yàn)?MyBatis 可以通過類型處理器(TypeHandler)推斷出具體傳入語句的參數(shù),默認(rèn)值為未設(shè)置(unset)。 |
| parameterMap | 用于引用外部 parameterMap 的屬性,目前已被廢棄。請(qǐng)使用行內(nèi)參數(shù)映射和 parameterType 屬性。 |
| resultType | 期望從這條語句中返回結(jié)果的類全限定名或別名。 注意,如果返回的是集合,那應(yīng)該設(shè)置為集合包含的類型,而不是集合本身的類型。 resultType 和 resultMap 之間只能同時(shí)使用一個(gè)。 |
| resultMap | 對(duì)外部 resultMap 的命名引用。結(jié)果映射是 MyBatis 最強(qiáng)大的特性,如果你對(duì)其理解透徹,許多復(fù)雜的映射問題都能迎刃而解。 resultType 和 resultMap 之間只能同時(shí)使用一個(gè)。 |
| flushCache | 將其設(shè)置為 true 后,只要語句被調(diào)用,都會(huì)導(dǎo)致本地緩存和二級(jí)緩存被清空,默認(rèn)值:false。 |
| useCache | 將其設(shè)置為 true 后,將會(huì)導(dǎo)致本條語句的結(jié)果被二級(jí)緩存緩存起來,默認(rèn)值:對(duì) select 元素為 true。 |
| timeout | 這個(gè)設(shè)置是在拋出異常之前,驅(qū)動(dòng)程序等待數(shù)據(jù)庫(kù)返回請(qǐng)求結(jié)果的秒數(shù)。默認(rèn)值為未設(shè)置(unset)(依賴數(shù)據(jù)庫(kù)驅(qū)動(dòng))。 |
| fetchSize | 這是一個(gè)給驅(qū)動(dòng)的建議值,嘗試讓驅(qū)動(dòng)程序每次批量返回的結(jié)果行數(shù)等于這個(gè)設(shè)置值。 默認(rèn)值為未設(shè)置(unset)(依賴驅(qū)動(dòng))。 |
| statementType | 可選 STATEMENT,PREPARED 或 CALLABLE。這會(huì)讓 MyBatis 分別使用 Statement,PreparedStatement 或 CallableStatement,默認(rèn)值:PREPARED。 |
| resultSetType | FORWARD_ONLY,SCROLL_SENSITIVE, SCROLL_INSENSITIVE 或 DEFAULT(等價(jià)于 unset) 中的一個(gè),默認(rèn)值為 unset (依賴數(shù)據(jù)庫(kù)驅(qū)動(dòng))。 |
| databaseId | 如果配置了數(shù)據(jù)庫(kù)廠商標(biāo)識(shí)(databaseIdProvider),MyBatis 會(huì)加載所有不帶 databaseId 或匹配當(dāng)前 databaseId 的語句;如果帶和不帶的語句都有,則不帶的會(huì)被忽略。 |
| resultOrdered | 這個(gè)設(shè)置僅針對(duì)嵌套結(jié)果 select 語句:如果為 true,則假設(shè)結(jié)果集以正確順序(排序后)執(zhí)行映射,當(dāng)返回新的主結(jié)果行時(shí),將不再發(fā)生對(duì)以前結(jié)果行的引用。 這樣可以減少內(nèi)存消耗。默認(rèn)值:false。 |
| resultSets | 這個(gè)設(shè)置僅適用于多結(jié)果集的情況。它將列出語句執(zhí)行后返回的結(jié)果集并賦予每個(gè)結(jié)果集一個(gè)名稱,多個(gè)名稱之間以逗號(hào)分隔。 |
insert
給數(shù)據(jù)庫(kù)增加一個(gè)用戶
UserMapper.java
//添加一條用戶 int addUser(User user);
UserMapper.xml
<insert id="addUser" parameterType="com.sin.pojo.User">
insert into user(id,name,pwd) values (#{id},#{name},#{pwd})
</insert>
測(cè)試用例
@Test
public void addUser(){
SqlSession session = MyBatisUtil.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = new User(5,"王五","123456");
System.out.println(mapper.addUser(user));
session.commit();//提交事務(wù),重點(diǎn)!不寫的話不會(huì)提交到數(shù)據(jù)庫(kù)
}
update
修改用戶的信息
UserMapper.java
//修改一個(gè)用戶 int updateUser(User user);
UserMapper.xml
<update id="updateUser" parameterType="com.sin.pojo.User">
update user set name = #{name},pwd = #{pwd} where id = #{id}
</update>
測(cè)試用例
@Test
public void testUpdateUser(){
SqlSession session = MyBatisUtil.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectUserById(1);
user.setName("趙六");
user.setPwd("123456");
int i = mapper.updateUser(user);
System.out.println(mapper.selectUserById(1));
session.commit();//提交事務(wù),
session.close();
}
delete
根據(jù)id刪除一個(gè)用戶
UserMapper.java
//根據(jù)id刪除用戶 int deleteUserById(int id);
UserMapper.xml
<delete id="deleteUserById" parameterType="com.sin.pojo.User">
delete from user where id = #{id};
</delete>
測(cè)試用例
@Test
public void deleteUesrById(){
SqlSession session = MyBatisUtil.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
System.out.println(mapper.deleteUserById(5));
session.commit();//提交事務(wù),
List<User> users = mapper.selectUser();
for (User user: users){
System.out.println(user);
}
session.close();
}
<insert id="insertAuthor" parameterType="com.sin.pojo.User" flushCache="true" statementType="PREPARED" keyProperty="" keyColumn="" useGeneratedKeys="" timeout="20"> <update id="updateAuthor" parameterType="com.sin.pojo.User" flushCache="true" statementType="PREPARED" timeout="20"> <delete id="deleteAuthor" parameterType="com.sin.pojo.User" flushCache="true" statementType="PREPARED" timeout="20">
Insert, Update, Delete 元素的屬性
| 屬性 | 描述 |
|---|---|
| id | 在命名空間中唯一的標(biāo)識(shí)符,可以被用來引用這條語句。 |
| parameterType | 將會(huì)傳入這條語句的參數(shù)的類全限定名或別名。這個(gè)屬性是可選的,因?yàn)?MyBatis 可以通過類型處理器(TypeHandler)推斷出具體傳入語句的參數(shù),默認(rèn)值為未設(shè)置(unset)。 |
| parameterMap | 用于引用外部 parameterMap 的屬性,目前已被廢棄。請(qǐng)使用行內(nèi)參數(shù)映射和 parameterType 屬性。 |
| flushCache | 將其設(shè)置為 true 后,只要語句被調(diào)用,都會(huì)導(dǎo)致本地緩存和二級(jí)緩存被清空,默認(rèn)值:(對(duì) insert、update 和 delete 語句)true。 |
| timeout | 這個(gè)設(shè)置是在拋出異常之前,驅(qū)動(dòng)程序等待數(shù)據(jù)庫(kù)返回請(qǐng)求結(jié)果的秒數(shù)。默認(rèn)值為未設(shè)置(unset)(依賴數(shù)據(jù)庫(kù)驅(qū)動(dòng))。 |
| statementType | 可選 STATEMENT,PREPARED 或 CALLABLE。這會(huì)讓 MyBatis 分別使用 Statement,PreparedStatement 或 CallableStatement,默認(rèn)值:PREPARED。 |
| useGeneratedKeys | (僅適用于 insert 和 update)這會(huì)令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法來取出由數(shù)據(jù)庫(kù)內(nèi)部生成的主鍵(比如:像 MySQL 和 SQL Server 這樣的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng)的自動(dòng)遞增字段),默認(rèn)值:false。 |
| keyProperty | (僅適用于 insert 和 update)指定能夠唯一識(shí)別對(duì)象的屬性,MyBatis 會(huì)使用 getGeneratedKeys 的返回值或 insert 語句的 selectKey 子元素設(shè)置它的值,默認(rèn)值:未設(shè)置(unset)。如果生成列不止一個(gè),可以用逗號(hào)分隔多個(gè)屬性名稱。 |
| keyColumn | (僅適用于 insert 和 update)設(shè)置生成鍵值在表中的列名,在某些數(shù)據(jù)庫(kù)(像 PostgreSQL)中,當(dāng)主鍵列不是表中的第一列的時(shí)候,是必須設(shè)置的。如果生成列不止一個(gè),可以用逗號(hào)分隔多個(gè)屬性名稱。 |
| databaseId | 如果配置了數(shù)據(jù)庫(kù)廠商標(biāo)識(shí)(databaseIdProvider),MyBatis 會(huì)加載所有不帶 databaseId 或匹配當(dāng)前 databaseId 的語句;如果帶和不帶的語句都有,則不帶的會(huì)被忽略。 |
selectKey
<selectKey keyProperty="id" resultType="int" order="BEFORE" statementType="PREPARED">
selectKey元素屬性
| 屬性 | 描述 |
|---|---|
| keyProperty | selectKey 語句結(jié)果應(yīng)該被設(shè)置到的目標(biāo)屬性。如果生成列不止一個(gè),可以用逗號(hào)分隔多個(gè)屬性名稱。 |
| keyColumn | 返回結(jié)果集中生成列屬性的列名。如果生成列不止一個(gè),可以用逗號(hào)分隔多個(gè)屬性名稱。 |
| resultType | 結(jié)果的類型。通常 MyBatis 可以推斷出來,但是為了更加準(zhǔn)確,寫上也不會(huì)有什么問題。MyBatis 允許將任何簡(jiǎn)單類型用作主鍵的類型,包括字符串。如果生成列不止一個(gè),則可以使用包含期望屬性的 Object 或 Map。 |
| order | 可以設(shè)置為 BEFORE 或 AFTER。如果設(shè)置為 BEFORE,那么它首先會(huì)生成主鍵,設(shè)置 keyProperty 再執(zhí)行插入語句。如果設(shè)置為 AFTER,那么先執(zhí)行插入語句,然后是 selectKey 中的語句 - 這和 Oracle 數(shù)據(jù)庫(kù)的行為相似,在插入語句內(nèi)部可能有嵌入索引調(diào)用。 |
| statementType | 和前面一樣,MyBatis 支持 STATEMENT,PREPARED 和 CALLABLE 類型的映射語句,分別代表 Statement, PreparedStatement 和 CallableStatement 類型。 |
到此這篇關(guān)于MyBatis中XML映射器的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)MyBatis XML映射器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot和前端聯(lián)動(dòng)實(shí)現(xiàn)存儲(chǔ)瀏覽記錄功能
這篇文章主要介紹了SpringBoot和前端聯(lián)動(dòng)實(shí)現(xiàn)存儲(chǔ)瀏覽記錄功能,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-01-01
Jedis操作Redis數(shù)據(jù)庫(kù)的方法
這篇文章主要為大家詳細(xì)介紹了Jedis操作Redis數(shù)據(jù)庫(kù)的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04
IDEA 如何控制編輯左側(cè)的功能圖標(biāo)ICON(操作步驟)
很多朋友被idea左側(cè)的圖標(biāo)不見了這一問題搞的焦頭爛額,不知道該怎么操作,今天小編就交大家如何控制編輯左側(cè)的功能圖標(biāo) ICON,文字內(nèi)容不多,主要通過兩張截圖給大家說明,感興趣的朋友一起看看吧2021-05-05
Java如何通過Socket同時(shí)發(fā)送文本和文件
這篇文章主要介紹了Java如何通過Socket同時(shí)發(fā)送文本和文件問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08
Redisson分布式信號(hào)量RSemaphore的使用超詳細(xì)講解
這篇文章主要介紹了Redisson分布式信號(hào)量RSemaphore的使用,基于Redis的Redisson的分布式信號(hào)量RSemaphore采用了與java.util.concurrent.Semaphore相似的接口和用法2023-02-02

