zoukankan      html  css  js  c++  java
  • mybatis与spring的整合

    今天是mybatis的最后一天,也是最为重要的一天,mybatis与spring整合,(spring相关知识我会抽一个大的模块进行讲解).

    首先加入Spring的依赖

    <dependency>
                <groupId>cglib</groupId>
                <artifactId>cglib</artifactId>
                <version>3.1</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
            </dependency>
            <!-- Mybatis -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
            </dependency>
            <!-- 分页插件 -->
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper</artifactId>
                <version>3.4.2</version>
            </dependency>
            <dependency>
                <groupId>com.github.jsqlparser</groupId>
                <artifactId>jsqlparser</artifactId>
                <version>0.9.1</version>
            </dependency>
    
            <!-- Spring -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aspects</artifactId>
            </dependency>
    
            <!-- Mybatis 和 Spring整合包 -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-spring</artifactId>
            </dependency>
    
            <!-- 连接池 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
            </dependency>
            

    先创建applicationContext.xml

    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
        xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        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/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
    
    <!-- 使用spring自带的占位符替换功能 -->
        <bean
            class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <!-- 允许JVM参数覆盖 -->
            <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
            <!-- 忽略没有找到的资源文件 -->
            <property name="ignoreResourceNotFound" value="true" />
            <!-- 配置资源文件 -->
            <property name="locations">
                <list>
                    <value>classpath:jdbc.properties</value>
                </list>
            </property>
        </bean>
    <context:component-scan base-package="com.j1"/>
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
            init-method="init" destroy-method="close">
            <!-- 数据库驱动 -->
            <property name="driverClassName" value="${jdbc.driver}" />
            <!-- 基本属性 url、user、password -->
            <property name="url" value="${jdbc.url}" />
            <property name="username" value="${jdbc.username}" />
            <property name="password" value="${jdbc.password}" />
    
            <!-- 配置初始化大小、最小、最大 -->
            <property name="initialSize" value="10" />
            <property name="minIdle" value="5" />
            <property name="maxActive" value="50" />
    
            <!-- 配置获取连接等待超时的时间 -->
            <property name="maxWait" value="60000" />
    
            <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
            <property name="timeBetweenEvictionRunsMillis" value="60000" />
    
            <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
            <property name="minEvictableIdleTimeMillis" value="300000" />
    
            <property name="validationQuery" value="SELECT 1" />
            <property name="testWhileIdle" value="true" />
            <property name="testOnBorrow" value="false" />
            <property name="testOnReturn" value="false" />
    
            <!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
            <!-- 如果用Oracle,则把poolPreparedStatements配置为true,mysql可以配置为false。分库分表较多的数据库,建议配置为false。 -->
            <property name="poolPreparedStatements" value="false" />
            <property name="maxPoolPreparedStatementPerConnectionSize"
                value="20" />
    
            <!-- 配置监控统计拦截的filters -->
            <property name="filters" value="stat" />
        </bean>
    
        <!-- 构造sqlSessionFactory -->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <!-- 指定Mybatis的配置文件 -->
            <property name="configLocation" value="classpath:mybatis-config.xml"></property>
        </bean>
    <!-- 定义Mapper -->
        <bean id="orderMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
             <!-- 指定接口 -->
            <property name="mapperInterface" value="com.j1.mybatis.mapper.OrderMapper" />
            <!-- 指定sqlSessionFactory -->
            <property name="sqlSessionFactory" ref="sqlSessionFactory" />
        </bean>
    </beans>

    通过Spring 来获得OrderMapper

    private OrderMapper orderMapper;
    
        @Before
        public void setUp() throws Exception {
            try {
                /**
                 * 这是之前的写法,现在我们来集成Spring做这件事情,就会很简单
                 *     // 构造SqlSessionFactory
                // 定义配置文件路径
                String resource = "mybatis-config.xml";
                // 读取配置文件
                InputStream inputStream = Resources.getResourceAsStream(resource);
                // 通过SqlSessionFactoryBuilder构建一个SqlSessionFactory
                SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
                        .build(inputStream);
                // this.userDAO = new UserDao(sqlSessionFactory);
                SqlSession sqlSession = sqlSessionFactory.openSession(true);
                this.orderMapper = sqlSession.getMapper(OrderMapper.class);
                 */
            ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
            this.orderMapper=context.getBean(OrderMapper.class);
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }

    进行测试:

    /**
         * 一对一的第二种查询
         */
        @Test
        public void testQuerOrderAndUserByOrderNum2() {
            Order order = orderMapper.querOrderAndUserByOrderNum2("20140921002");
            System.out.println(order);
        }
     /**
         * 根据订单号查询订单并且查询出下单人的信息,第二种实现
         * 
         * @param orderNumber
         * @return
         */
        public Order querOrderAndUserByOrderNum2(String orderNum);
    <!-- 一对一的第二种查询方法,进行映射 -->    
    <resultMap id="orderMap" type="Order" autoMapping="true">
    <id  column="id"  property="id"/>
        <association property="user" javaType="User" autoMapping="true">
        
        </association>
    </resultMap>
        <select id="querOrderAndUserByOrderNum2" resultMap="orderMap">
                SELECT
                o.*,
                u.name,
                u.user_name,
                u.age
            FROM
                tb_order o
            LEFT JOIN tb_user u ON u.id = o.user_id
            WHERE
                o.order_number = #{orderNumber}
            
        </select>

    这套代码运行下来,初级的Spring的整合就结束了.

    接着我们来整理applicationContext.xml,使其更加简明扼要.

    <!-- 定义Mybatis mapper接口扫描器 -->
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
             <property name="basePackage" value="com.j1.mybatis.mapper" />
        </bean>
     <!-- 构造sqlSessionFactory -->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <!-- 指定Mybatis的配置文件 -->
            <property name="configLocation" value="classpath:mybatis-config.xml"></property>
            <!-- 使用通配符配置mapper.xml -->
            <property name="mapperLocations" value="classpath:mappers/*.xml"></property>
        </bean>

    如果指定了mapper不需要定义接口扫描,如果xml与mapper的java代码分离的话就必须定义接口扫描器,否则或报错.

    1.1. Mapper整合Service

    package com.j1.mybatis.service;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import com.j1.mybatis.mapper.OrderMapper;
    import com.j1.mybatis.pojo.Order;
    
    @Service
    public class OrderService {
        @Autowired
        private OrderMapper orderMapper;
    
        public Order querOrderAndUserByOrderNum2(String orderNum){
            return orderMapper.querOrderAndUserByOrderNum2(orderNum);
        }
    }
    package com.j1.mybatis.mapper;
    
    import static org.junit.Assert.*;
    
    import java.io.IOException;
    import java.io.InputStream;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    import org.aspectj.apache.bcel.util.ClassPath;
    import org.junit.Before;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.j1.mybatis.pojo.Order;
    import com.j1.mybatis.pojo.OrderUser;
    import com.j1.mybatis.pojo.User;
    import com.j1.mybatis.service.OrderService;
    
    public class OrderMapperTest {
        private OrderMapper orderMapper;
    
        private OrderService orderService;
        @Before
        public void setUp() throws Exception {
            try {
            
            ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
    
            this.orderService=context.getBean(OrderService.class);
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    
        /**
         * 一对一查询的第一种方法
         */
        @Test
        public void testQuerOrderAndUserByOrderNumY() {
            OrderUser orderUser = this.orderMapper
                    .querOrderAndUserByOrderNumY("20140921002");
            System.out.println(orderUser);
        }
    
        /**
         * 一对一的第二种查询
         */
        @Test
        public void testQuerOrderAndUserByOrderNum2() {
    //        Order order = orderMapper.querOrderAndUserByOrderNum2("20140921002");
            Order order=orderService.querOrderAndUserByOrderNum2("20140921002");
            System.out.println(order);
        }
    
        /**
         * 一对多的查询
         */
        @Test
        public void queryOrderAndUserAndOrderDetailByOrderNumber() {
            Order order = orderMapper
                    .queryOrderAndUserAndOrderDetailByOrderNumber("20140921002");
            System.out.println(order);
        }
    
        /**
         * 多对多的查询
         */
        @Test
        public void testQueryOrderAndUserAndOrderDetailAndItemByOrderNumber() {
            Order order = this.orderMapper
                    .queryOrderAndUserAndOrderDetailAndItemByOrderNumber("20140921001");
            System.out.println(order);
        }
    
    }

    1.   整合spring事务管理

    为什么要整合Spring的事务管理呢?

    先分析一下,其实这和mybatis没任何关系,只是事务管理用Spring来进行管理罢了.

    创建applicationContext-transaction.xml文件,

    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
        xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        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/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
        
        <!-- 定义事务管理器 -->
        <bean id="transactionManager"
            class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource" />
        </bean>
    
        <!-- 定义事务策略 -->
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                <!--所有以query开头的方法都是只读的 -->
                <tx:method name="query*" read-only="true" />
                <!--其他方法使用默认事务策略 -->
                <tx:method name="*" />
            </tx:attributes>
        </tx:advice>
    
        <aop:config>
            <!--pointcut元素定义一个切入点,execution中的第一个星号 用以匹配方法的返回类型,
                这里星号表明匹配所有返回类型。 com.abc.dao.*.*(..)表明匹配com.j1.mybatis.service包下的所有类的所有 
                方法 -->
            <aop:pointcut id="myPointcut" expression="execution(* com.j1.mybatis.*.*(..))" />
            <!--将定义好的事务处理策略应用到上述的切入点 -->
            <aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut" />
        </aop:config>
        
    </beans>
    package com.j1.mybatis.service;
    
    import static org.junit.Assert.*;
    
    import org.junit.Before;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.j1.mybatis.pojo.Order;
    
    
    public class OrderServiceTest {
        
        private OrderService orderService;
    
        @Before
        public void setUp() throws Exception {
            ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml","applicationContext-transaction.xml"});
            this.orderService = context.getBean(OrderService.class);
        }
    
        @Test
        public void querOrderAndUserByOrderNum2() {
            Order order = this.orderService.querOrderAndUserByOrderNum2("20140921001");
            System.out.println(order);
        }
    
    }

    log如下:

    2016-09-21 21:56:08,886 [main] [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[DEBUG] Creating instance of bean '(inner bean)#2369fbfa'
    2016-09-21 21:56:08,886 [main] [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[DEBUG] Returning cached instance of singleton bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
    2016-09-21 21:56:08,896 [main] [org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource]-[DEBUG] Adding transactional method [query*] with attribute [PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly]
    2016-09-21 21:56:08,896 [main] [org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource]-[DEBUG] Adding transactional method [*] with attribute [PROPAGATION_REQUIRED,ISOLATION_DEFAULT]
    2016-09-21 21:56:08,897 [main] [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[DEBUG] Returning cached instance of singleton bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
    2016-09-21 21:56:08,897 [main] [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[DEBUG] Returning cached instance of singleton bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
    2016-09-21 21:56:08,901 [main] [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[DEBUG] Finished creating instance of bean '(inner bean)#2369fbfa'
    2016-09-21 21:56:08,902 [main] [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[DEBUG] Invoking afterPropertiesSet() on bean with name 'txAdvice'
    2016-09-21 21:56:08,902 [main] [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[DEBUG] Finished creating instance of bean 'txAdvice'
    2016-09-21 21:56:08,902 [main] [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[DEBUG] Returning cached instance of singleton bean 'org.springframework.aop.config.internalAutoProxyCreator'
    2016-09-21 21:56:08,902 [main] [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[DEBUG] Returning cached instance of singleton bean 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0'
    2016-09-21 21:56:08,902 [main] [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[DEBUG] Returning cached instance of singleton bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor'
    2016-09-21 21:56:08,903 [main] [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[DEBUG] Returning cached instance of singleton bean 'org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor'
    2016-09-21 21:56:08,903 [main] [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[DEBUG] Returning cached instance of singleton bean 'orderMapper'
    2016-09-21 21:56:08,903 [main] [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[DEBUG] Returning cached instance of singleton bean 'userMapper'
    2016-09-21 21:56:08,906 [main] [org.springframework.context.support.ClassPathXmlApplicationContext]-[DEBUG] Unable to locate LifecycleProcessor with name 'lifecycleProcessor': using default [org.springframework.context.support.DefaultLifecycleProcessor@3fc12084]
    2016-09-21 21:56:08,907 [main] [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[DEBUG] Returning cached instance of singleton bean 'lifecycleProcessor'
    2016-09-21 21:56:08,911 [main] [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[DEBUG] Returning cached instance of singleton bean 'sqlSessionFactory'
    2016-09-21 21:56:08,913 [main] [org.springframework.core.env.PropertySourcesPropertyResolver]-[DEBUG] Searching for key 'spring.liveBeansView.mbeanDomain' in [systemProperties]
    2016-09-21 21:56:08,914 [main] [org.springframework.core.env.PropertySourcesPropertyResolver]-[DEBUG] Searching for key 'spring.liveBeansView.mbeanDomain' in [systemEnvironment]
    2016-09-21 21:56:08,914 [main] [org.springframework.core.env.PropertySourcesPropertyResolver]-[DEBUG] Could not find key 'spring.liveBeansView.mbeanDomain' in any property source. Returning [null]
    2016-09-21 21:56:08,915 [main] [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[DEBUG] Returning cached instance of singleton bean 'orderService'
    2016-09-21 21:56:08,932 [main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Creating a new SqlSession
    2016-09-21 21:56:08,956 [main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6848db81] was not registered for synchronization because synchronization is not active
    2016-09-21 21:56:08,976 [main] [org.springframework.jdbc.datasource.DataSourceUtils]-[DEBUG] Fetching JDBC Connection from DataSource
    2016-09-21 21:56:08,988 [main] [org.mybatis.spring.transaction.SpringManagedTransaction]-[DEBUG] JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@c59de6f] will not be managed by Spring
    2016-09-21 21:56:09,001 [main] [com.j1.mybatis.mapper.OrderMapper.querOrderAndUserByOrderNum2]-[DEBUG] ==>  Preparing: SELECT o.*, u.name, u.user_name, u.age FROM tb_order o LEFT JOIN tb_user u ON u.id = o.user_id WHERE o.order_number = ? 
    2016-09-21 21:56:09,107 [main] [com.j1.mybatis.mapper.OrderMapper.querOrderAndUserByOrderNum2]-[DEBUG] ==> Parameters: 20140921001(String)
    2016-09-21 21:56:09,264 [main] [com.j1.mybatis.mapper.OrderMapper.querOrderAndUserByOrderNum2]-[DEBUG] <==      Total: 1
    2016-09-21 21:56:09,264 [main] [com.alibaba.druid.pool.PreparedStatementPool]-[DEBUG] {conn-10010, pstmt-20000} enter cache
    2016-09-21 21:56:09,278 [main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6848db81]
    2016-09-21 21:56:09,279 [main] [org.springframework.jdbc.datasource.DataSourceUtils]-[DEBUG] Returning JDBC Connection to DataSource
    Order [id=1, userId=1, orderNumber=20140921001, user=User [id=1, userName=zhangsan, password=null, name=张三, age=30, sex=null, birthday=null, created=null, updated=null]]

    好了,至此,mybatis已全部结束,有问题,大家在一起沟通,互相交流

  • 相关阅读:
    HDU 1124 Factorial
    hdu 1690 Bus System
    hdu 1113 Word Amalgamation
    POJ 2482 Stars in Your Window
    hdu 1385 ZOJ 1456 Minimum Transport Cost(经典floyd)
    hdu 1907 John
    VMware 虚拟机 安装 UBuntu 9.10 命令模式转换成窗口模试
    #pragma CODE_SEG __NEAR_SEG NON_BANKED详解
    Ubuntu 下Hadoop 伪分布式 hadoop0.20.2.tar.gz 的安装
    文件拷贝代码以及疑问
  • 原文地址:https://www.cnblogs.com/wangchuanfu/p/5891964.html
Copyright © 2011-2022 走看看