github上有一个Mybatis-Spring的项目,专门用于辅助完成mybatis与spring的整合,大大简化了整合难度,使用步骤:

准备工作:

maven依赖项:

 <properties>
<java-version>1.6</java-version>
<spring.version>3.2.8.RELEASE</spring.version>
</properties>
<dependencies> <!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</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-beans</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-context-support</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-webmvc</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-jdbc</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-aop</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7.3</version>
</dependency> <dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency> <!-- json -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.3</version>
</dependency> <dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
<version>1.9.9-redhat-2</version>
</dependency> <!-- logback -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency> <dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.2</version>
</dependency> <dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.2</version>
</dependency> <dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.3</version>
</dependency> <!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency> <!-- oracle -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3</version>
</dependency> <!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.2</version>
</dependency> <dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.7</version>
</dependency> </dependencies>

一、先创建entity类

 package com.cnblogs.yjmyzz.entity;

 import java.io.Serializable;

 public class BasCarrierEntity implements Serializable {

     private static final long serialVersionUID = -971818065984481747L;

     private int recId;
private int cyear;
private String carrier; public int getRecId() {
return recId;
} public void setRecId(int recId) {
this.recId = recId;
} public int getCyear() {
return cyear;
} public void setCyear(int cyear) {
this.cyear = cyear;
} public String getCarrier() {
return carrier;
} public void setCarrier(String carrier) {
this.carrier = carrier;
} public String toString() {
return "recid:" + recId + ",cyear:" + cyear + ",carrier:" + carrier;
} }

这是一个POJO类,没有任何花头.

二、创建Mapper接口

 package com.cnblogs.yjmyzz.mybatis.mapper;

 import com.cnblogs.yjmyzz.entity.BasCarrierEntity;

 public interface CarrierMapper {

     BasCarrierEntity getCarrierById(int recId);

     void insertCarrier(BasCarrierEntity entity);

     void deleteCarrier(BasCarrierEntity entity);

 }

相当于传统ORM数据库应用里的DAO层接口

三、定义sql映射文件 BasCarrier.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="com.cnblogs.yjmyzz.mybatis.mapper.CarrierMapper"> <cache /> <select id="getCarrierById" resultType="BasCarrierEntity"
parameterType="int">
select t.recid recId,t.cyear cyear,t.carrier carrier
from T_BAS_CARRIER t where
t.recid = #{recId}
</select> <insert id="insertCarrier" parameterType="BasCarrierEntity">
<selectKey keyProperty="recId" order="BEFORE" resultType="int">
select seq_t_bas_carrier.nextval as recId from dual
</selectKey>
insert into
t_bas_carrier(recid,cyear,carrier)
values(#{recId,jdbcType=NUMERIC},#{cyear,jdbcType=NUMERIC},#{carrier,jdbcType=VARCHAR})
</insert> <delete id="deleteCarrier" parameterType="BasCarrierEntity">
delete from
t_bas_carrier where 1=1
<if test="carrier != null">
and carrier like #{carrier}
</if>
</delete> </mapper>

以上这三板斧是必不可少的,注:xml中sql语句的id要与mapper接口中的方法名完全相同,这样不用其它任何额外配置,运行时,mybatis就能自动将接口中的方法与sql关联起来。

四、Spring-Database.xml 配置文件

 <?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
default-autowire="byName"> <bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="${db-url}" />
<property name="username" value="${db-username}" />
<property name="password" value="${db-password}" />
</bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- mybatis主配置文件,不能与后面的mapperLocations/typeAliasesPackage同时使用 -->
<!-- <property name="configLocation" value="classpath:mybatis-config.xml"></property> -->
<property name="dataSource" ref="dataSource" />
<!-- mapper中的类型别名 -->
<property name="typeAliasesPackage" value="com.cnblogs.yjmyzz.entity"></property>
<!-- mybatis 映射sql xml路径 -->
<property name="mapperLocations" value="classpath:mybatis/**/*.xml"></property>
</bean> <!-- 扫描指定包下的Mapper,自动创建mapper bean实例 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.cnblogs.yjmyzz.mybatis.mapper" />
</bean> <!-- 事务管理 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean> <tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 仅do开头的Service层方法,发生Exception异常时,才会事务回滚 -->
<tx:method name="do*" read-only="false" rollback-for="java.lang.Exception" />
<!-- 其它方法,只读事务,不回滚 -->
<tx:method name="*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice> <aop:config>
<!-- 仅拦截service层方法 -->
<aop:pointcut id="pc"
expression="execution(* com.cnblogs.yjmyzz.service..*.*(..))" />
<aop:advisor pointcut-ref="pc" advice-ref="txAdvice" />
</aop:config> <!-- <tx:annotation-driven /> -->
</beans>

真正属于mybatis专用的配置是22-35行,其它都是些db开发的常规配置。

事务这里有一个要特别注意的问题:因为Spring/SpringMVC的父子容器问题,默认情况下@Service的xxxService并不具备增加事务处理能力,需要做点特殊配置

a) spring-mvc servlet的配置文件里,参考下面配置:

     <context:component-scan base-package="com.cnblogs.yjmyzz">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Service" />
</context:component-scan>

即:将@Service所对应的Service类排除掉,因为Spring-MVC compent-scan注入的只是普通的bean,不具备增加事务处理能力,所以要排除掉.

b) spring 主配置文件里,参考下面配置:

    <context:component-scan base-package="com.cnblogs.yjmyzz">
</context:component-scan>

这样处理后,compent-scan扫描到的Service类,就交由Spring,而非Spring-MVC来注入了。

另外还有一个事务自动提交的问题,虽然在配置中已经明确指定了仅Service层do开头的方法,才支持可写事务,其它方法都是只读事务,但如果你运行一下会发现,其它非do开头的方法如果执行一条insert语句,仍然会提交成功。

造成这个的原因在于datasource,这里我们采用的是org.springframework.jdbc.datasource.DriverManagerDataSource数据源,这种数据源不支持defaultAutoCommit属性,如果不想使用自动提交,可以把datasource节点换成

     <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="${db-url}" />
<property name="username" value="${db-username}" />
<property name="password" value="${db-password}" />
<property name="defaultAutoCommit" value="false" />
<property name="initialSize" value="2" />
<property name="maxActive" value="5" />
<property name="maxWait" value="60000" />
</bean>

注意第7行,defaultAutoCommit设置成false即可

如果使用Oracle,事务这里还有一个小坑,read-only不管设置成true/false,效果都是一样的,原因见:http://docs.oracle.com/cd/B19306_01/java.102/b14355/apxtips.htm

Transaction Isolation Levels and Access Modes

Read-only connections are supported by the Oracle server, but not by the Oracle JDBC drivers.

即:使用oracle jdbc驱动时,不支持read-only属性

五、mybatis在eclipse控制台显示sql语句的问题

mybatis支持多种日志组件,默认顺序如下:

• SLF4J
• Apache Commons Logging
• Log4j 2
• Log4j
• JDK logging

上一篇刚学习的logback组件,正好是SLF4J的实现之一,所以如果采用logback来记录日志,mybatis不用做任何额外配置,将logback.xml扔在resource目录下即可

 <?xml version="1.0" encoding="UTF-8" ?>
<configuration scan="true" scanPeriod="1800 seconds"
debug="false"> <property name="USER_HOME" value="logs" />
<property scope="context" name="FILE_NAME" value="mybatis-logback" /> <timestamp key="byDay" datePattern="yyyy-MM-dd" /> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender> <appender name="file"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${USER_HOME}/${FILE_NAME}.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>${USER_HOME}/${byDay}/${FILE_NAME}-${byDay}-%i.log.zip
</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>10</maxIndex>
</rollingPolicy> <triggeringPolicy
class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>5MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n
</pattern>
</encoder> </appender> <logger name="com.cnblogs.yjmyzz" level="debug" additivity="true">
<appender-ref ref="file" />
<!-- <appender-ref ref="STDOUT" /> -->
</logger> <root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>

注:log的level要设置成DEBUG。

logback与spring mvc整合的方法,上一篇已经讲过,就不再重复了,这里只给出web.xml的配置

 <?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<param-name>logbackConfigLocation</param-name>
<param-value>classpath:logback.xml</param-value>
</context-param>
<listener>
<listener-class>com.cnblogs.yjmyzz.util.LogbackConfigListener</listener-class>
</listener> <context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:root-context.xml</param-value>
</context-param>
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:servlet-context.xml</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping> </web-app>

示例源码:Spring-MVC-REST-MyBatis.zip

最新文章

  1. C#设计模式系列:组合模式(Composite)
  2. tomcat和HTTP
  3. ThinkPhp 验证码不显示图片
  4. visual studio code 里调试运行 Python代码
  5. javascript学习内容--改变样式、取消设置、显示内容、隐藏内容
  6. Sprint总结和第八九十的读书笔记
  7. 1. 走进java
  8. asp.net sql无限极分类实例程序
  9. html中的空格可以用什么代替
  10. python遗传算法实现数据拟合
  11. 让EFCore更疯狂些的扩展类库(二):查询缓存、分部sql、表名替换的策略配置
  12. 有关Windows10中诊断和反馈隐私设置
  13. Java——泛型
  14. 利用 SQL Server Audit 审核哪些用户添加删除更新SQL Agent Job
  15. 关于Grid Layout
  16. Quartz的使用案例
  17. POJ 3020 -Antenna Placement-二分图匹配
  18. matlab常用命令
  19. Happiness
  20. java多态的向上转型与向下转型(与编译时类型与运行时类型有关)

热门文章

  1. js window对象
  2. 集合迭代器快速失败行为及CopyOnWriteArrayList
  3. android中的广播接收实现总结
  4. LoadRunner性能测试巧匠训练营
  5. 一条诡异的insert语句
  6. 小议如何使用APPLY
  7. 【JSP】JSP基础学习记录(四)—— Servlet
  8. srping MVC 工程简单搭建
  9. 透过byte数组简单分析Java序列化、Kryo、ProtoBuf序列化
  10. ubuntu下apache2 安装 配置 卸载 CGI设置 SSL设置