下载: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(); } } }