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">
<cache
eviction="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/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://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 !");
}