MyBatis中XML映射器的實(shí)現(xiàn)
XML映射器
MyBatis 的真正強(qiáng)大在于它的語句映射,這是它的魔力所在。由于它的異常強(qiáng)大,映射器的 XML 文件就顯得相對簡單。如果拿它跟具有相同功能的 JDBC 代碼進(jìn)行對比,你會立即發(fā)現(xiàn)省掉了將近 95% 的代碼。MyBatis 致力于減少使用成本,讓用戶能更專注于 SQL 代碼。
SQL 映射文件只有很少的幾個頂級元素(按照應(yīng)被定義的順序列出):
cache
– 該命名空間的緩存配置。cache-ref
– 引用其它命名空間的緩存配置。resultMap
– 描述如何從數(shù)據(jù)庫結(jié)果集中加載對象,是最復(fù)雜也是最強(qiáng)大的元素。parameterMap
– 老式風(fēng)格的參數(shù)映射。此元素已被廢棄,并可能在將來被移除!請使用行內(nèi)參數(shù)映射。文檔中不會介紹此元素。sql
– 可被其它語句引用的可重用語句塊。insert
– 映射插入語句。update
– 映射更新語句。delete
– 映射刪除語句。select
– 映射查詢語句。
CRUD操作
select
查詢語句是 MyBatis 中最常用的元素之一——光能把數(shù)據(jù)存到數(shù)據(jù)庫中價(jià)值并不大,還要能重新取出來才有用,多數(shù)應(yīng)用也都是查詢比修改要頻繁。 MyBatis 的基本原則之一是:在每個插入、更新或刪除操作之間,通常會執(zhí)行多個查詢操作。因此,MyBatis 在查詢和結(jié)果映射做了相當(dāng)多的改進(jìn)。一個簡單查詢的 select 元素是非常簡單的。
根據(jù)id查詢用戶
public interface UserMapper { //查詢user表數(shù)據(jù) List<User> selectUser(); //根據(jù)id查詢用戶 User selectUserById(int id); }
UserMapper.xml
<!-- id : 與mapper層的接口做映射 parameterType : 參數(shù)類型 resultType : 返回的類型對象 --> <select id="selectUserById" resultType="com.sin.pojo.User" parameterType="int"> select * from user where id = #{id} </select>
#{id}
告訴 MyBatis 創(chuàng)建一個預(yù)處理語句(PreparedStatement)參數(shù),在 JDBC 中,這樣的一個參數(shù)在 SQL 中會由一個“?”來標(biāo)識,并被傳遞到一個新的預(yù)處理語句中,
類似于
// 近似的 JDBC 代碼,非 MyBatis 代碼... String selectPerson = "SELECT * FROM PERSON WHERE ID=?"; PreparedStatement ps = conn.prepareStatement(selectPerson); ps.setInt(1,id);
測試用例
@Test public void selectUserById(){ SqlSession session = MyBatisUtil.getSession(); UserMapper mapper = session.getMapper(UserMapper.class); System.out.println(mapper.selectUserById(2)); }
根據(jù)名字和密碼查詢
方法一:使用對象
UserMapper.java
- 參數(shù)傳入對象
//根據(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>
測試用例
@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>
測試用例
@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語句編寫的時候,直接取
@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>
測試用例
@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)識符,可以被用來引用這條語句。 |
parameterType | 將會傳入這條語句的參數(shù)的類全限定名或別名。這個屬性是可選的,因?yàn)?MyBatis 可以通過類型處理器(TypeHandler)推斷出具體傳入語句的參數(shù),默認(rèn)值為未設(shè)置(unset)。 |
parameterMap | 用于引用外部 parameterMap 的屬性,目前已被廢棄。請使用行內(nèi)參數(shù)映射和 parameterType 屬性。 |
resultType | 期望從這條語句中返回結(jié)果的類全限定名或別名。 注意,如果返回的是集合,那應(yīng)該設(shè)置為集合包含的類型,而不是集合本身的類型。 resultType 和 resultMap 之間只能同時使用一個。 |
resultMap | 對外部 resultMap 的命名引用。結(jié)果映射是 MyBatis 最強(qiáng)大的特性,如果你對其理解透徹,許多復(fù)雜的映射問題都能迎刃而解。 resultType 和 resultMap 之間只能同時使用一個。 |
flushCache | 將其設(shè)置為 true 后,只要語句被調(diào)用,都會導(dǎo)致本地緩存和二級緩存被清空,默認(rèn)值:false。 |
useCache | 將其設(shè)置為 true 后,將會導(dǎo)致本條語句的結(jié)果被二級緩存緩存起來,默認(rèn)值:對 select 元素為 true。 |
timeout | 這個設(shè)置是在拋出異常之前,驅(qū)動程序等待數(shù)據(jù)庫返回請求結(jié)果的秒數(shù)。默認(rèn)值為未設(shè)置(unset)(依賴數(shù)據(jù)庫驅(qū)動)。 |
fetchSize | 這是一個給驅(qū)動的建議值,嘗試讓驅(qū)動程序每次批量返回的結(jié)果行數(shù)等于這個設(shè)置值。 默認(rèn)值為未設(shè)置(unset)(依賴驅(qū)動)。 |
statementType | 可選 STATEMENT,PREPARED 或 CALLABLE。這會讓 MyBatis 分別使用 Statement,PreparedStatement 或 CallableStatement,默認(rèn)值:PREPARED。 |
resultSetType | FORWARD_ONLY,SCROLL_SENSITIVE, SCROLL_INSENSITIVE 或 DEFAULT(等價(jià)于 unset) 中的一個,默認(rèn)值為 unset (依賴數(shù)據(jù)庫驅(qū)動)。 |
databaseId | 如果配置了數(shù)據(jù)庫廠商標(biāo)識(databaseIdProvider),MyBatis 會加載所有不帶 databaseId 或匹配當(dāng)前 databaseId 的語句;如果帶和不帶的語句都有,則不帶的會被忽略。 |
resultOrdered | 這個設(shè)置僅針對嵌套結(jié)果 select 語句:如果為 true,則假設(shè)結(jié)果集以正確順序(排序后)執(zhí)行映射,當(dāng)返回新的主結(jié)果行時,將不再發(fā)生對以前結(jié)果行的引用。 這樣可以減少內(nèi)存消耗。默認(rèn)值:false。 |
resultSets | 這個設(shè)置僅適用于多結(jié)果集的情況。它將列出語句執(zhí)行后返回的結(jié)果集并賦予每個結(jié)果集一個名稱,多個名稱之間以逗號分隔。 |
insert
給數(shù)據(jù)庫增加一個用戶
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>
測試用例
@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)!不寫的話不會提交到數(shù)據(jù)庫 }
update
修改用戶的信息
UserMapper.java
//修改一個用戶 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>
測試用例
@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刪除一個用戶
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>
測試用例
@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)識符,可以被用來引用這條語句。 |
parameterType | 將會傳入這條語句的參數(shù)的類全限定名或別名。這個屬性是可選的,因?yàn)?MyBatis 可以通過類型處理器(TypeHandler)推斷出具體傳入語句的參數(shù),默認(rèn)值為未設(shè)置(unset)。 |
parameterMap | 用于引用外部 parameterMap 的屬性,目前已被廢棄。請使用行內(nèi)參數(shù)映射和 parameterType 屬性。 |
flushCache | 將其設(shè)置為 true 后,只要語句被調(diào)用,都會導(dǎo)致本地緩存和二級緩存被清空,默認(rèn)值:(對 insert、update 和 delete 語句)true。 |
timeout | 這個設(shè)置是在拋出異常之前,驅(qū)動程序等待數(shù)據(jù)庫返回請求結(jié)果的秒數(shù)。默認(rèn)值為未設(shè)置(unset)(依賴數(shù)據(jù)庫驅(qū)動)。 |
statementType | 可選 STATEMENT,PREPARED 或 CALLABLE。這會讓 MyBatis 分別使用 Statement,PreparedStatement 或 CallableStatement,默認(rèn)值:PREPARED。 |
useGeneratedKeys | (僅適用于 insert 和 update)這會令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法來取出由數(shù)據(jù)庫內(nèi)部生成的主鍵(比如:像 MySQL 和 SQL Server 這樣的關(guān)系型數(shù)據(jù)庫管理系統(tǒng)的自動遞增字段),默認(rèn)值:false。 |
keyProperty | (僅適用于 insert 和 update)指定能夠唯一識別對象的屬性,MyBatis 會使用 getGeneratedKeys 的返回值或 insert 語句的 selectKey 子元素設(shè)置它的值,默認(rèn)值:未設(shè)置(unset)。如果生成列不止一個,可以用逗號分隔多個屬性名稱。 |
keyColumn | (僅適用于 insert 和 update)設(shè)置生成鍵值在表中的列名,在某些數(shù)據(jù)庫(像 PostgreSQL)中,當(dāng)主鍵列不是表中的第一列的時候,是必須設(shè)置的。如果生成列不止一個,可以用逗號分隔多個屬性名稱。 |
databaseId | 如果配置了數(shù)據(jù)庫廠商標(biāo)識(databaseIdProvider),MyBatis 會加載所有不帶 databaseId 或匹配當(dāng)前 databaseId 的語句;如果帶和不帶的語句都有,則不帶的會被忽略。 |
selectKey
<selectKey keyProperty="id" resultType="int" order="BEFORE" statementType="PREPARED">
selectKey元素屬性
屬性 | 描述 |
---|---|
keyProperty | selectKey 語句結(jié)果應(yīng)該被設(shè)置到的目標(biāo)屬性。如果生成列不止一個,可以用逗號分隔多個屬性名稱。 |
keyColumn | 返回結(jié)果集中生成列屬性的列名。如果生成列不止一個,可以用逗號分隔多個屬性名稱。 |
resultType | 結(jié)果的類型。通常 MyBatis 可以推斷出來,但是為了更加準(zhǔn)確,寫上也不會有什么問題。MyBatis 允許將任何簡單類型用作主鍵的類型,包括字符串。如果生成列不止一個,則可以使用包含期望屬性的 Object 或 Map。 |
order | 可以設(shè)置為 BEFORE 或 AFTER。如果設(shè)置為 BEFORE,那么它首先會生成主鍵,設(shè)置 keyProperty 再執(zhí)行插入語句。如果設(shè)置為 AFTER,那么先執(zhí)行插入語句,然后是 selectKey 中的語句 - 這和 Oracle 數(shù)據(jù)庫的行為相似,在插入語句內(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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot實(shí)現(xiàn)PPT格式文件上傳并在線預(yù)覽功能
本文介紹SpringBoot實(shí)現(xiàn)PPT格式文件上傳并在線預(yù)覽功能,通過上傳接口,可在C盤的tempfile目錄下找到上傳的文件,預(yù)覽時會在同級目錄下創(chuàng)建一個相同文件名后綴為pdf的文件,每次預(yù)覽會先查找文件是否存在,存在則直接預(yù)覽,不存在則會走上面的處理,需要的朋友可以參考下2022-02-02SpringBoot下載文件的實(shí)現(xiàn)及速度對比
這篇文章主要介紹了SpringBoot下載文件的實(shí)現(xiàn)及速度對比,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12Java調(diào)用Oss JDk實(shí)現(xiàn)刪除指定目錄下的所有文件
這篇文章主要為大家詳細(xì)介紹了Java如何調(diào)用Oss JDk實(shí)現(xiàn)刪除指定目錄下的所有文件功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2025-03-03SpringBoot使用Thymeleaf自定義標(biāo)簽的實(shí)例代碼
這篇文章主要介紹了SpringBoot使用Thymeleaf自定義標(biāo)簽的實(shí)例代碼,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09MySQL?MyBatis?默認(rèn)插入當(dāng)前時間方式
這篇文章主要介紹了MySQL?MyBatis?默認(rèn)插入當(dāng)前時間方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10解決SpringBoot整合MybatisPlus分模塊管理遇到的bug
這篇文章主要介紹了解決SpringBoot整合MybatisPlus分模塊管理遇到的bug,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07