Mybatis学习笔记

第一章 Mybatis介绍

  下载:https://github.com/mybatis/mybatis-3/releasesjava

  Mybatisapache下的顶级项目。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>

 

 

2.1. Properties

将参数配置在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>

 

 

 

 

 

2.2.Settings

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>

2.3.typeAliases

别名 映射的类型

_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>

 

2.4.typeHandlers(类型处理器)

 

类型处理器用于java类型和jdbc类型映射

<select id="findUserById" parameterType="int" resultType="user">
        select * from user where id = #{id}
</select>

mybatis自带的类型处理器基本上知足平常需求,不须要单独定义。

如IntegerTypeHandler,BooleanTypeHandler ....

 

2.5.mappers(映射器)

 

2.5.1 使用相对于类路径的资源

<mapper resource="sqlmap/User.xml" />

2.5.2 使用彻底限定路径

<mapper url="file:///E:\workspace\newJavaSpace\mybatis\cofnig\sqlmap\User.xml" />

 

2.5.3 使用mapper接口类路径

 

<mapper class="cn.kai.mybatis.mapper.UserMapper"/>
此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中(xxxMapper.xml和xxxMapper.java要在同一个目录)。

 

 

2.5.3 注册指定包下的全部mapper接口

 

<package name="cn.kai.mybatis.mapper"/>
此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中

 

第三章 Mapper.xml映射文件

 

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>

 

 

3.1 parameterType(输入类型)

 

3.1.1 传递简单类型

parameterType="int"

 

3.1.2 传递pojo对象

 

parameterType="user"  parameterType="cn.kai.mybatis.po.User"

 

3.1.3 传递pojo包装对象

 

public class ItemsQueryVo {

 

private Items items;

 

3.1.4 传递hashmap

parameterType="hashmap"

where id=#{id}

map.put("id", 1);

map.put("username", "管理员");

 

3.2 resultType(输出类型)

 

只有查出来的列名和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输出类型,将输出的字段名称做为mapkeyvalue为字段值。

 

3.3 resultMap

若是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>

 

 

第四章 mapper接口

 

  1. mapper.xmlnamespace就是mapper.java的类全路径
  2. Mapper接口方法名和Mapper.xml中定义的statementid相同
  3. Mapper接口方法的输入参数类型和mapper.xml中定义的statementparameterType的类型相同
  4. Mapper接口方法的输出参数类型和mapper.xml中定义的statementresultType的类型相同

 

  使用注解来映射简单语句

  

public interface BlogMapper {
  @Select("SELECT * FROM blog WHERE id = #{id}")
  Blog selectBlog(int id);
}

 

第五章 动态sql

5.1. If

<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>

5.2. Where

<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>

5.3 foreach

5.4 Sql片断

 

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.xmlsql片断,则在引用时须要加上namespace,以下:

<include refid="namespace.sql片断”/>

 

 

第六章 mybatis框架

 

 

6.1. SqlMapConfig.xml文件名字不固定

 

全局配置文件,配置了数据源,事务等

 

6.2. 配置映射文件(配置sql语句)

 

mapper.xml

 

6.3. SqlSessionFactory

SqlSession线程不安全,最好放在方法体内建立

 

建立SqlSession:操做数据库(发出sql增、删、改、查)

//mybatis配置文件
            String resource = "SqlMapConfig.xml";
            
            InputStream inputStream;
            inputStream = Resources.getResourceAsStream(resource);
            //建立会话工厂
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            
            //经过工厂获得SqlSession
            sqlSession = sqlSessionFactory.openSession();

 

6.4. Exection(执行器)

 

是一个接口(基本执行器,缓存执行器)

 

SqlSession内部经过执行器操做数据库

 

6.5. Mapped statement(底层封装对象)

 

对操做数据库存储封装、包括sql语句,输入参数、输出结果类型

 

输入参数类型:java简单类型、hashmappojo自定义类型

 

#{}   ${}:

 

使用占位符#{}能够有效防止sql注入

 

#{}能够接收简单类型值或pojo属性值,若是parameterType传输单个简单类型值,#{}括号中能够是value或其它名称。

 

${}和#{}不一样,经过${}能够将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, ${}能够接收简单类型值或pojo属性值,若是parameterType传输单个简单类型值,${}括号中只能是value。

 

使用${}不能防止sql注入

 

第七章 延迟加载

当须要查询关联信息时再去数据库查询,默认不去关联查询,提升数据库性能。

只有使用resultMap支持延迟加载设置。

 

7.1. 打开延迟开关

 

方法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>

 

7.2. 实例

<!-- 查询订单信息,延迟加载用户信息 -->
    <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);
            }

 

 

第八章 查询缓存

8.1. 一级缓存

一级缓存是SqlSession级别的缓存。在操做数据库时须要构造 sqlSession对象,在对象中有一个数据结构(HashMap)用于存储缓存数据。不一样的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。

若是sqlSession去执行commit操做(执行插入、更新、删除),清空SqlSession中的一级缓存,这样作的目的为了让缓存中存储的是最新的信息,避免脏读。

若是缓存中有数据就不用从数据库中获取,大大提升系统性能。

 

 

 

 

 

8.2. 二级缓存

 

二级缓存区域是根据mappernamespace划分的,相同namespacemapper查询数据放在同一个区域,若是使用mapper代理方法每一个mappernamespace都不一样,此时能够理解为二级缓存区域是根据mapper划分。

 

每次查询会先从缓存区域找,若是找不到从数据库查询,查询到数据将数据写入缓存。

 

Mybatis内部存储缓存使用一个HashMapkeyhashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象

 

sqlSession执行insertupdatedelete等操做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中,若是有其它insertupdatedelete操做数据后须要刷新缓存,若是不执行刷新缓存会出现脏读。

 

 

 

 设置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 – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

 

 

 

 

 

 

 

8.3. mybatis整合ehcache

 

为了提升系统并发,性能、通常对系统进行分布式部署,不使用分布缓存,缓存的数据在各各服务单独存储,不方便系统开发。因此要使用分布式缓存对缓存数据进行集中管理。

 

mybatis没法实现分布式缓存,须要和其它分布式缓存框架进行整合。

 

 

 

mybatis提供了一个cache接口,若是要实现本身的缓存逻辑,实现cache接口开发便可。

 

mybatisehcache整合,mybatisehcache整合包中提供了一个cache接口的实现类。

 

mybatis默认实现cachePerpetualCache

 

 

 

整合方法

  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那么还要根据timeToIdleSecondstimeToLiveSeconds判断

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>

 

第九章 mybatis spring整合

 

须要spring经过单例方式管理SqlSessionFactory

 

springmybatis整合生成代理对象,使用SqlSessionFactory建立SqlSession。(springmybatis整合自动完成)

 

持久层的mapper都须要由spring进行管理。

 

 

 

Jar包:

 

mybatis3.2.7jar

 

spring3.2.0jar

 

9.1. Spring配置文件applicationContext.xml

 

<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>

 

9.2. daodao的实现

 

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);
    }

 

9.3. 使用mapper实现

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.xmlpo..

 

<?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();
        }
        
    }

}
相关文章
相关标签/搜索