Spring MVC(三)—— 集成MyBatis

一、MyBatis 介绍

  MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
 

二、Spring MVC中集成MyBatis 

1、准备依赖的jar包,添加到工程

 

2、MyBatis 与数据库连接配置

 先添加如下配置文件到工程:
 
 
applicationContext-mybatis.xml为mybatis配置文件,内容如下:
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
 4     xmlns:context="http://www.springframework.org/schema/context" xmlns:cache="http://www.springframework.org/schema/cache"
 5     xsi:schemaLocation="
 6       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
 7       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
 8       http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
 9       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
10       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
11       http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.2.xsd"
12     default-autowire="byName" default-lazy-init="false">
13 
14     <!-- Mybatis's sqlSessionFactory config -->
15     <bean id="mysqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
16         <property name="dataSource" ref="dataSource"></property>
17         <property name="configLocation" value="classpath:mybatis/mybatis-config-mysql.xml" />
18     </bean>
19     <bean id="mapperScannerConfigurer"  class="org.mybatis.spring.mapper.MapperScannerConfigurer">
20         <property name="sqlSessionFactoryBeanName" value="mysqlSessionFactory" />
21         <property name="basePackage" value="com.ruijie.crazy.dao.persistence" />
22     </bean>
23 
24     <!-- Spring JtaTransactionManager -->
25     <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
26         <property name="dataSource" ref="dataSource"></property>
27     </bean>
28     
29     <!-- enable the configuration of transactional behavior based on annotations -->
30     <tx:annotation-driven transaction-manager="transactionManager" order="1" />
31 
32     <!-- 启用事务 -->
33     <tx:advice id="txAdvice" transaction-manager="transactionManager">
34         <tx:attributes>
35             <tx:method name="select*" read-only="true" propagation="SUPPORTS" />
36             <tx:method name="list*" read-only="true" propagation="SUPPORTS" />
37             <tx:method name="query*" read-only="true" propagation="SUPPORTS" />
38             <tx:method name="get*" read-only="true" propagation="SUPPORTS" />
39             <tx:method name="find*" read-only="true" propagation="SUPPORTS" />
40             <tx:method name="count*" read-only="true" propagation="SUPPORTS" />
41 
42             <tx:method name="add*" read-only="false" propagation="REQUIRED" rollback-for="Throwable" />
43             <tx:method name="del*" read-only="false" propagation="REQUIRED" rollback-for="Throwable" />
44             <tx:method name="insert*" read-only="false" propagation="REQUIRED" rollback-for="Throwable" />
45             <tx:method name="update*" read-only="false" propagation="REQUIRED" rollback-for="Throwable" />
46             <tx:method name="delete*" read-only="false" propagation="REQUIRED" rollback-for="Throwable" />
47             <tx:method name="save*" read-only="false" propagation="REQUIRED" rollback-for="Throwable" />
48 
49             <tx:method name="newTran*" read-only="false" propagation="REQUIRES_NEW" rollback-for="Throwable" />
50             <tx:method name="xaTran*" read-only="false" propagation="REQUIRED" isolation="SERIALIZABLE" rollback-for="Throwable" />
51 
52             <tx:method name="*" propagation="REQUIRED" rollback-for="Throwable" />
53         </tx:attributes>
54     </tx:advice>
55         
56 </beans>

applicationContext-database.xml为数据库连接配置文件,内容如下:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
 4     xmlns:context="http://www.springframework.org/schema/context" xmlns:cache="http://www.springframework.org/schema/cache"
 5     xsi:schemaLocation="
 6       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
 7       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
 8       http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
 9       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
10       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
11       http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.2.xsd"
12     default-autowire="byName" default-lazy-init="false">
13     <!-- 加载配置属性文件 -->
14     <context:property-placeholder ignore-unresolvable="true" location="classpath:jdbc-dbcp.properties" />
15 
16     <!-- 数据库连接池 -->
17     <bean id="parentDataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close" abstract="true">
18         <property name="username" value="${dbcp.db.username}" />
19         <property name="password" value="${dbcp.db.password}" />
20         <property name="driverClassName" value="${dbcp.db.driverClassName}" />
21         <property name="connectionProperties" value="${dbcp.db.connectionProperties}" />
22 
23 
24         <!-- Connection Pooling Info -->
25         <!-- 连接池启动时创建的初始化连接数量 -->
26         <property name="initialSize" value="${dbcp.db.initialSize}" />
27         <!-- 连接池中可同时连接的最大的连接数(默认值为8,调整为20,高峰单机器在20并发左右,自己根据应用场景定) -->
28         <property name="maxTotal" value="${dbcp.db.maxTotal}" />
29         <!-- 连接池中最大的空闲的连接数,超过的空闲连接将被释放,如果设置为负数表示不限制(默认为8个,maxIdle不能设置 太小,因为假如在高负载的情况下,连接的打开时间比关闭的时间快,会引起连接池中idle的个数 上升超过maxIdle,而造成频繁的连接销毁>和创建,类似于jvm参数中的Xmx设置) -->
30         <property name="maxIdle" value="${dbcp.db.maxIdle}" />
31         <!-- 连接池中最小的空闲的连接数,低于这个数量会被创建新的连接(默认为0,调整为5,该参数越接近maxIdle,性能越>好,因为连接的创建和销毁,都是需要消耗资源的;但是不能太大,因为在机器很空闲的时候,也会创建低于minidle个数的连接,类似于jvm>参数中的Xmn设置) -->
32         <property name="minIdle" value="${dbcp.db.minIdle}" />
33         <!--最大等待时间,当没有可用连接时,连接池等待连接释放的最大时间,超过该时间限制会抛出异常,如果设置-1表示无>限等待(默认为无限,调整为60000ms,避免因线程池不够用,而导致请求被无限制挂起) -->
34         <property name="maxWaitMillis" value="${dbcp.db.maxWaitMillis}" />
35 
36 
37         <!-- Validate配置代码 -->
38         <property name="testOnCreate" value="${dbcp.db.testOnCreate}" />
39         <!-- GenericObjectPool中针对pool管理,起了一个Evict的TimerTask定时线程进行控制(可通过设置参数timeBetweenEvictionRunsMillis>0),定时对线程池中的链接进行validateObject校验,对无效的链接进行关闭后,会调用ensureMinIdle,适当建立链接保证最小的minIdle连接数。 -->
40         <property name="testWhileIdle" value="${dbcp.db.testWhileIdle}" />
41         <!-- 对拿到的connection进行validateObject校验 -->
42         <property name="testOnBorrow" value="${dbcp.db.testOnBorrow}" />
43         <property name="testOnReturn" value="${dbcp.db.testOnReturn}" />
44         
45         <!-- 设置的Evict线程的时间,单位ms,大于0才会开启evict检查线程 -->
46         <property name="timeBetweenEvictionRunsMillis" value="${dbcp.db.timeBetweenEvictionRunsMillis}" />
47         <!-- 代表每次检查链接的数量,建议设置和maxActive一样大,这样每次可以有效检查所有的链接. -->
48         <property name="numTestsPerEvictionRun" value="${dbcp.db.numTestsPerEvictionRun}" />
49         <property name="minEvictableIdleTimeMillis" value="${dbcp.db.minEvictableIdleTimeMillis}" />
50         <!-- 验证连接是否可用sql -->
51         <property name="validationQuery" value="${dbcp.db.validationQuery}" />
52 
53         <!--超过removeAbandonedTimeout时间后,是否进 行没用连接(废弃)的回收(默认为false,调整为true) -->
54         <property name="removeAbandonedOnMaintenance" value="${dbcp.db.removeAbandonedOnMaintenance}" />
55         <property name="removeAbandonedOnBorrow" value="${dbcp.db.removeAbandonedOnBorrow}" />
56         <!--超过时间限制,回收没有用(废弃)的连接(默认为 300秒,调整为180) -->
57         <property name="removeAbandonedTimeout" value="${dbcp.db.removeAbandonedTimeout}" />
58         <!-- 是否在自动回收超时连接的时候打印连接的超时错误 -->
59         <property name="logAbandoned" value="${dbcp.db.logAbandoned}" />        
60         
61     </bean>
62 
63     <!-- 数据库连接池 -->
64     <bean id="defaultDataSource" parent="parentDataSource">
65         <property name="url" value="${dbcp.db.url}" />
66     </bean>
67    
68     <bean id="dataSource" class="com.ruijie.crazy.core.db.DynamicDataSource">
69         <property name="targetDataSources">
70             <map key-type="java.lang.String">
71             </map>
72         </property>
73         <property name="defaultTargetDataSource" ref="defaultDataSource" />
74     </bean>
75         
76 </beans>

jdbc-dbcp.properties为数据库连接配置:

 1 dbcp.db.driverClassName=com.mysql.jdbc.Driver
 2 dbcp.db.url=jdbc:mysql://127.0.0.1:3306/test
 3 dbcp.db.username=root
 4 dbcp.db.password=admin
 5 
 6 dbcp.db.connectionProperties=useUnicode=true;characterEncoding=utf8;
 7 #Connection Pooling Info
 8 dbcp.db.initialSize=20
 9 dbcp.db.maxTotal=50
10 dbcp.db.maxIdle=50
11 dbcp.db.minIdle=20
12 dbcp.db.maxWaitMillis=90000
13 
14 dbcp.db.validationQuery=SELECT 1 FROM DUAL
15 
16 dbcp.db.testOnCreate=false
17 dbcp.db.testWhileIdle=true
18 dbcp.db.testOnBorrow=true
19 dbcp.db.testOnReturn=false
20 
21 dbcp.db.timeBetweenEvictionRunsMillis=60000
22 dbcp.db.numTestsPerEvictionRun=50
23 #The minimum amount of time an object may sit idle in the pool before it is eligable for eviction by the idle object evictor (if any).
24 dbcp.db.minEvictableIdleTimeMillis=300000
25 
26 dbcp.db.removeAbandonedOnBorrow=true
27 dbcp.db.removeAbandonedOnMaintenance=true
28 dbcp.db.removeAbandonedTimeout=180
29 dbcp.db.logAbandoned=false

mybatis-config-mysql.xml为sql映射配置文件:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
 3 <configuration>
 4     <!-- 基础设置 -->
 5     <settings>
 6         <!-- 全局映射器启用缓存,设置为false,由应用去管理缓存,mybatis专注于sql -->
 7         <setting name="cacheEnabled" value="false" />
 8         <!-- 查询时,关闭关联对象即时加载以提高性能 -->
 9         <setting name="lazyLoadingEnabled" value="true" />
10         <!-- 设置关联对象加载的形态,此处为按需加载字段(加载字段由SQL指 定),不会加载关联表的所有字段,以提高性能 -->
11         <setting name="aggressiveLazyLoading" value="false" />
12         <!-- 对于未知的SQL查询,允许返回不同的结果集以达到通用的效果 -->
13         <setting name="multipleResultSetsEnabled" value="true" />
14         <!-- 允许使用列标签代替列名 -->
15         <setting name="useColumnLabel" value="true" />
16         <!-- 允许使用自定义的主键值(比如由程序生成的UUID 32位编码作为键值),数据表的PK生成策略将被覆盖 -->
17         <setting name="useGeneratedKeys" value="false" />
18         <!-- 给予被嵌套的resultMap以字段-属性的映射支持 -->
19         <setting name="autoMappingBehavior" value="FULL" />
20         <!-- 对于批量更新操作缓存SQL以提高性能,如果返回行数有问题,可以修改该值为SIMPLE -->
21         <setting name="defaultExecutorType" value="REUSE" />
22         <!-- 数据库超过120秒仍未响应则超时 -->
23         <setting name="defaultStatementTimeout" value="120" />
24     </settings>
25 
26     <!-- SQL映射文件 -->
27     <mappers>
28         <!-- 通用SQL语句片段 -->
29         <mapper resource="mybatis/mapper/common_SqlMap.xml" />        
30         <mapper resource="mybatis/mapper/TProvinceMapper.xml" />        
31     </mappers>
32 </configuration>

common_SqlMap.xml是为了封装sql查询语句使用的配置文件,非必须配置:

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
 3 <mapper namespace="common" >
 4   <sql id="If_Example_Conditon_Valid" >
 5     <if test="condition.valid" >
 6       <trim prefix="(" suffix=")" prefixOverrides="and" >
 7         <foreach collection="condition.criterions" item="criterion" >
 8           <choose >
 9             <when test="criterion.noValue" >
10               and ${criterion.condition}
11             </when>
12             <when test="criterion.singleValue" >
13               and ${criterion.condition} #{criterion.value}
14             </when>
15             <when test="criterion.betweenValue" >
16               and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
17             </when>
18             <when test="criterion.listValue" >
19               and ${criterion.condition}
20               <foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
21                 #{listItem}
22               </foreach>
23             </when>
24             <when test="criterion.dateValue" >
25               and ${criterion.condition} #{criterion.value,jdbcType=TIMESTAMP}
26             </when>
27           </choose>
28         </foreach>
29       </trim>
30     </if>
31   </sql>
32   <sql id="Example_Where_Clause" >
33     <where >
34       <foreach collection="oredCriteria" item="condition" separator="or" >
35         <include refid="common.If_Example_Conditon_Valid" />
36       </foreach>
37     </where>
38   </sql>
39   <sql id="Update_By_Example_Where_Clause" >
40     <where >
41       <foreach collection="example.oredCriteria" item="condition" separator="or" >
42         <include refid="common.If_Example_Conditon_Valid" />
43       </foreach>
44     </where>
45   </sql>
46 </mapper>

TProvinceMapper.xml为与数据库中具体的表匹配的映射文件:

  1 <?xml version="1.0" encoding="UTF-8" ?>
  2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
  3 <mapper namespace="com.ruijie.crazy.dao.persistence.TProvinceMapper" >
  4   <resultMap id="BaseResultMap" type="com.ruijie.crazy.entity.beans.TProvince" >
  5     <id column="id" property="id" jdbcType="INTEGER" />
  6     <result column="province" property="province" jdbcType="VARCHAR" />
  7   </resultMap>
  8   <sql id="Base_Column_List" >
  9     id, province
 10   </sql>
 11   <select id="selectByExample" resultMap="BaseResultMap" parameterType="com.ruijie.crazy.core.mybatis.Criteria" >
 12     select
 13     <if test="distinct" >
 14       distinct
 15     </if> 
 16     <include refid="Base_Column_List" />
 17     from t_province
 18     <if test="_parameter != null" >
 19       <include refid="common.Example_Where_Clause" />
 20     </if>
 21   </select>
 22   <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
 23     select 
 24     <include refid="Base_Column_List" />
 25     from t_province
 26     where id = #{id,jdbcType=INTEGER}
 27   </select>
 28   <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
 29     delete from t_province
 30     where id = #{id,jdbcType=INTEGER}
 31   </delete>
 32   <delete id="deleteByExample" parameterType="com.ruijie.crazy.core.mybatis.Criteria" >
 33     delete from t_province
 34     <if test="_parameter != null" >
 35       <include refid="common.Example_Where_Clause" />
 36     </if>
 37   </delete>
 38   <insert id="insert" parameterType="com.ruijie.crazy.entity.beans.TProvince" >
 39     <selectKey resultType="java.lang.Integer" keyProperty="id" order="BEFORE" >
 40       SELECT LAST_INSERT_ID()
 41     </selectKey>
 42     insert into t_province (id, province)
 43     values (#{id,jdbcType=INTEGER}, #{province,jdbcType=VARCHAR})
 44   </insert>
 45   <insert id="insertSelective" parameterType="com.ruijie.crazy.entity.beans.TProvince" >
 46     <selectKey resultType="java.lang.Integer" keyProperty="id" order="BEFORE" >
 47       SELECT LAST_INSERT_ID()
 48     </selectKey>
 49     insert into t_province
 50     <trim prefix="(" suffix=")" suffixOverrides="," >
 51       id,
 52       <if test="province != null" >
 53         province,
 54       </if>
 55     </trim>
 56     <trim prefix="values (" suffix=")" suffixOverrides="," >
 57       #{id,jdbcType=INTEGER},
 58       <if test="province != null" >
 59         #{province,jdbcType=VARCHAR},
 60       </if>
 61     </trim>
 62   </insert>
 63   <select id="countByExample" parameterType="com.ruijie.crazy.core.mybatis.Criteria" resultType="java.lang.Integer" >
 64     select count(*) from t_province
 65     <if test="_parameter != null" >
 66       <include refid="common.Example_Where_Clause" />
 67     </if>
 68   </select>
 69   <update id="updateByExampleSelective" parameterType="map" >
 70     update t_province
 71     <set >
 72       <if test="record.id != null" >
 73         id = #{record.id,jdbcType=INTEGER},
 74       </if>
 75       <if test="record.province != null" >
 76         province = #{record.province,jdbcType=VARCHAR},
 77       </if>
 78     </set>
 79     <if test="_parameter != null" >
 80       <include refid="common.Update_By_Example_Where_Clause" />
 81     </if>
 82   </update>
 83   <update id="updateByExample" parameterType="map" >
 84     update t_province
 85     set id = #{record.id,jdbcType=INTEGER},
 86       province = #{record.province,jdbcType=VARCHAR}
 87     <if test="_parameter != null" >
 88       <include refid="common.Update_By_Example_Where_Clause" />
 89     </if>
 90   </update>
 91   <update id="updateByPrimaryKeySelective" parameterType="com.ruijie.crazy.entity.beans.TProvince" >
 92     update t_province
 93     <set >
 94       <if test="province != null" >
 95         province = #{province,jdbcType=VARCHAR},
 96       </if>
 97     </set>
 98     where id = #{id,jdbcType=INTEGER}
 99   </update>
100   <update id="updateByPrimaryKey" parameterType="com.ruijie.crazy.entity.beans.TProvince" >
101     update t_province
102     set province = #{province,jdbcType=VARCHAR}
103     where id = #{id,jdbcType=INTEGER}
104   </update>
105     
106 </mapper>

3、java中代码

4、测试

Controller中写入如下测试代码:
 1 package com.ruijie.crazy.controller;
 2 
 3 import java.util.HashMap;
 4 import java.util.List;
 5 import java.util.Map;
 6 
 7 import javax.annotation.Resource;
 8 
 9 import org.springframework.stereotype.Controller;
10 import org.springframework.web.bind.annotation.RequestMapping;
11 import org.springframework.web.bind.annotation.RequestMethod;
12 import org.springframework.web.bind.annotation.ResponseBody;
13 import org.springframework.web.servlet.ModelAndView;
14 
15 import com.ruijie.crazy.dao.service.TProvinceDao;
16 import com.ruijie.crazy.entity.beans.TProvince;
17 
18 @Controller
19 @RequestMapping("/myweb")
20 public class MyFirstController {
21     @Resource
22     TProvinceDao tProvinceDao;
23         
24     @RequestMapping(value = "/test", method = RequestMethod.GET)
25     public ModelAndView getUserInfoByCode() {              
26         System.out.println("/myweb/test");
27         Map<String, Object> map = new HashMap<String, Object>();  
28         
29         List<TProvince> plist= tProvinceDao.getAll();
30         map.put("userName", "ypf: " + plist.get(0).getProvince());  
31         return new ModelAndView("hello",map);
32     }
33         
34 }

运行工程,浏览器输入http://127.0.0.1/crazypf/myweb/test.html,显示结果如下:

原文地址:https://www.cnblogs.com/ypf1989/p/5546158.html