下載:https://github.com/mybatis/mybatis-3/releasesjava
Mybatis是apache下的頂級項目。mysql
MyBatis是一個優秀的持久層框架,它對jdbc的操做數據庫的過程進行封裝,使開發者只須要關注 SQL 自己,而不須要花費精力去處理例如註冊驅動、建立connection、建立statement、手動設置參數、結果集檢索等jdbc繁雜的過程代碼。git
Mybatis經過xml或註解的方式將要執行的各類statement(statement、preparedStatemnt、CallableStatement)配置起來,並經過java對象和statement中的sql進行映射生成最終執行的sql語句,最後由mybatis框架執行sql並將結果映射成java對象並返回。程序員
經過mybatis提供的映射方式,自由靈活生成知足須要的sql語句。github
向preparedStatement中輸入參數自動進行輸入映射,將查詢結果集靈活映射成java對象。spring
SqlMapConfig.xml: <?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> <!-- 和spring整合後 environments配置將廢除--> <environments default="development"> <environment id="development"> <!-- 使用jdbc事務管理--> <transactionManager type="JDBC" /> <!-- 數據庫鏈接池--> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" /> <property name="username" value="root" /> <property name="password" value="mysql" /> </dataSource> </environment> </environments> <mappers> <mapper resource="sqlmap/User.xml"/> </mappers> </configuration>
將參數配置在properties中,只須要在SqlMapConfig.xml中加載properties,不須要硬編碼,好比db.propertiessql
<properites resource="db.properties"> <property name="age" value="18"/> </properties>
properties 元素體內的屬性優先被加載,例如:age數據庫
例:apache
<!-- 經過properites加載 -->
<properties resource="db.properties" />
<!-- 和spring整合後 environments配置將廢除-->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事務管理-->
<transactionManager type="JDBC" />
<!-- 數據庫鏈接池-->
<dataSource type="POOLED">
<property name="driver" value="${mysql.Driver}" />
<property name="url" value="${mysql.url}" />
<property name="username" value="${mysql.user}" />
<property name="password" value="${mysql.password}" />
</dataSource>
</environment>
</environments>
mybatis全局配置參數,全局參數將會影響mybatis的運行行爲。spring-mvc
Setting(設置) |
Description(描述) |
Valid Values(驗證值組) |
Default(默認值) |
cacheEnabled |
在全局範圍內啓用或禁用緩存配置任何映射器在此配置下。 |
true | false |
TRUE |
lazyLoadingEnabled |
在全局範圍內啓用或禁用延遲加載。禁用時,全部協會將熱加載。 |
true | false |
TRUE |
aggressiveLazyLoading |
啓用時,有延遲加載屬性的對象將被徹底加載後調用懶惰的任何屬性。不然,每個屬性是按需加載。 |
true | false |
TRUE |
multipleResultSetsEnabled |
容許或不容許從一個單獨的語句(須要兼容的驅動程序)要返回多個結果集。 |
true | false |
TRUE |
useColumnLabel |
使用列標籤,而不是列名。在這方面,不一樣的驅動有不一樣的行爲。參考驅動文檔或測試兩種方法來決定你的驅動程序的行爲如何。 |
true | false |
TRUE |
useGeneratedKeys |
容許JDBC支持生成的密鑰。兼容的驅動程序是必需的。此設置強制生成的鍵被使用,若是設置爲true,一些驅動會不兼容性,但仍然能夠工做。 |
true | false |
FALSE |
autoMappingBehavior |
指定MyBatis的應如何自動映射列到字段/屬性。NONE自動映射。 PARTIAL只會自動映射結果沒有嵌套結果映射定義裏面。 FULL會自動映射的結果映射任何複雜的(包含嵌套或其餘)。 |
NONE, PARTIAL, FULL |
PARTIAL |
defaultExecutorType |
配置默認執行人。SIMPLE執行人確實沒有什麼特別的。 REUSE執行器重用準備好的語句。 BATCH執行器重用語句和批處理更新。 |
SIMPLE REUSE BATCH |
SIMPLE |
defaultStatementTimeout |
設置驅動程序等待一個數據庫響應的秒數。 |
Any positive integer |
Not Set (null) |
safeRowBoundsEnabled |
容許使用嵌套的語句RowBounds。 |
true | false |
FALSE |
mapUnderscoreToCamelCase |
從經典的數據庫列名A_COLUMN啓用自動映射到駱駝標識的經典的Java屬性名aColumn。 |
true | false |
FALSE |
localCacheScope |
MyBatis的使用本地緩存,以防止循環引用,並加快反覆嵌套查詢。默認狀況下(SESSION)會話期間執行的全部查詢緩存。若是localCacheScope=STATMENT本地會話將被用於語句的執行,只是沒有將數據共享之間的兩個不一樣的調用相同的SqlSession。 |
SESSION | STATEMENT |
SESSION |
dbcTypeForNull |
指定爲空值時,沒有特定的JDBC類型的參數的JDBC類型。有些驅動須要指定列的JDBC類型,但其餘像NULL,VARCHAR或OTHER的工做與通用值。 |
JdbcType enumeration. Most common are: NULL, VARCHAR and OTHER |
OTHER |
lazyLoadTriggerMethods |
指定觸發延遲加載的對象的方法。 |
A method name list separated by commas |
equals,clone,hashCode,toString |
defaultScriptingLanguage |
指定所使用的語言默認爲動態SQL生成。 |
A type alias or fully qualified class name. |
org.apache.ibatis.scripting.xmltags.XMLDynamicLanguageDriver |
callSettersOnNulls |
指定若是setter方法或地圖的put方法時,將調用檢索到的值是null。它是有用的,當你依靠Map.keySet()或null初始化。注意原語(如整型,布爾等)不會被設置爲null。 |
true | false |
FALSE |
logPrefix |
指定的前綴字串,MyBatis將會增長記錄器的名稱。 |
Any String |
Not set |
logImpl |
指定MyBatis的日誌實現使用。若是此設置是不存在的記錄的實施將自動查找。 |
SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING |
Not set |
proxyFactory |
指定代理工具,MyBatis將會使用建立懶加載能力的對象。 |
CGLIB | JAVASSIST |
<settings> <!-- 打開延遲加載開關 全局性設置懶加載。若是設爲‘false’,則全部相關聯的都會被初始化加載。 --> <setting name="lazyLoadingEnabled" value="true"/> <!-- 將積極加載改成消極加載(按需加載) 當設置爲‘true’的時候,懶加載的對象可能被任何懶屬性所有加載。不然,每一個屬性都按需加載。 --> <setting name="aggressiveLazyLoading" value="false"/> <!-- 開啓二級緩存 對在此配置文件下的全部cache 進行全局性開/關設置。 --> <setting name="cacheEnabled" value="true"/> </settings>
別名 映射的類型
_byte byte
_long long
_short short
_int int
_integer int
_double double
_float float
_boolean boolean
string String
byte Byte
long Long
short Short
int Integer
integer Integer
double Double
float Float
boolean Boolean
date Date
decimal BigDecimal
bigdecimal BigDecimal
自定義別名
<typeAliases> <!-- 單個別名定義 --> <typeAlias alias="user" type="cn.kai.mybatis.po.User"/> <!-- 批量別名定義,掃描整個包下的類,別名爲類名(首字母大寫或小寫均可以) --> <package name="cn.kai.mybatis.po"/> <package name="其它包"/> ... </typeAliases>
類型處理器用於java類型和jdbc類型映射
<select id="findUserById" parameterType="int" resultType="user"> select * from user where id = #{id} </select>
mybatis自帶的類型處理器基本上知足平常需求,不須要單獨定義。
如IntegerTypeHandler,BooleanTypeHandler ....
<mapper resource="sqlmap/User.xml" />
<mapper url="file:///E:\workspace\newJavaSpace\mybatis\cofnig\sqlmap\User.xml" />
<mapper class="cn.kai.mybatis.mapper.UserMapper"/> 此種方法要求mapper接口名稱和mapper映射文件名稱相同,且放在同一個目錄中(xxxMapper.xml和xxxMapper.java要在同一個目錄)。
<package name="cn.kai.mybatis.mapper"/> 此種方法要求mapper接口名稱和mapper映射文件名稱相同,且放在同一個目錄中
UserMapper.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="cn.kai.mybatis.mapper.UserMapper"> <select id="findUserById" parameterType="int" resultType="cn.kai.mybatis.po.User"> select * from user where id = #{id} </select> </mapper>
parameterType="int"
parameterType="user" 或 parameterType="cn.kai.mybatis.po.User"
public class ItemsQueryVo {
private Items items;
parameterType="hashmap"
where id=#{id}
map.put("id", 1);
map.put("username", "管理員");
只有查出來的列名和pojo中的屬性名一致,才能夠映射成功
輸出簡單類型:resultType="int"
輸出pojo對象:resultType="user"
輸出pojo列表:resultType="user"
輸出pojo對象和輸出pojo列表在sql中定義的resultType是同樣的。
返回單個pojo對象要保證sql查詢出來的結果集爲單條,內部使用session.selectOne方法調用,mapper接口使用pojo對象做爲方法返回值。
返回pojo列表表示查詢出來的結果集可能爲多條,內部使用session.selectList方法,mapper接口使用List<pojo>對象做爲方法返回值。
輸出hashmap:輸出pojo對象能夠改用hashmap輸出類型,將輸出的字段名稱做爲map的key,value爲字段值。
若是resultMap在其餘的mapper文件引用,前邊須要加namespace
<?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"> <!-- namespace命名空間,做用對sql進行分類化管理 --> <mapper namespace="cn.kai.mybatis.mapper.OrdersMapps"> <!-- 根據訂單查詢用戶信息resultmap --> <resultMap type="cn.kai.mybatis.po.Orders" id="OrdersUserResultMap"> <!-- orders信息 --> <id column="id" property="id"/> <result column="user_id" property="userId"/> <result column="number" property="number"/> <result column="createtime" property="createtime"/> <result column="note" property="note"/> <!-- user信息 --> <association property="user" javaType="cn.kai.mybatis.po.User"> <id column="user_id" property="id"/> <result column="username" property="username"/> <result column="sex" property="sex"/> <result column="birthday" property="birthday"/> <result column="address" property="address"/> </association> </resultMap> <resultMap type="cn.kai.mybatis.po.Orders" id="OrdersOrderdetailResultMap" extends="OrdersUserResultMap"> <!-- orders信息 --> <!-- user信息 --> <!-- 訂單詳情信息 --> <collection property="orderdetails" ofType="cn.kai.mybatis.po.Orderdetail"> <id column="orderdetail_id" property="id"/> <result column="items_id" property="itemsId"/> <result column="items_num" property="itemsNum"/> <result column="orders_id" property="ordersId"/> </collection> </resultMap> <!-- 根據訂單查詢用戶信息 --> <select id="findOrdersUserResultMap" resultMap="OrdersUserResultMap"> SELECT a.*, b.`username`, b.`sex`, b.`birthday`, b.`address` FROM orders a, USER b WHERE a.`user_id` = b.`id` </select> <!-- 根據訂單查詢訂單詳情 --> <select id="findOrdersOrderdetailResultMap" resultMap="OrdersOrderdetailResultMap"> SELECT a.*, b.`username`, b.`sex`, b.`birthday`, b.`address` , c.`id` orderdetail_id, c.`items_id`, c.`items_num`, c.`orders_id` FROM orders a, USER b, orderdetail c WHERE a.`user_id` = b.`id` AND c.`orders_id` = a.`id` </select> <!-- 查詢用戶和購買商品信息ResultMap --> <resultMap type="cn.kai.mybatis.po.User" id="UserAndItemsResultMap"> <id column="user_id" property="id"/> <result column="username" property="username"/> <result column="sex" property="sex"/> <result column="birthday" property="birthday"/> <result column="address" property="address"/> <!-- ordersList信息 --> <collection property="ordersList" ofType="cn.kai.mybatis.po.Orders"> <id column="id" property="id"/> <result column="user_id" property="userId"/> <result column="number" property="number"/> <result column="createtime" property="createtime"/> <result column="note" property="note"/> <collection property="orderdetails" ofType="cn.kai.mybatis.po.Orderdetail"> <id column="orderdetail_id" property="id"/> <result column="items_id" property="itemsId"/> <result column="items_num" property="itemsNum"/> <result column="orders_id" property="ordersId"/> <association property="items" javaType="cn.kai.mybatis.po.Items"> <id column="items_id" property="id"/> <result column="items_name" property="name"/> <result column="items_price" property="price"/> </association> </collection> </collection> </resultMap> <!-- 查詢用戶和購買商品信息 --> <select id="findUserAndItems" resultMap="UserAndItemsResultMap"> SELECT a.*, b.`username`, b.`sex`, b.`birthday`, b.`address` , c.`id` orderdetail_id, c.`items_id`, c.`items_num`, c.`orders_id`, d.`name` items_name, d.`price` items_price FROM orders a, USER b, orderdetail c, items d WHERE a.`user_id` = b.`id` AND c.`orders_id` = a.`id` AND c.`items_id` = d.`id` </select> <!-- 查詢訂單信息,延遲加載用戶信息ResultMap --> <resultMap type="cn.kai.mybatis.po.Orders" id="OrderLazyLogingUserResultMap"> <!-- orders信息 --> <id column="id" property="id"/> <result column="user_id" property="userId"/> <result column="number" property="number"/> <result column="createtime" property="createtime"/> <result column="note" property="note"/> <!-- 延遲加載用戶信息 --> <association property="user" javaType="cn.kai.mybatis.po.User" select="cn.kai.mybatis.mapper.UserMapper.findUserById" column="user_id" fetchType="lazy"> </association> </resultMap> <!-- 查詢訂單信息,延遲加載用戶信息 --> <select id="findOrderLazyLodingUser" resultMap="OrderLazyLogingUserResultMap"> SELECT * FROM orders </select> <!-- 根據userId查詢訂單信息 --> <select id="findOrdersByUserId" parameterType="int" resultType="cn.kai.mybatis.po.Orders" > SELECT * FROM orders WHERE user_id = #{user_id} </select> <!-- 查詢用戶信息,延遲加載訂單信息 ResultMap --> <resultMap type="cn.kai.mybatis.po.User" id="UserLazyLodingOrdersResultMap"> <id column="id" property="id"/> <result column="username" property="username"/> <result column="sex" property="sex"/> <result column="birthday" property="birthday"/> <result column="address" property="address"/> <!-- 延遲加載訂單信息 --> <collection property="ordersList" ofType="cn.kai.mybatis.po.Orders" select="findOrdersByUserId" column="id" fetchType="lazy"> </collection> </resultMap> <!-- 查詢用戶信息,延遲加載訂單信息 --> <select id="findUserLazyLodingOrders" resultMap="UserLazyLodingOrdersResultMap"> SELECT * FROM USER </select> </mapper>
使用註解來映射簡單語句:
public interface BlogMapper { @Select("SELECT * FROM blog WHERE id = #{id}") Blog selectBlog(int id); }
<select id="findUserList" parameterType="user" resultType="user"> select * from user where 1=1 <if test="id!=null and id!=''"> and id=#{id} </if> <if test="username!=null and username!=''"> and username like '%${username}%' </if> </select>
<where />能夠自動處理第一個and,不用擔憂會多一個and
<select id="findUserList" parameterType="user" resultType="user"> select * from user <where> <if test="id!=null and id!=''"> and id=#{id} </if> <if test="username!=null and username!=''"> and username like '%${username}%' </if> </where> </select>
Sql中可將重複的sql提取出來,使用時用include引用便可,最終達到sql重用的目的
<sql id="query_user_where"> <if test="id!=null and id!=''"> and id=#{id} </if> <if test="username!=null and username!=''"> and username like '%${username}%' </if> </sql> <select id="findUserList" parameterType="user" resultType="user"> select * from user <where> <include refid="query_user_where"/> </where> </select>
若是引用其它mapper.xml的sql片斷,則在引用時須要加上namespace,以下:
<include refid="namespace.sql片斷」/>
全局配置文件,配置了數據源,事務等
mapper.xml
SqlSession線程不安全,最好放在方法體內建立
建立SqlSession:操做數據庫(發出sql增、刪、改、查)
//mybatis配置文件 String resource = "SqlMapConfig.xml"; InputStream inputStream; inputStream = Resources.getResourceAsStream(resource); //建立會話工廠 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //經過工廠獲得SqlSession sqlSession = sqlSessionFactory.openSession();
是一個接口(基本執行器,緩存執行器)
SqlSession內部經過執行器操做數據庫
對操做數據庫存儲封裝、包括sql語句,輸入參數、輸出結果類型
輸入參數類型:java簡單類型、hashmap,pojo自定義類型
#{} ${}:
使用佔位符#{}能夠有效防止sql注入
#{}能夠接收簡單類型值或pojo屬性值,若是parameterType傳輸單個簡單類型值,#{}括號中能夠是value或其它名稱。
${}和#{}不一樣,經過${}能夠將parameterType 傳入的內容拼接在sql中且不進行jdbc類型轉換, ${}能夠接收簡單類型值或pojo屬性值,若是parameterType傳輸單個簡單類型值,${}括號中只能是value。
使用${}不能防止sql注入
當須要查詢關聯信息時再去數據庫查詢,默認不去關聯查詢,提升數據庫性能。
只有使用resultMap支持延遲加載設置。
方法1、
<!-- setting:mybatis全局配置參數,全局參數將會影響mybatis的運行行爲。 -->
<settings>
<!-- 打開延遲加載開關
全局性設置懶加載。若是設爲‘false’,則全部相關聯的都會被初始化加載。
-->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 將積極加載改成消極加載(按需加載)
當設置爲‘true’的時候,懶加載的對象可能被任何懶屬性所有加載。不然,每一個屬性都按需加載。
-->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
方法2、用fetchType="lazy" 設置單個延遲加載
<!-- 延遲加載用戶信息 -->
<association property="user" javaType="cn.kai.mybatis.po.User"
select="cn.kai.mybatis.mapper.UserMapper.findUserById" column="user_id" fetchType="lazy">
</association>
<!-- 查詢訂單信息,延遲加載用戶信息 --> <select id="findOrderLazyLodingUser" resultMap="OrderLazyLogingUserResultMap"> SELECT * FROM orders </select> <!-- 查詢訂單信息,延遲加載用戶信息ResultMap --> <resultMap type="cn.kai.mybatis.po.Orders" id="OrderLazyLogingUserResultMap"> <!-- orders信息 --> <id column="id" property="id"/> <result column="user_id" property="userId"/> <result column="number" property="number"/> <result column="createtime" property="createtime"/> <result column="note" property="note"/> <!-- 延遲加載用戶信息 --> <association property="user" javaType="cn.kai.mybatis.po.User" select="cn.kai.mybatis.mapper.UserMapper.findUserById" column="user_id" fetchType="lazy"> </association> </resultMap> List<Orders> list = ordersMapps.findOrderLazyLodingUser(); for(Orders order: list) { //調用getUser時延遲加載查詢數據庫 User user = order.getUser(); System.out.println(user); }
一級緩存是SqlSession級別的緩存。在操做數據庫時須要構造 sqlSession對象,在對象中有一個數據結構(HashMap)用於存儲緩存數據。不一樣的sqlSession之間的緩存數據區域(HashMap)是互相不影響的。
若是sqlSession去執行commit操做(執行插入、更新、刪除),清空SqlSession中的一級緩存,這樣作的目的爲了讓緩存中存儲的是最新的信息,避免髒讀。
若是緩存中有數據就不用從數據庫中獲取,大大提升系統性能。
二級緩存區域是根據mapper的namespace劃分的,相同namespace的mapper查詢數據放在同一個區域,若是使用mapper代理方法每一個mapper的namespace都不一樣,此時能夠理解爲二級緩存區域是根據mapper劃分。
每次查詢會先從緩存區域找,若是找不到從數據庫查詢,查詢到數據將數據寫入緩存。
Mybatis內部存儲緩存使用一個HashMap,key爲hashCode+sqlId+Sql語句。value爲從查詢出來映射生成的java對象
sqlSession執行insert、update、delete等操做commit提交後會清空緩存區域。
開啓二級緩存:
1.在覈心配置文件SqlMapConfig.xml中加入
<setting name="cacheEnabled" value="true"/>
2.要在你的Mapper映射文件中添加一行: <cache /> ,表示此mapper開啓二級緩存。
二級緩存須要查詢結果映射的pojo對象實現java.io.Serializable接口實現序列化和反序列化操做,注意若是存在父類、成員pojo都須要實現序列化接口。
public class Orders implements Serializable
public class User implements Serializable
禁用二級緩存:
<select ... useCache="false">
每次查詢都會發出sql去查詢
刷新緩存:
在mapper的同一個namespace中,若是有其它insert、update、delete操做數據後須要刷新緩存,若是不執行刷新緩存會出現髒讀。
設置statement配置中的flushCache="true" 屬性,默認狀況下爲true即刷新緩存,若是改爲false則不會刷新。使用緩存時若是手動修改數據庫表中的查詢數據會出現髒讀。
以下:
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User" flushCache="true">
flushInterval(刷新間隔)
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
這個更高級的配置建立了一個 FIFO 緩存,並每隔 60 秒刷新,存數結果對象或列表的 512 個引用,並且返回的對象被認爲是隻讀的,所以在不一樣線程中的調用者之間修改它們會致使衝突。可用的收回策略有, 默認的是 LRU:
1.LRU – 最近最少使用的:移除最長時間不被使用的對象。
2.FIFO – 先進先出:按對象進入緩存的順序來移除它們。
3.SOFT – 軟引用:移除基於垃圾回收器狀態和軟引用規則的對象。
4.WEAK – 弱引用:更積極地移除基於垃圾收集器狀態和弱引用規則的對象。
爲了提升系統併發,性能、通常對系統進行分佈式部署,不使用分佈緩存,緩存的數據在各各服務單獨存儲,不方便系統開發。因此要使用分佈式緩存對緩存數據進行集中管理。
mybatis沒法實現分佈式緩存,須要和其它分佈式緩存框架進行整合。
mybatis提供了一個cache接口,若是要實現本身的緩存邏輯,實現cache接口開發便可。
mybatis和ehcache整合,mybatis和ehcache整合包中提供了一個cache接口的實現類。
mybatis默認實現cache類PerpetualCache
整合方法:
1. 加入ehcache包
2. 緩存配置文件ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd"> <diskStore path="F:\develop\ehcache" /> <defaultCache maxElementsInMemory="1000" maxElementsOnDisk="10000000" eternal="false" overflowToDisk="false" timeToIdleSeconds="120" timeToLiveSeconds="120" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"> </defaultCache> </ehcache>
屬性說明:
diskStore:指定數據在磁盤中的存儲位置。
defaultCache:當藉助CacheManager.add("demoCache")建立Cache時,EhCache便會採用<defalutCache/>指定的的管理策略
如下屬性是必須的:
maxElementsInMemory - 在內存中緩存的element的最大數目
maxElementsOnDisk - 在磁盤上緩存的element的最大數目,如果0表示無窮大
eternal - 設定緩存的elements是否永遠不過時。若是爲true,則緩存的數據始終有效,若是爲false那麼還要根據timeToIdleSeconds,timeToLiveSeconds判斷
overflowToDisk - 設定當內存緩存溢出的時候是否將過時的element緩存到磁盤上
如下屬性是可選的:
timeToIdleSeconds - 當緩存在EhCache中的數據先後兩次訪問的時間超過timeToIdleSeconds的屬性取值時,這些數據便會刪除,默認值是0,也就是可閒置時間無窮大
timeToLiveSeconds - 緩存element的有效生命期,默認是0.,也就是element存活時間無窮大
diskSpoolBufferSizeMB 這個參數設置DiskStore(磁盤緩存)的緩存區大小.默認是30MB.每一個Cache都應該有本身的一個緩衝區.
diskPersistent - 在VM重啓的時候是否啓用磁盤保存EhCache中的數據,默認是false。
diskExpiryThreadIntervalSeconds - 磁盤緩存的清理線程運行間隔,默認是120秒。每一個120s,相應的線程會進行一次EhCache中數據的清理工做
memoryStoreEvictionPolicy - 當內存緩存達到最大,有新的element加入的時候, 移除緩存中element的策略。默認是LRU(最近最少使用),可選的有LFU(最不常使用)和FIFO(先進先出)
3. 開啓ehcache緩存
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
根據需求調整緩存參數:
<cache type="org.mybatis.caches.ehcache.EhcacheCache" > <property name="timeToIdleSeconds" value="3600"/> <property name="timeToLiveSeconds" value="3600"/> <!-- 同ehcache參數maxElementsInMemory --> <property name="maxEntriesLocalHeap" value="1000"/> <!-- 同ehcache參數maxElementsOnDisk --> <property name="maxEntriesLocalDisk" value="10000000"/> <property name="memoryStoreEvictionPolicy" value="LRU"/> </cache>
須要spring經過單例方式管理SqlSessionFactory。
spring和mybatis整合生成代理對象,使用SqlSessionFactory建立SqlSession。(spring和mybatis整合自動完成)
持久層的mapper都須要由spring進行管理。
Jar包:
mybatis3.2.7的jar包
spring3.2.0的jar包
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd "> <!-- 加載配置文件 --> <context:property-placeholder location="classpath:db.properties"/> <!-- dbcp數據源 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${mysql.Driver}"/> <property name="url" value="${mysql.url}" /> <property name="username" value="${mysql.user}"/> <property name="password" value="${mysql.password}"/> </bean> <!-- oracle數據源 --> <!-- <bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource" destroy-method="close"> <property name="serviceName" value="${mysql.Driver}"/> <property name="url" value="${mysql.url}" /> <property name="user" value="${mysql.user}"/> <property name="password" value="${mysql.password}"/> </bean> --> <!-- sqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 配置數據源 --> <property name="dataSource" ref="dataSource"/> <!-- 配置mybatis配置文件 --> <property name="configLocation" value="./mybatis/SqlMapConfig.xml"/> </bean> <bean id="userDao" class="cn.kai.sm.dao.impl.UserDaoImpl"> <property name="sqlSessionFactory" ref="sqlSessionFactory"/> </bean> <bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> <!-- 設置mapper接口 --> <property name="mapperInterface" value="cn.kai.sm.mapper.UserMapper"/> <property name="sqlSessionFactory" ref="sqlSessionFactory"/> </bean> </beans>
1)dao的實現須要繼承SqlSessionDaoSupport:
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao { @Override public User findUserById(int id) throws Exception { SqlSession sqlSession = getSqlSession(); return sqlSession.selectOne("userMapper.findUserById", id); } }
2)加載bean
<!-- dao的實現的方法加載userbean -->
<bean id="userDao" class="cn.kai.sm.dao.impl.UserDaoImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
3)測試
private ApplicationContext applicationContext; @Before public void setUp() throws Exception{ applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); } @Test public void testFindUserById() throws Exception { UserDao userdao = (UserDao) applicationContext.getBean("userDao"); User user = userdao.findUserById(29); System.out.println(user); }
1)<!-- 經過mapper的方法加載userbean -->
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<!-- 設置mapper接口 -->
<property name="mapperInterface" value="cn.kai.sm.mapper.UserMapper"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
2)<!-- 批量掃描mapper加載userbean -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 要掃描的包,多個包名用,隔開 -->
<property name="basePackage" value="cn.kai.sm.mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
3)測試
UserMapper userMapper = (UserMapper) applicationContext.getBean("userMapper"); User user = userMapper.findUserById(29); System.out.println(user);
mybaits須要程序員本身編寫sql語句,mybatis官方提供逆向工程 能夠針對單表自動生成mybatis執行所須要的代碼(mapper.java,mapper.xml、po..)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <context id="testTables" targetRuntime="MyBatis3"> <commentGenerator> <!-- 是否去除自動生成的註釋 true:是 : false:否 --> <property name="suppressAllComments" value="true" /> </commentGenerator> <!--數據庫鏈接的信息:驅動類、鏈接地址、用戶名、密碼 --> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/mybatis" userId="root" password="chenkai123"> </jdbcConnection> <!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver" connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:yycg" userId="yycg" password="yycg"> </jdbcConnection> --> <!-- 默認false,把JDBC DECIMAL 和 NUMERIC 類型解析爲 Integer,爲 true時把JDBC DECIMAL 和 NUMERIC 類型解析爲java.math.BigDecimal --> <javaTypeResolver> <property name="forceBigDecimals" value="false" /> </javaTypeResolver> <!-- targetProject:生成PO類的位置 --> <javaModelGenerator targetPackage="cn.kai.sm.bean" targetProject=".\src"> <!-- enableSubPackages:是否讓schema做爲包的後綴 --> <property name="enableSubPackages" value="false" /> <!-- 從數據庫返回的值被清理先後的空格 --> <property name="trimStrings" value="true" /> </javaModelGenerator> <!-- targetProject:mapper映射文件生成的位置 --> <sqlMapGenerator targetPackage="cn.kai.sm.mapper" targetProject=".\src"> <!-- enableSubPackages:是否讓schema做爲包的後綴 --> <property name="enableSubPackages" value="false" /> </sqlMapGenerator> <!-- targetPackage:mapper接口生成的位置 --> <javaClientGenerator type="XMLMAPPER" targetPackage="cn.kai.sm.mapper" targetProject=".\src"> <!-- enableSubPackages:是否讓schema做爲包的後綴 --> <property name="enableSubPackages" value="false" /> </javaClientGenerator> <!-- 指定數據庫表 --> <table tableName="items"></table> <table tableName="orders"></table> <table tableName="orderdetail"></table> <table tableName="user"></table> </context> </generatorConfiguration>
public class GeneratorSqlmap { public void generator() throws Exception{ List<String> warnings = new ArrayList<String>(); boolean overwrite = true; //指定 逆向工程配置文件 File configFile = new File("generatorConfig.xml"); ConfigurationParser cp = new ConfigurationParser(warnings); Configuration config = cp.parseConfiguration(configFile); DefaultShellCallback callback = new DefaultShellCallback(overwrite); MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings); myBatisGenerator.generate(null); } public static void main(String[] args) throws Exception { try { GeneratorSqlmap generatorSqlmap = new GeneratorSqlmap(); generatorSqlmap.generator(); } catch (Exception e) { e.printStackTrace(); } } }