您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關MyBatis的知識點有哪些,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
初期的 MyBatis 是一個 XML 驅動的框架。配置信息是基于 XML 的,映射語句也是定義在 XML 中的。而在 MyBatis 3 中,提供了其它的配置方式。MyBatis 3 構建在全面且強大的基于 Java 語言的配置 API 之上。它是 XML 和注解配置的基礎。注解提供了一種簡單且低成本的方式來實現簡單的映射語句。
提示: Java 注解的表達能力和靈活性十分有限。盡管MyBatis團隊花了很多時間在調查、設計和試驗上,但最強大的 MyBatis 映射并不能用注解來構建。
經驗對于單表的操作使用注解更加便利,但是對于復雜的多表,使用注解模式就顯得難以維護建議使用XML。
常用注解
注解 | 用途 |
---|---|
@Insert | 新增 |
@Update | 更新 |
@Delete | 刪除 |
@Select | 查詢 |
@Result | 封裝結果集 |
@Results | 與@Result配合,封裝多個結果集 |
@One | 實現一對一結果集封裝 |
@Many | 實現一對多結果集封裝 |
以下的查詢案例和要求均和XML模式一致,只是將xml操作替換為注解操作
對于注解的查詢操作是不需要Mapper.xml配置文件的,因為sql的配置和結果映射都通過注解實現了
SqlMapConfig.xml更新
<mappers> <!-- 注解方式Mapper的信息已經在接口中使用功能注解實現,所以掃描接口解析注解獲取 --> <package name="com.zyj.mapper"/> </mappers>
對于基礎的單表新增、更新、查詢、刪除操作如下,sql語句和xml一致,這里不多介紹。
public interface UserMapper { // 新增 @Insert(value = "insert into user(id, username, `password`, birthday) values (#{id}, #{username}, #{password}, #{birthday})") void addUser(User user); // 更新 @Update(value = "update user set username = #{username}, `password` = #{password}, birthday = #{birthday} where id = #{id}") void updateUser(User user); // 查詢 @Select(value = "select * from user") List<User> selectAll(); // 刪除 @Delete(value = "delete from user where id = #{id}") void deleteUser(Integer id); }
執行過程:
1)執行@Select
標簽的sql語句。
2)執行@Results
標簽的語句封裝@Select
的查詢結果。
3)封裝結果的時候有一個屬性是user
,內部的one屬性關聯到了另外一個查詢結果。所以就會去UserMapper
中執行selectById
根據 column=uid
將 order
的uid
作為參數去查詢結果。
// 訂單一對一查詢 public interface OrdersMapper { // select * from orders o left join user u on o.uid = u.id @Results({ @Result(property = "id", column = "id"), @Result(property = "ordertime", column = "ordertime"), @Result(property = "total", column = "total"), @Result( javaType = User.class, property = "user", column = "uid", one = @One(select = "com.zyj.mapper.UserMapper.selectById")) }) @Select(value = "select * from orders") List<Order> findAllOrderAndUser(); }
// 用戶查詢 public interface UserMapper { @Select(value = "select * from user where id = #{id}") User selectById(Integer id); }
注解和標簽對應關系總結:
注解 | 標簽 |
---|---|
@Select | select |
@Results | resultMap |
@Result | id和<result |
@One | association |
執行過程:
1)執行@Select
標簽的sql語句。
2)執行@Results
標簽的語句封裝@Select
的查詢結果。
3)封裝結果的時候有一個屬性是orderList
,內部的Many屬性關聯到了另外一個查詢結果。所以就會去OrderMapper
中執行selectByUId
根據 column=id
將 User
的id
作為參數去查詢結果。
// 用戶查詢一對多 public interface UserMapper { // select * from user u left join orders o on u.id = o.uid; @Results({ @Result(property = "id", column = "id"), @Result(property = "username", column = "username"), @Result(property = "password", column = "password"), @Result(property = "birthday", column = "birthday"), @Result( property = "orderList", column = "id", javaType = List.class, many = @Many(select = "com.zyj.mapper.OrdersMapper.selectByUId") ) }) @Select(value = "select * from user") List<User> findAllUserAndOrder(); }
// 根據用戶id查詢用戶訂單 public interface OrdersMapper { // 根據用戶id返回查詢結果 @Select(value = "select * from orders where uid = #{uid}") List<Order> selectByUId(Integer uid); }
注解和標簽對應關系總結:
注解 | 標簽 |
---|---|
@Select | <select> |
@Results | <resultMap> |
@Result | <id>和<result> |
@Many | <collection> |
執行過程:
1)執行@Select
標簽的sql語句。
2)執行@Results
標簽的語句封裝@Select
的查詢結果。
3)封裝結果的時候有一個屬性是roleList
,內部的Many屬性關聯到了另外一個查詢結果。所以就會去RoleMapper
中執行selectByUserId
根據 column=id
將 User
的id
作為參數去查詢結果。
public interface UserMapper { // select * from user u left join sys_user_role ur on u.id = ur.userid left join sys_role r on ur.roleid = r.id; @Results({ @Result(property = "id", column = "id"), @Result(property = "username", column = "username"), @Result(property = "password", column = "password"), @Result(property = "birthday", column = "birthday"), @Result( property = "roleList", column = "id", javaType = List.class, many = @Many(select = "com.zyj.mapper.RoleMapper.selectByUserId") ) }) @Select(value = "select * from user") List<User> findAllUserAndRole(); }
// 根據用戶id查詢角色 public interface RoleMapper { @Select(value = "select r.* from sys_role r inner join sys_user_role ur on r.id = ur.roleid where userid = #{uid}") List<Role> selectByUserId(Integer uid); }
注解和標簽對應關系總結:
注解 | 標簽 |
---|---|
@Select | select |
@Results | resultMap |
@Result | id和result |
@Many | collection |
MyBatis提供的動態Sql標簽在注解模式中也是一樣適用,但是寫法和剛才的一對一、一對多、多對多 的查詢有所差異。作用和效果是一樣的。所以這里只給出一個案例即可。
@Update({"<script>", "update Author", " <set>", " <if test='username != null'>username=#{username},</if>", " <if test='password != null'>password=#{password},</if>", " <if test='email != null'>email=#{email},</if>", " <if test='bio != null'>bio=#{bio}</if>", " </set>", "where id=#{id}", "</script>"}) void updateAuthorValues(Author author);
如果想在注解的映射器接口中使用動態SQL,那么可以使用script元素。
Mybatis 使用到了兩種緩存:本地緩存(local cache)和二級緩存(second level cache)。 兩個緩存的關系如下圖:
每當一個新 session 被創建,MyBatis 就會創建一個與之相關聯的本地緩存。任何在 session 執行過的查詢結果都會被保存在本地緩存中,所以,當再次執行參數相同的相同查詢時,就不需要實際查詢數據庫了。本地緩存將會在做出修改、事務提交或回滾,以及關閉 session 時清空。
1)在同一個sqlSession中,對User用戶表根據id進行2次查詢,觀察控制臺的sql打印情況。
@Test public void test1(){ // 獲取一個sqlSession SqlSession sqlSession = sessionFactory.openSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); // 使用sqlSession執行第一次查詢 User u1 = userMapper.selectUserByUserId(1); System.out.println(u1); // 使用sqlSession執行第二次查詢 User u2 = userMapper.selectUserByUserId(1); System.out.println(u2); sqlSession.close(); }
2)在同一個sqlSession中,對User用戶表根據id進行2次查詢。但是,中間對查詢到的用戶執行Update更新操作,并提交事務,觀察控制臺的sql打印情況。
@Test public void test2(){ // 獲取一個sqlSession SqlSession sqlSession = sessionFactory.openSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); // 使用sqlSession執行第一次查詢 User u1 = userMapper.selectUserByUserId( 1 ); System.out.println(u1); // 第二次查詢之前執行更新操作并提交事務 u1.setSex("女"); userMapper.updateUserByUserId(u1); sqlSession.commit(); // 使用sqlSession執行第二次查詢 User u2 = userMapper.selectUserByUserId(1); System.out.println(u2); sqlSession.close(); }
總結:
1)第一次查詢用戶的時候,會在一級緩存中去查詢用戶信息,如果查詢不到就去數據庫中查詢。并將查詢到的結果更新到以及緩存中。
2)如果同一個SqlSession中執行了commit事務提交操作(增加、更新、刪除),那么就會清空SqlSession中的緩存信息,避免下次查詢的時候出現臟數據。
3)第二次查詢的時候同樣去一級緩存查詢,如果有值就獲取返回,如果沒有就查詢數據庫并添加到一級緩存中。
二級緩存和一級緩存原理類似,只不過緩存的級別更高而已。一級緩存針對sqlSession,但是二級緩存就針對Mapper文件。所以二級緩存可以被多個sqlSession共享。
二級緩存和一級緩存不一樣,一級緩存默認都是開啟的,二級緩存默認是關閉的。所以需要配置開啟。二級緩存的開啟需要配置2個地方。
總開關開啟二級緩存SqlMapConfig.xml配置文件開啟。
<!-- 二級緩存總開關 --> <settings> <setting name="cacheEnabled" value="true"/> </settings>
由于二級緩存是Mapper級別的緩存,所以可以針對單個Mapper配置是否需要開啟。
<!--對應的Mapper.xml開啟二級緩存。如:UserMapper.xml、OrderMapper.xml--> <cache></cache>
基于上訴流程測試二級緩存
@Test public` `void` `testTwoCache(){ // 獲取sqlSession SqlSession sqlSession1 = sessionFactory.openSession(); SqlSession sqlSession2 = sessionFactory.openSession(); SqlSession sqlSession3 = sessionFactory.openSession(); String statement = "com.zyj.UserMapper.selectById" ; UserMapper userMapper1 = sqlSession1.getMapper(UserMapper. class ); UserMapper userMapper2 = sqlSession2.getMapper(UserMapper. class ); UserMapper userMapper3 = sqlSession2.getMapper(UserMapper. class ); // 第一次執行查詢,結果會放入二級緩存中 User u1 = userMapper1.selectById( 1 ); System.out.println(u1); sqlSession1.close(); // 關閉第一個session // 執行更新操作,并提交 u1.setUsername("知春秋"); userMapper3.selectById(u1); sqlSession3.commit(); // 第二次查詢,由于更新操作導致二級緩存被更新,所以會重新查詢數據庫 User u2 = userMapper2.selectById( 1 ); System.out.println(u2); sqlSession2.close(); }
關于“MyBatis的知識點有哪些”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。