MyBatis小結

既然作了SpringMVC的小結,那就順便作個MyBatis的小結。java

 

MyBatis和Hibernate的執行流程差很少,都是加載配置文件 - 會話工廠建造器 - 會話工廠 - 會話 - 執行具體邏輯redis

Configuration->SqlSessionFactoryBuilder/SessionFactoryBuilder->SqlSessionFactory/SessionFactory->SqlSession/Sessionsql

且都有懶加載、一二級緩存。數據庫

但MyBatis沒有Hibernate那麼抽象,學習起來相對簡單。只須要從其自帶的文檔MyBatis-User-Guide中搞清楚幾個概念便可。配置等更是能夠直接從文檔中複製。緩存

 

和Hibernate相似,MyBatis的執行須要配置文件(Cfg文件)和映射文件(通常稱爲Mapper文件)。session

配置文件無需多說,就是MyBatis的執行環境參數設置。以下:數據結構

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <properties resource="db.properties" /><!--加載數據庫信息-->
    <typeAliases>
        <package name="cn.larry.mybatis.po" /><!--類型別名,批量處理-->
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC" /><!--事務管理器-->
            <dataSource type="POOLED"><!--數據源 || 鏈接池-->
                <property name="driver" value="${jdbc.driver}" />
                <property name="url" value="${jdbc.url}" />
                <property name="username" value="${jdbc.username}" />
                <property name="password" value="${jdbc.password}" />
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="cn/larry/mybatis/mapper/UserMapper.xml" /><!--加載單個映射文件-->
    </mappers>
</configuration>

 

映射文件,其實看樣例是最簡單的辦法:mybatis

<?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="test">

    <!-- 需求:根據id查詢用戶信息 -->
    <!--    id:惟一標識。 
     parameterType:參數類型,輸入映射的類型。
     resultType:返回結果類型,輸出映射的類型(老是對應表中一條記錄的類型)。
     #{}:佔位符,若是傳遞的是基本類型,{}內的名稱:任意。
     ${}:鏈接符,若是傳遞的是基本類型,{}內的名稱:value
--> <select id="queryUserById" parameterType="int" resultType="cn.larry.mybatis.po.User"> select * from user where id = #{id} </select> <!-- 根據username查詢用戶信息 --> <select id="queryUserListByUsername" parameterType="string" resultType="cn.larry.mybatis.po.User"> select * from user where username like '%${value}%' </select> <!-- 根據username查詢用戶信息 --> <select id="queryUserList" parameterType="string" resultType="cn.larry.mybatis.po.User"> select * from user </select> <!-- 添加用戶 --> <insert id="insertUser" parameterType="cn.larry.mybatis.po.User"> <selectKey keyProperty="id" resultType="int" order="AFTER"> select LAST_INSERT_ID() <!-- 插入後返回id,僅限於自增主鍵;select uuid()則能夠返回uuid類型的主鍵 --> </selectKey> insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address}) </insert> <!-- 更改用戶 --> <update id="updateUser" parameterType="cn.larry.mybatis.po.User"> update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id} </update> <!-- 刪除用戶--> <delete id="deleteUserById" parameterType="int"> delete from user where id=#{id} </delete> </mapper>

注意上面的標籤名,增刪改查的操做都有對應標籤(僅僅是爲了更好的辨識,本質上仍然是一堆SQL語句)。架構

另外,有人可能不理解鏈接符$的含意,其實模糊查詢那裏已經很明顯了。app

佔位符#是要做爲查詢的一個參數,獨立的參數;鏈接符$則能夠聯合已有的數據而後總體做爲一個參數。

你能夠寫成 '%${value}%',但不能寫成 '%#{value}%',由於#{value}是個獨立的參數,甚至無需引號。

至於標籤的屬性,看英文便可明白。

 

MyBatis的執行是直接調用映射文件中的標籤id:

 

User selectOne = sqlSession.selectOne("cn.larry.mybatis.mapper.UserMapper.queryUserById", 1); // 1是queryUserById須要的參數

 

傳統的Dao和DaoImpl是將SqlSessionFactory注入DaoImpl,經過接口方法調用映射文件中的標籤id,但這很麻煩,並且冗餘代碼太多。

@Override
public User queryUserById(int id) throws Exception {
    SqlSession session = sqlSessionFactory.openSession();
    User user = session.selectOne("test.queryUserById", id);
    return user;
}

 

因此Mybatis提供了另外一種實現方式:Mapper代理

 

這種方式只須要聲明接口,再編寫映射文件便可。

可是,它要求①接口名和映射文件名一致;②映射文件的namespace就是接口的全名稱(無擴展名);③接口方法要與映射文件中的標籤id一致。

<?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要和mapper的類全路徑名稱 -->
<mapper namespace="cn.larry.mybatis.mapper.UserMapper">

    <select id="queryAllUserList" resultType="user">
        SELECT * FROM USER
    </select>
    
</mapper>    
package cn.larry.mybatis.mapper;

import java.util.List;
import cn.larry.mybatis.po.User;

public interface UserMapper {
    public List<User> queryAllUserList();
}

具體調用:

UserMapper mapper = sqlSession.getMapper(UserMapper.class); // 指定Mapper對應的類(內部是JDK動態代理
List<User> queryAllUserList = mapper.queryAllUserList();

 

 

MyBatis提供了resultMap屬性,能夠將查詢的返回結果綁定到指定的屬性上。

其餘:

一對一:association。javaType。經過主鍵/id聯合。

一對多:collection。ofType。經過主鍵/id聯合。

多對多:由一對1、一對多嵌套聯合完成。

 

注意,標籤中使用extends="xxx_id",能夠繼承已有的mapper。
例如:Orders類中有User類還有OrdersDetail類,而一個mapper是查詢訂單和用戶的數據,另外一個mapper是查詢Orders、User以及OrdersDetail的數據,那麼後者能夠繼承前者,從而只須要添加對OrdersDetail的查詢便可。

 

延遲加載,就是按需加載,本質上就是將關聯的子查詢延後加載(未必是外鍵關聯的,同Hibernate)。默認關閉。
前提一:association或collection的內容能夠獨立出去,再使用select屬性引入,column屬性是關聯的外鍵。
前提二:settings配置。<setting name="lazyLoadingEnabled" value="true"/>  (查找方法:直接查找標籤對應的類,查找其中的屬性)(全部標籤都對應某個類)
上面是標籤實現。


mybatis的緩存
一級緩存,sqlSession級別的緩存,會話級別的緩存。語句和參數都相同。若是執行了commit操做,清空緩存。一級緩存的數據結構hashmap。(數據庫也有緩存)
二級緩存,mapper級別的緩存。只針對單表。重點:序列化。一級緩存始終開啓;二級緩存能夠設置開啓關閉。(cacheEnabled)想使用二級緩存,<cache></cache>便可。見說明。但,因爲一二級緩存都是mybatis的緩存,有侷限性,因此一般在分佈式架構中使用第三方緩存,如ehcache、redis、memcache等。ehcache1.7後,爲集羣提供了五種解決方案,rmi、jms、ehcache server、jgroups、terracotta。rmi不存在主從。若使用第三方緩存,緩存須要實現mybatis提供的Cache接口。加入jar包,設置配置文件,以及<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>便可。

相關文章
相關標籤/搜索