MyBatis和Spring的整合
1、什么是MyBatis?
2)
简单的写了个测试类:
MyBatis是Apache的一款开源的java的持久层框架,提供了SQL Map和DAO。支持普通的SQL查询,存储过程和高级的映射,myBatis将SQL语句和java代码分离开,解耦了代码,将接口和POJOs映射成数据库表的记录。
每个数据源对应一个SqlSessionFactory,SqlSessionFactory的创建 可以通过代码调用SqlSessionFactoryBuilder创建,Builder也通过xml资源创建SqlSessionFactory。SqlSessionFactory会创建SqlSession负责执行SQL和结果的映射。
2、MyBatis和Hibernate的对比
1)hibernate比MyBatis重量级,难上手。
2)Mybatis查询能够指定字段和编写复杂的SQL语句,如left join等,而hibernate的HQL若过于复杂则服务器效率会下降,所以Mybatis适合复杂的SQL查询,而hibernate适合并不复杂的简单的SQL。
3)mybatis因为编写的SQL与具体的数据库类型有关,故移植性差,而hibernate使用HQL,不关心底层数据库的类型,移植性高。
4)mybatis和hibernate都实现了自己的二级缓存机制,也能够实现自己的二级缓存或者使用第三方机制的缓存如echcache或Redis。hibernate的二级缓存在SessionFactory生成的配置文件里配置,然后再配置具体的表和实体类的映射。如下面例子:
<bean id="entityManagerFactory"class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"><property name="dataSource" ref="dataSource" /><property name="persistenceProvider" ref="persistenceProvider" /><property name="jpaVendorAdapter" ref="jpaVendorAdapter" /><property name="jpaProperties"><props><prop key="hibernate.dialect">${hibernate.dialect}</prop><prop key="hibernate.show_sql">${hibernate.show_sql}</prop><prop key="hibernate.format_sql">${hibernate.format_sql}</prop><prop key="hibernate.jdbc.fetch_size">50</prop><prop key="hibernate.jdbc.batch_size">50</prop><!--二级缓存启用--><prop key="hibernate.cache.use_second_level_cache">true</prop><!--查询缓存启用--><prop key="hibernate.cache.use_query_cache">true</prop><prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</prop><prop key="javax.persistence.sharedCache.mode">ENABLE_SELECTIVE</prop><!--echcache的配置文件--><prop key="net.sf.ehcache.configurationResourceName">/ehcache.xml</prop><prop key="hibernate.generate_statistics">false</prop></props></property></bean>
<?xml version="1.0" encoding="UTF-8"?><ehcache><diskStore path="/opt/bpm/cache/bpm" /><!-- --><defaultCache maxElementsInMemory="20000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" diskPersistent="false"diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" /><cache name="com.psbc.cfc.bpm.domain.Area" maxElementsInMemory="500" eternal="false" timeToLiveSeconds="7200" timeToIdleSeconds="3600" overflowToDisk="true" /></ehcache>
在相关的的实体类中使用xml或者用注解:
/*** Created By: Comwave Project Team* Created Date: 2014-4-28*/package com.psbc.cfc.bpm.domain;import java.io.Serializable;import javax.persistence.Cacheable;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.Id;import javax.persistence.Table;import org.hibernate.annotations.Cache;import org.hibernate.annotations.CacheConcurrencyStrategy;/*** 区域** @author James* @version 1.0*/@Entity@Cacheable@Cache(usage=CacheConcurrencyStrategy.READ_ONLY)@Table(name = "VIEW_AREA")public class Area implements Serializable {private static final long serialVersionUID = 6474865115108614073L;/** 区域编号 */@Id@Column(name = "AREA_CODE", length = 100)private String areaCode;/** 区域名称 */@Column(name = "AREA_NAME", length = 100)private String areaName;public String getAreaCode() {return areaCode;}public void setAreaCode(String areaCode) {this.areaCode = areaCode;}public String getAreaName() {return areaName;}public void setAreaName(String areaName) {this.areaName = areaName;}}
CacheConcurrencyStrategy有四种类型:
NONE
READ_ONLY:只读和缓存,不能修改缓存,但数据库修改能够立即见效。
READ_WRITE:严格的读写,更新缓存时加锁,其他线程查询缓存时查数据库。
NONSTRICT_READ_WRITE:不严格的读写,更新缓存不加锁,适合偶尔的更新,即两个事务更新同一缓存比较少。
而myBatis的缓存具体到在表和实体的Mapper里,如:
<mapper namespace="com.cnblogs.yjmyzz.mybatis.mapper.OrderMapper"><cacheeviction="LRU"flushInterval="60000"size="1024"readOnly="true"/>...</mapper>
在<Select"></Select>这样使用则表示不使用缓存机制。
Mapper里的所有操作默认是会作用到缓存,若使用 useCache="false",则可以禁止掉缓存。
但通常在效率上hibernate的效能比Mybatis好。
总结:
hibernate:
1)hibernate对对象的维护和缓存比Mybatis好。
2)hibernate增删查改已经为用户实现了,要写的SQL比较少。
3)hibernate的移植性比mybatis好。
4)hibernate的二级缓存能够支持第三方缓存,而且比Mybatis好。
Mybatis:
1)支持复杂的SQL查询,效率比hibernate快。
2)门槛低,容易上手。
3、Spring和Mybatis的整合
1)创建Maven WebApp项目
这里贴上我自己的Maven的setting.xml,下载快:
<?xml version="1.0"?><settings><localRepository>C:\job\maven_repository\maven_repository</localRepository><mirrors><mirror><id>alimaven</id><name>aliyun maven</name><url>http://maven.aliyun.com/nexus/content/groups/public/</url><mirrorOf>central</mirrorOf></mirror></mirrors><profiles><profile><id>nexus</id><repositories><repository><id>nexus</id><name>local private nexus</name><url>http://maven.oschina.net/content/groups/public/</url><releases><enabled>true</enabled></releases><snapshots><enabled>false</enabled></snapshots></repository></repositories><pluginRepositories><pluginRepository><id>nexus</id><name>local private nexus</name><url>http://maven.oschina.net/content/groups/public/</url><releases><enabled>true</enabled></releases><snapshots><enabled>false</enabled></snapshots></pluginRepository></pluginRepositories></profile></profiles></settings>
项目结构如下:

Pom.xml如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>yi.zhen.mo</groupId><artifactId>spring_myBatis</artifactId><packaging>war</packaging><version>0.0.1-SNAPSHOT</version><name>spring_myBatis Maven Webapp</name><url>http://maven.apache.org</url><properties><!-- spring版本号 --><spring.version>4.2.4.RELEASE</spring.version><!-- mybatis版本号 --><mybatis.version>3.2.6</mybatis.version><!-- log4j日志文件管理包版本 --><slf4j.version>1.7.7</slf4j.version><log4j.version>1.2.17</log4j.version></properties><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-oxm</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</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-webmvc</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-context-support</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>${spring.version}</version></dependency><!-- mybatis核心包 --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>${mybatis.version}</version></dependency><!-- mybatis/spring包 --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>1.2.2</version></dependency><dependency><groupId>javax</groupId><artifactId>javaee-api</artifactId><version>7.0</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.30</version></dependency><dependency><groupId>commons-dbcp</groupId><artifactId>commons-dbcp</artifactId><version>1.2.2</version></dependency><dependency><groupId>jstl</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency><!-- 日志文件管理包 --><!-- log start --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>${log4j.version}</version></dependency><!-- 格式化对象,方便输出日志 --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.1.41</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>${slf4j.version}</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>${slf4j.version}</version></dependency><!-- log end --><!-- 映入JSON --><dependency><groupId>org.codehaus.jackson</groupId><artifactId>jackson-mapper-asl</artifactId><version>1.9.13</version></dependency><!-- 上传组件包 --><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.1</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.4</version></dependency><dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>1.9</version></dependency></dependencies><build><finalName>spring_myBatis</finalName><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.1</version><configuration><source>1.7</source><target>1.7</target><encoding>utf8</encoding></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>2.19.1</version><configuration><groups>org.apache.surefire.BuildTest</groups><parallel>classes</parallel><threadCount>10</threadCount><forkCount>3</forkCount><reuseForks>true</reuseForks><skipTests>true</skipTests><argLine>-Xmx1024m -XX:MaxPermSize=256m</argLine></configuration></plugin></plugins></build></project>
看applicationContext.xml如下:
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-4.0.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.0.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"><!-- 自动扫描 --><context:component-scan base-package="yi.zhen.mo" /><!-- <context:annotation-config /> --><bean id="propertyConfigurer"class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="location" value="classpath:jdbc.properties" /></bean><bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"><property name="driverClassName" value="${driver}" /><property name="url" value="${url}" /><property name="username" value="${username}" /><property name="password" value="${password}" /><!-- 初始化连接大小 --><property name="initialSize" value="${initialSize}"></property><!-- 连接池最大数量 --><property name="maxActive" value="${maxActive}"></property><!-- 连接池最大空闲 --><property name="maxIdle" value="${maxIdle}"></property><!-- 连接池最小空闲 --><property name="minIdle" value="${minIdle}"></property><!-- 获取连接最大等待时间 --><property name="maxWait" value="${maxWait}"></property></bean><!-- SqlSessionFactoryBean是的getObject方法会返回一个sqlSessionFactory实例 --><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource" /><!-- 自动扫描mapping.xml文件 若使用注解则不需 --><property name="mapperLocations" value="classpath:yi/zhen/mo/mapping/*.xml"></property></bean><!-- 单个dao的配置--><!-- <bean id="useDao" class="org.mybatis.spring.mapper.MapperFactoryBean"><property name="mapperInterface" value="com.xxx.dao.UserDao" /><property name="sqlSessionFactory" ref="sqlSessionFactory" /></bean> --><!-- 多个dao的配置 MapperScannerConfigurer会将生成的Mapper代理注册到Spring IOC容器中--><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="yi.zhen.mo.dao" /><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property></bean><!-- dataSource的事务配置--><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource" /></bean></beans>
Mapper的配置有两种:
(1)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="yi.zhen.mo.dao.UserMapper"><select id="getUser" resultType="yi.zhen.mo.entity.User">select * from User where username=#{username} and password=#{password}</select></mapper>
(2)注解:

简单的写了个测试类:
public static void main(String[] args) {ClassPathXmlApplicationContext cx=new ClassPathXmlApplicationContext("spring-mybatis.xml");UserMapper um=(UserMapper)cx.getBean("userMapper");List<User> list=um.getUser("xiaoming","111111");if(list==null||list.size()==0)System.out.println("can not find !");else System.out.println("find the record !");}
浙公网安备 33010602011771号