MyBatis 实践 -配置

MyBatis 实践

标签: Java与存储


Configuration

mybatis-configuration.xml是MyBatis的全局配置文件(文件名称随意),其配置内容和顺序例如以下:

  1. properties : 属性(文件)载入/配置
  2. settings : 全局配置參数
  3. typeAliases : 定义类型别名
  4. typeHandlers : 类型处理器
  5. objectFactory : 对象工厂
  6. plugins : 插件
  7. environments : 环境集合属性对象
    • environment
      • transactionManager : 事务管理
      • dataSource : 数据源
  8. databaseIdProvider:P数据库厂商标识
  9. mappers : 映射器

properties

方便对配置參数统一管理,供其它XML引用,我们能够将数据库的连接參数抽取出来:

  • db.properties
## Data Source
mysql.driver.class=com.mysql.jdbc.Driver
mysql.url=jdbc:mysql://host:port/db?characterEncoding=utf-8
mysql.user=user
mysql.password=password
  • mybatis-configuration.xml
<properties resource="db.properties"/><environments default="development"><environment id="development"><!-- 配置JDBC事务管理--><transactionManager type="JDBC"/><!-- 配置数据源--><dataSource type="POOLED"><property name="driver" value="${mysql.driver.class}"/><property name="url" value="${mysql.url}"/><property name="username" value="${mysql.user}"/><property name="password" value="${mysql.password}"/></dataSource></environment>
</environments>

注: MyBatis依照例如以下顺序载入properties:
1) 在<properties>标签内定义的属性;
2) .properties文件里定义的属性;
3) 最后读取作为方法參数传递的属性.


settings

MyBatis全局配置參数,会影响MyBatis执行时行为(如:开启二级缓存/延迟载入).见MyBatis文档.


typeAliases

MyBatis默认支持的类型别名可參考MyBatis文档,我们也能够自己定义别名,但并不推荐,使用PO对象的全限定名能够提高Statement的可读性.


typeHandlers

typeHandlers用于Java类型和JDBC类型转换,MyBatis提供了非常多默认的类型处理器(详见MyBatis文档),并且也基本满足日常开发需求,因此一般就不再须要单独定义.


mappers

前面已经将SQL语句定义到了mapper文件里,那么<mappers/>属性就是告诉MyBatis到哪里去寻找mapper文件,MyBatis提供了例如以下几种配置方法:

配置描写叙述
<mapper resource=""/>使用类路径的资源(Resources/java文件夹下)
<mapper url=""/>使用全然限定路径
<mapper class=""/>使用mapper接口类路径
<package name=""/>注冊指定包下的全部mapper接口

注意:后两种方式要求mapper接口名和mapper映射文件名称称同样,且放在同一个文件夹中(不推荐).

其它关于MyBatis的配置信息可參考MyBatis文档.


整合Spring

实现MyBatis与Spring整合之后,能够使用Spring来管理SqlSessionFactory和mapper接口,Spring自己主动使用SqlSessionFactory创建SqlSession,并将实现好DAO接口注冊到Spring容器中, 供@Autowired使用.


1. 加入依赖

  • 加入Spring支持
<dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${spring.version}</version>
</dependency>
<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version>
</dependency>
<dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>${spring.version}</version>
</dependency>
<dependency><groupId>org.springframework</groupId><artifactId>spring-expression</artifactId><version>${spring.version}</version>
</dependency>
<dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>${spring.version}</version>
</dependency>
<dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>${spring.version}</version>
</dependency>
<dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>${spring.version}</version>
</dependency>
<dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>${spring.version}</version>
</dependency>
  • 加入MyBatis-Spring包
<dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>${mybatis-spring.version}</version>
</dependency>
  • 加入Hikaricp数据库连接池
<dependency><groupId>com.zaxxer</groupId><artifactId>HikariCP</artifactId><version>${hikaricp.version}</version>
</dependency>
  • 不要忘了MySQL数据库驱动
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version>
</dependency>

2. 配置文件

  • 精简mybatis-configuration.xml
    能够将数据源的配置移到以下的applicationContext-datasource.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><mappers><mapper resource="mybatis/mapper/UserDAO.xml"/></mappers>
</configuration>
  • 定义applicationContext-datasource.xml
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><context:property-placeholder location="classpath:db.properties"/><!-- 配置数据源 --><bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig"><property name="driverClassName" value="${mysql.driver.class}"/><property name="jdbcUrl" value="${mysql.url}"/><property name="username" value="${mysql.user}"/><property name="password" value="${mysql.password}"/><property name="maximumPoolSize" value="5"/><property name="maxLifetime" value="700000"/><property name="idleTimeout" value="600000"/><property name="connectionTimeout" value="10000"/><property name="dataSourceProperties"><props><prop key="dataSourceClassName">com.mysql.jdbc.jdbc2.optional.MysqlDataSource</prop><prop key="cachePrepStmts">true</prop><prop key="prepStmtCacheSize">250</prop><prop key="prepStmtCacheSqlLimit">2048</prop></props></property></bean><bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close"><constructor-arg ref="hikariConfig"/></bean><!-- 配置SqlSessionFactory --><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"/><property name="configLocation" value="classpath:mybatis/mybatis-configuration.xml"/></bean><!-- 依据mapper接口生成代理对象 --><bean id="dao" class="org.mybatis.spring.mapper.MapperFactoryBean"><property name="mapperInterface" value="com.fq.mybatis.UserDAO"/><property name="sqlSessionFactory" ref="sqlSessionFactory"/></bean>
</beans>

上面的配置存在一个问题:须要针对每一个mapper配置一个MapperFactoryBean(繁琐),因此这段依据mapper接口生成代理对象的配置可更改例如以下:

<!-- 基于包扫描的mapper配置 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.fq.mybatis"/><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>

附: applicationContext-database.xml完整配置可參考: Git地址

  • 定义Spring主配置文件applicationContext.xml
    定义注解驱动载入静态配置文件datasource:
<?

xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 注解驱动 --> <context:annotation-config/> <!-- 载入静态配置文件 --> <import resource="applicationContext-datasource.xml"/> </beans>
  • Client
/*** @author jifang* @since 16/2/22 上午10:20.*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring/applicationContext.xml")
public class UserDAOClient {@Autowiredprivate UserDAO dao;@Testpublic void client() throws Exception {User user = dao.selectUserById(1);System.out.println(user);}
}

缓存

与大多数持久层框架一样,MyBatis也支持一级缓存二级缓存.

缓存作用是提升系统总体性能(不是提升数据库性能:由于缓存将数据库中的数据存放到内存,下次查询同样内容时直接从内存读取,减轻数据库压力,并且直接从内存中读取数据要比从数据库检索快非常多,因此能够提升系统总体性能).

缓存数据更新:当一个作用域(一级缓存为SqlSession/二级缓存为namespace)进行了C/U/D操作后,默认该作用域下全部缓存都被清空.


一级缓存

MyBatis默认开启了一级缓存.一级缓存是基于org.apache.ibatis.cache.impl.PerpetualCacheHashMap本地缓存,其存储作用域为SqlSession,同一个SqlSession几次执行同样SQL,后面的查询会直接从缓存中载入,从而提高查询效率/减轻数据库压力.当SqlSessionflush/close后,该SqlSession中的全部Cache数据被清空.


二级缓存

与一级缓存机制相似,MyBatis二级缓存默认也是採用PerpetualCacheHashMap存储,不同在于二级缓存存储作用域为namespace/mapper,并且能够自己定义缓存实现,如Ehcache.

MyBatis默认没有开启二级缓存,须要经过以下步骤才干使用:

  • 启用二级缓存(可选)
    其须要在mybatis-configuration.xml的settings全局參数中开启:
<settings><setting name="cacheEnabled" value="true"/>
</settings>

cacheEnabled对此配置文件下的全部cache进行全局性开/关设置(默觉得true).

  • 配置缓存策略
    在mapper映射文件里加入<cache/>标签,以指定该namespace开启二级缓存, 并指定缓存策略:
<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>

1) eviction:缓存淘汰算法:

算法描写叙述释义
LRU近期最少使用移除最长时间不被使用的对象(默认).
FIFO先进先出按对象进入缓存的顺序移除.
SOFT软引用移除基于垃圾回收器状态和软引用规则的对象.
WEAK弱引用更积极地移除基于垃圾收集器状态和弱引用规则的对象.

2) flushInterval:刷新间隔(缓存过期时间),单位为毫秒,MyBatis会每隔一段时间自己主动清空缓存(默认刷新间隔为空, 即永只是期,仅调用语句时刷新).
3) size:引用数目,要记住你缓存的对象的数目和执行环境可用内存资源数目(默认1024).
4) readOnly: 仅仅读.假设为true,则全部同样SQL返回同一对象(因此这些对象不能改动,有助于提高性能,但并发操作同一条数据时,可能不安全);假设为false,则同样SQL后面返回的是cache的clone副本(通过序列化,慢一些但更是安全,因此默认是false).

  • 序列化
    PO对象要实现Serializable序列化,由于二级缓存的存储介质不一定仅仅是内存:
public class User implements Serializable {//...
}
  • Client
@Test
public void cacheClient() throws Exception {testCache(factory.openSession());testCache(factory.openSession());testCache(factory.openSession());
}private void testCache(SqlSession session) throws Exception {UserDAO dao = session.getMapper(UserDAO.class);dao.selectUserById(1);// 须要将SqlSession关闭才干将数据写入缓存.session.close();
}

执行代码, 并观察log输出的命中率(Cache Hit Ratio).

  • Statement配置

1) 禁用缓存: 在Statement中设置useCache="false"能够禁用当前select语句的二级缓存(默觉得true:该SQL启用二级缓存).

<select id="selectUserById" parameterType="java.lang.Integer" resultType="com.fq.domain.User" useCache="true">SELECT *FROM userWHERE id = #{id};
</select>

2)刷新缓存: 同一个namespace中,假设还有其它insert/update/delete操作,须要刷新缓存,使用flushCache="true"属性设置(默觉得true刷新缓存).

<insert id="insertUserList" parameterType="java.util.List" flushCache="true">INSERT INTO user(name, password) VALUES<if test="list != null and list.size != 0"><foreach collection="list" item="user" separator=",">(#{user.name}, #{user.password})</foreach></if>
</insert>

整合Ehcache

MyBatis暴露一个org.apache.ibatis.cache.Cache接口出来,通过实现该接口,能够实现各类缓存产品(如Ehcache/Redis/Memcached)与MyBatis的整合(MyBatis的特长操作数据库,缓存管理并非其擅长,因此整合其它缓存产品能够提高系统总体性能).
Ehcache是一个纯Java开发的进程内缓存框架,具有开源/高速/灵活等特点,是Hibernate默认的CacheProvider.使用Ehcache须要在pom.xml中加入例如以下依赖:

<dependency><groupId>net.sf.ehcache</groupId><artifactId>ehcache-core</artifactId><version>2.6.11</version>
</dependency>
<dependency><groupId>org.mybatis.caches</groupId><artifactId>mybatis-ehcache</artifactId><version>1.0.3</version>
</dependency>
  • 配置Ehcache
    在Resources文件夹下加入ehcache.xml配置文件
<ehcache><diskStore path="/data/cache"/><defaultCache
            maxElementsInMemory="1000"maxElementsOnDisk="10000000"eternal="false"overflowToDisk="false"timeToIdleSeconds="120"timeToLiveSeconds="120"diskExpiryThreadIntervalSeconds="120"memoryStoreEvictionPolicy="LRU"></defaultCache>
</ehcache>
属性描写叙述
diskStore指定缓存数据在磁盘的存储位置
maxElementsInMemory在内存中缓存element的最大数目
maxElementsOnDisk在磁盘上缓存element的最大数目,0表示无穷大
eternal设定缓存的elements是否永远只是期.true,则缓存的数据始终有效,假设为false那么还要依据timeToIdleSeconds,timeToLiveSeconds推断
overflowToDisk设定当内存缓存溢出的时候是否将过期的element缓存到磁盘上
timeToIdleSeconds刷新间隔:缓存数据前后两次訪问时间超过timeToIdleSeconds时,这些数据便会删除(默觉得0,时间间隔无穷大)
timeToLiveSeconds缓存element的有效生命期(默觉得0,时间无限)
diskSpoolBufferSizeMB设置DiskStore(磁盘缓存)缓存区大小.默认是30MB.
diskPersistent在JVM重新启动时是否使用磁盘保存Ehcache数据,默认是false.
diskExpiryThreadIntervalSeconds磁盘缓存的清理线程执行间隔,默认是120秒.
memoryStoreEvictionPolicy当内存缓存达到最大,有新的element加入的时候, 移除缓存中element的策略.默认是LRU(近期最少使用),可选的有LFU(最不常使用)和FIFO(先进先出)
  • mapper配置ehcache
<cache type="org.mybatis.caches.ehcache.EhcacheCache" eviction="LRU" flushInterval="60000" size="1024"readOnly="true"/>

还能够依据需求调整当前namespace的缓存參数:

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

二级缓存小结

  • 适用场景
    对于查询请求多对查询结果实时性要求不高的场景,可採用二级缓存减少数据库负担,提高訪问速度(业务场景如:微博/动态/订单信息等).
  • 局限
    二级缓存对细粒度级别的缓存实现不好,如”缓存全部的商品信息时,二级缓存就无法实现当一个商品信息变化时仅仅刷新该商品缓存而不刷新全部商品缓存“,由于二级缓存区域以namespace为单位划分,当一个商品发生变化会将全部商品缓存清空,因此解决此类问题须要在上层对数据进行业务划分.

转载于:https://www.cnblogs.com/jhcelue/p/7142311.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/254070.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DM365视频处理流程/DM368 NAND Flash启动揭秘

DM365的视频处理涉及到三个相关处理器&#xff0c;分别是视频采集芯片、ARM处理器和视频图像协处理器&#xff08;VICP&#xff09;&#xff0c;整个处理流程由ARM核协调。视频处理主要涉及三个处理流程&#xff0c;分别是视频采集、视频编码和对编码后的视频的处理&#xff0c…

系统的Drawable(四)-LayerListDrawable

系统的Drawable(四)-LayerListDrawable 学习自 https://blog.csdn.net/u014695188/article/details/52815444 LayerListDrawable 漫谈 使用layer-list可以将多个drawable按照顺序层叠在一起显示&#xff0c;默认情况下&#xff0c;所有的item中的drawable都会自动根据它附上vie…

图像处理:镜头频率(衍射极限) 和 相机采样:显微镜的采样定理

采样定理大家都知道&#xff0c;相信不用多说。 我自己写下来给自己看。 下面&#xff0c;我总结 大家平时照相的镜头或者显微镜的物镜的情况下&#xff1a; 采样频率是指图像在数字化的时候的过程&#xff0c;实际上就是我们相机感光元件CCD或者CMOS的一个个小像元把模拟的连续…

【练习】使用事务控制语句

1.使用show engines 命令确定系统中是否有任何事务存储引擎可用以及哪个是默认引擎。 2.使用set autocommit 语句启用autocommit。 3.为使用world数据库做准备&#xff0c;确认city表使用事务存储引擎innodb。 4.使用start transaction 语句显式启动新事务。 5.删除一行。 6.使…

老男孩Day1作业(一):编写登录接口

要求&#xff1a;编写登录接口 1. 输入用户名和密码 2. 认证成功后显示欢迎信息 3. 输错三次后锁定 1&#xff09;编写思路 编写思路参考下面GitHub链接中的流程图 https://github.com/ChuixinZeng/PythonStudyCode/blob/master/PythonCode-OldBoy/Day1/作业/Day1_作业_登录接口…

hashcat源码分析1

typedef struct hash{void *digest;salt_t *salt;void *esalt;void *hook_salt; // additional salt info only used by the hook (host)int cracked;hashinfo_t *hash_info;char *pw_buf;int pw_len;} hash_t;一.1. 信号 函数&a…

Davinci及U-boot的一些介绍

TI推出的数字多媒体平台DM系列&#xff0c;集成了ARM与DSP双核处理器&#xff1a;DSP处理器运行DSP/BIOS操作系统&#xff0c;负责音视频编解码算法以及其他图形处理算法&#xff1b;ARM处理器运行MontaVista Linux操作系统&#xff0c;负责设备初始化、用户图形界面管理。ARM处…

像素越多越好?像元的面积越小越好?为何底大一级压死人?

像素越多越好&#xff1f;像素点的面积越小越好&#xff1f;为何底大一级压死人&#xff1f; 像素是&#xff1a;图像最小单元的数量&#xff0c;例如6000*4000&#xff0c;像素数量就是24*10^6。 像素太少当然图像就看不见了&#xff0c;看不清晰了。 但是现在几乎所有手机和相…

设计模式(5)--工厂模式

//5.工厂模式 //ver1 //回顾简单工厂模式 class OperationFactory { public:static Operation createOperation(char chOper){Operation * op NULL;switch(chOper){case :op new OperationAdd();break;case -:op new OperationSub();break;default:break;}return *op;} };vo…

对于多属性类型系统的数据库设计

主要是以下几类系统: 生活信息系统, 内容:小, 属性:大,电商商品系统, 内容:大, 属性:大,风控征信系统, 内容:小, 属性:大,新闻系统, 内容:大, 属性:小,这些系统共同的特点, 都是在主体内容上会携带多个属性, 并且属性需要随时能调整, 并且要求能兼容旧属性, 还需要频繁的通过属…

linux环境部署常用命令

1.  查看当前所属目录&#xff1a;pwd2.  回到上级目录&#xff1a;cd ../回到上两级目录&#xff1a;cd ../ ../3.  查看当前目录下有哪些文件&#xff1a;ls4.  查看最后100行日志&#xff1a;tail -100 catalina.out动态重看操作日志&#xff1a;tail -f catalina.o…

DM6446开发攻略:V4L2视频驱动和应用分析

针对DAVINCI DM6446平台&#xff0c;网络上也有很多网友写了V4L2的驱动&#xff0c;但只是解析Montavistalinux-2.6.10 V4L2的原理、结构和函数&#xff0c;深度不够。本文决定把Montavista 的Linux-2.6.18 V4L2好好分析一下&#xff0c;顺便讲解在产品中的应用&#xff0c;满足…

相机像素尺寸(像元大小)和成像系统分辨率之间的关系

相机像素尺寸&#xff08;像元大小&#xff09;和成像系统分辨率之间的关系 在显微成像系统中&#xff0c;常常会用分辨率来评价其成像能力的好坏。这里的分辨率通常是指光学系统的极限分辨率以及成像探测器的图像分辨率。最终图像所呈现出的实际分辨率&#xff0c;取决于二者的…

H5网页播放器播不了服务器上的mp4视频文件

打开IIS&#xff0c;在功能视图里找到MIME类型菜单&#xff0c;打开该菜单后鼠标右键添加.mp4扩展名的MIME类型video/mp4 其他视频文件播放不了估计也得在IIS里添加对应的MIME类型&#xff08;从服务器下载文件时也得添加对应的MIME类型&#xff09; 转载于:https://www.cnblog…

不定宽度居中

一、传统方法 <div class"wrap"><div class"inner">html &#xff1a; 让 inner 居中</div> </div> .wrap {float: left; /* 自适应内容宽度 */position: relative;left: 50%; } .inner {position: relative;left: -50%; } 二、…

文章目录自动生成器

提供一个插件&#xff0c;可以实现segmentfault的文章目录效果啦~~ 不止点击跳转还滚动激活当前链接 demo地址 使用很简单 <!-- 文章容器 --> <div id"kCatelog"></div> <!-- 目录容器 --> <div class"k-catelog-list" id"…

基于ARM+DSP进行应用开发-经验共享

针对当前应用的复杂性&#xff0c;SOC芯片更好能能满足应用和媒体的需求&#xff0c;集成众多接口&#xff0c;用ARM做为应用处理器进行多样化的应用开发和用户界面和接口&#xff0c;利用DSP进行算法加速&#xff0c;特别是媒体的编解码算法加速&#xff0c;既能够保持算法的灵…

工业相机之全局曝光与卷帘曝光

曝光方式包括两种&#xff1a; 全局曝光&#xff08;global shutter&#xff09;卷帘曝光&#xff08;rolling shutter&#xff09; CCD相机都是全局曝光&#xff0c;CMOS相机既有全局曝光也有卷帘曝光 全局曝光 全局曝光的方式比较简单。也就是说光圈打开后&#xff0c;整个图…

Hibernate入门注解笔记

Entity 代表实体 映射一张表 Table 定义表的属性 Embeddable 定义类级别可以被嵌入 Id 指定主键 GeneratedValue 指定主键生成策略 Column指定列级别的属性 Embedded 指定属性为被包含类 将被包含类 作为 包含类的 字段属性 写入同一张表 EmbeddedId 指定包含类为特定主键 实…

.NET 环境中使用RabbitMQ

在企业应用系统领域&#xff0c;会面对不同系统之间的通信、集成与整合&#xff0c;尤其当面临异构系统时&#xff0c;这种分布式的调用与通信变得越发重要。其次&#xff0c;系统中一般会有很多对实时性要求不高的但是执行起来比较较耗时的地方&#xff0c;比如发送短信&#…