首页 > 代码库 > mybatis 3.2.7 与 spring mvc 3.x、logback整合

mybatis 3.2.7 与 spring mvc 3.x、logback整合

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

准备工作:

maven依赖项:

  1 <properties>  2         <java-version>1.6</java-version>  3         <spring.version>3.2.8.RELEASE</spring.version>                  4     </properties>  5     <dependencies>  6   7         <!-- Spring -->  8         <dependency>  9             <groupId>org.springframework</groupId> 10             <artifactId>spring-core</artifactId> 11             <version>${spring.version}</version> 12         </dependency> 13  14         <dependency> 15             <groupId>org.springframework</groupId> 16             <artifactId>spring-expression</artifactId> 17             <version>${spring.version}</version> 18         </dependency> 19  20         <dependency> 21             <groupId>org.springframework</groupId> 22             <artifactId>spring-beans</artifactId> 23             <version>${spring.version}</version> 24         </dependency> 25  26         <dependency> 27             <groupId>org.springframework</groupId> 28             <artifactId>spring-context</artifactId> 29             <version>${spring.version}</version> 30         </dependency> 31         <dependency> 32             <groupId>org.springframework</groupId> 33             <artifactId>spring-context-support</artifactId> 34             <version>${spring.version}</version> 35         </dependency> 36         <dependency> 37             <groupId>org.springframework</groupId> 38             <artifactId>spring-web</artifactId> 39             <version>${spring.version}</version> 40         </dependency> 41  42         <dependency> 43             <groupId>org.springframework</groupId> 44             <artifactId>spring-webmvc</artifactId> 45             <version>${spring.version}</version> 46         </dependency> 47  48         <dependency> 49             <groupId>org.springframework</groupId> 50             <artifactId>spring-oxm</artifactId> 51             <version>${spring.version}</version> 52         </dependency> 53  54         <dependency> 55             <groupId>org.springframework</groupId> 56             <artifactId>spring-jdbc</artifactId> 57             <version>${spring.version}</version> 58         </dependency> 59  60         <dependency> 61             <groupId>org.springframework</groupId> 62             <artifactId>spring-tx</artifactId> 63             <version>${spring.version}</version> 64         </dependency> 65  66         <dependency> 67             <groupId>org.springframework</groupId> 68             <artifactId>spring-aop</artifactId> 69             <version>${spring.version}</version> 70         </dependency> 71  72  73         <dependency> 74             <groupId>org.aspectj</groupId> 75             <artifactId>aspectjweaver</artifactId> 76             <version>1.7.3</version> 77         </dependency> 78  79         <dependency> 80             <groupId>aopalliance</groupId> 81             <artifactId>aopalliance</artifactId> 82             <version>1.0</version> 83         </dependency> 84  85         <!-- json --> 86         <dependency> 87             <groupId>org.codehaus.jackson</groupId> 88             <artifactId>jackson-mapper-asl</artifactId> 89             <version>1.9.3</version> 90         </dependency> 91  92         <dependency> 93             <groupId>org.codehaus.jackson</groupId> 94             <artifactId>jackson-jaxrs</artifactId> 95             <version>1.9.9-redhat-2</version> 96         </dependency> 97  98         <!-- logback --> 99         <dependency>100             <groupId>org.slf4j</groupId>101             <artifactId>slf4j-api</artifactId>102             <version>1.7.7</version>103         </dependency>104 105         <dependency>106             <groupId>ch.qos.logback</groupId>107             <artifactId>logback-core</artifactId>108             <version>1.1.2</version>109         </dependency>110 111         <dependency>112             <groupId>ch.qos.logback</groupId>113             <artifactId>logback-classic</artifactId>114             <version>1.1.2</version>115         </dependency>116 117         <dependency>118             <groupId>commons-logging</groupId>119             <artifactId>commons-logging</artifactId>120             <version>1.1.3</version>121         </dependency>122 123         <!-- Servlet -->124         <dependency>125             <groupId>javax.servlet</groupId>126             <artifactId>servlet-api</artifactId>127             <version>2.5</version>128             <scope>provided</scope>129         </dependency>130 131         <!-- oracle -->132         <dependency>133             <groupId>com.oracle</groupId>134             <artifactId>ojdbc6</artifactId>135             <version>11.2.0.3</version>136         </dependency>137 138         <!-- mybatis -->139         <dependency>140             <groupId>org.mybatis</groupId>141             <artifactId>mybatis-spring</artifactId>142             <version>1.2.2</version>143         </dependency>144 145         <dependency>146             <groupId>org.mybatis</groupId>147             <artifactId>mybatis</artifactId>148             <version>3.2.7</version>149         </dependency>150 151 152     </dependencies>
View Code

一、先创建entity类

 1 package com.cnblogs.yjmyzz.entity; 2  3 import java.io.Serializable; 4  5 public class BasCarrierEntity implements Serializable { 6  7     private static final long serialVersionUID = -971818065984481747L; 8  9     private int recId;10     private int cyear;11     private String carrier;12 13     public int getRecId() {14         return recId;15     }16 17     public void setRecId(int recId) {18         this.recId = recId;19     }20 21     public int getCyear() {22         return cyear;23     }24 25     public void setCyear(int cyear) {26         this.cyear = cyear;27     }28 29     public String getCarrier() {30         return carrier;31     }32 33     public void setCarrier(String carrier) {34         this.carrier = carrier;35     }36 37     public String toString() {38         return "recid:" + recId + ",cyear:" + cyear + ",carrier:" + carrier;39     }40 41 }
View Code

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

二、创建Mapper接口

 1 package com.cnblogs.yjmyzz.mybatis.mapper; 2  3 import com.cnblogs.yjmyzz.entity.BasCarrierEntity; 4  5 public interface CarrierMapper { 6      7     BasCarrierEntity getCarrierById(int recId); 8  9     void insertCarrier(BasCarrierEntity entity);10 11     void deleteCarrier(BasCarrierEntity entity);12 13 }
View Code

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

三、定义sql映射文件 BasCarrier.xml

 1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  3 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 4  5 <mapper namespace="com.cnblogs.yjmyzz.mybatis.mapper.CarrierMapper"> 6  7     <cache /> 8  9     <select id="getCarrierById" resultType="BasCarrierEntity"10         parameterType="int">11         select t.recid recId,t.cyear cyear,t.carrier carrier12         from T_BAS_CARRIER t where13         t.recid = #{recId}14     </select>15 16     <insert id="insertCarrier" parameterType="BasCarrierEntity">17         <selectKey keyProperty="recId" order="BEFORE" resultType="int">18             select seq_t_bas_carrier.nextval as recId from dual19         </selectKey>20         insert into21         t_bas_carrier(recid,cyear,carrier)22         values(#{recId},#{cyear},#{carrier})23     </insert>24 25     <insert id="deleteCarrier" parameterType="BasCarrierEntity">26         delete from27         t_bas_carrier where 1=128         <if test="carrier != null">29             and carrier like #{carrier}30         </if>31     </insert>32 33 </mapper>
View Code

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

四、Spring-Database.xml 配置文件

 1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" 4     xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc" 5     xmlns:context="http://www.springframework.org/schema/context" 6     xsi:schemaLocation=" 7      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd 8      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 9      http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd10      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd11      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"12     default-autowire="byName">13 14     <bean id="dataSource"15         class="org.springframework.jdbc.datasource.DriverManagerDataSource">16         <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />17         <property name="url" value="${db-url}" />18         <property name="username" value="${db-username}" />19         <property name="password" value="${db-password}" />20     </bean>21 22     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">23         <!-- mybatis主配置文件,不能与后面的mapperLocations/typeAliasesPackage同时使用 -->24         <!-- <property name="configLocation" value="http://www.mamicode.com/classpath:mybatis-config.xml"></property> -->25         <property name="dataSource" ref="dataSource" />26         <!-- mapper中的类型别名 -->27         <property name="typeAliasesPackage" value="com.cnblogs.yjmyzz.entity"></property>28         <!-- mybatis 映射sql xml路径 -->29         <property name="mapperLocations" value="classpath:mybatis/**/*.xml"></property>30     </bean>31 32     <!-- 扫描指定包下的Mapper,自动创建mapper bean实例 -->33     <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">34         <property name="basePackage" value="com.cnblogs.yjmyzz.mybatis.mapper" />35     </bean>36 37     <!-- 事务管理 -->38     <bean id="transactionManager"39         class="org.springframework.jdbc.datasource.DataSourceTransactionManager">40         <property name="dataSource" ref="dataSource" />41     </bean>42 43     <tx:advice id="txAdvice" transaction-manager="transactionManager">44         <tx:attributes>45             <!-- 仅do开头的Service层方法,发生Exception异常时,才会事务回滚 -->46             <tx:method name="do*" read-only="false" rollback-for="java.lang.Exception" />47             <!-- 其它方法,只读事务,不回滚 -->48             <tx:method name="*" propagation="SUPPORTS" read-only="true" />49         </tx:attributes>50     </tx:advice>51 52     <aop:config>53         <!-- 仅拦截service层方法 -->54         <aop:pointcut id="pc"55             expression="execution(* com.cnblogs.yjmyzz.service..*.*(..))" />56         <aop:advisor pointcut-ref="pc" advice-ref="txAdvice" />57     </aop:config>58 59     <!-- <tx:annotation-driven /> -->60 </beans>
View Code

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

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

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

1     <context:component-scan base-package="com.cnblogs.yjmyzz">2         <context:exclude-filter type="annotation"3             expression="org.springframework.stereotype.Service" />4     </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节点换成

 1     <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" 2         destroy-method="close"> 3         <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" /> 4         <property name="url" value="${db-url}" /> 5         <property name="username" value="${db-username}" /> 6         <property name="password" value="${db-password}" /> 7         <property name="defaultAutoCommit" value="false" /> 8         <property name="initialSize" value="2" /> 9         <property name="maxActive" value="5" />10         <property name="maxWait" value="60000" />11     </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目录下即可

 1 <?xml version="1.0" encoding="UTF-8" ?> 2 <configuration scan="true" scanPeriod="1800 seconds" 3     debug="false"> 4  5     <property name="USER_HOME" value="logs" /> 6     <property scope="context" name="FILE_NAME" value="mybatis-logback" /> 7  8     <timestamp key="byDay" datePattern="yyyy-MM-dd" /> 9 10     <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">11         <encoder>12             <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n13             </pattern>14         </encoder>15     </appender>16 17     <appender name="file"18         class="ch.qos.logback.core.rolling.RollingFileAppender">19         <file>${USER_HOME}/${FILE_NAME}.log</file>20 21         <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">22             <fileNamePattern>${USER_HOME}/${byDay}/${FILE_NAME}-${byDay}-%i.log.zip23             </fileNamePattern>24             <minIndex>1</minIndex>25             <maxIndex>10</maxIndex>26         </rollingPolicy>27 28         <triggeringPolicy29             class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">30             <maxFileSize>5MB</maxFileSize>31         </triggeringPolicy>32         <encoder>33             <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n34             </pattern>35         </encoder>36 37     </appender>38 39     <logger name="com.cnblogs.yjmyzz" level="debug" additivity="true">40         <appender-ref ref="file" />41         <!-- <appender-ref ref="STDOUT" /> -->42     </logger>43 44     <root level="debug">45         <appender-ref ref="STDOUT" />46     </root>47 </configuration>
View Code

注:log的level要设置成DEBUG。

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

 1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 5     <context-param> 6         <param-name>logbackConfigLocation</param-name> 7         <param-value>classpath:logback.xml</param-value> 8     </context-param> 9     <listener>10         <listener-class>com.cnblogs.yjmyzz.util.LogbackConfigListener</listener-class>11     </listener>12     13     <context-param>14         <param-name>contextConfigLocation</param-name>15         <param-value>classpath:root-context.xml</param-value>16     </context-param>17     <filter>18         <filter-name>CharacterEncodingFilter</filter-name>19         <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>20         <init-param>21             <param-name>encoding</param-name>22             <param-value>utf-8</param-value>23         </init-param>24     </filter>25     <filter-mapping>26         <filter-name>CharacterEncodingFilter</filter-name>27         <url-pattern>/*</url-pattern>28     </filter-mapping>29     <listener>30         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>31     </listener>32     <servlet>33         <servlet-name>appServlet</servlet-name>34         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>35         <init-param>36             <param-name>contextConfigLocation</param-name>37             <param-value>classpath:servlet-context.xml</param-value>38         </init-param>39         <load-on-startup>0</load-on-startup>40     </servlet>41     <servlet-mapping>42         <servlet-name>appServlet</servlet-name>43         <url-pattern>/</url-pattern>44     </servlet-mapping>45 46 </web-app>
View Code

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

mybatis 3.2.7 与 spring mvc 3.x、logback整合