• 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已全部结束,有问题,大家在一起沟通,互相交流

  • 相关阅读:
    <li>标签在ie6下的上下间隔的BUG解决办法
    win7 瘦身 减肥 记录!
    学习系统封装半年经验总结!
    DIV 类似 hover 悬停效果 鼠标移动上去变化
    解决 WIN7 部署 安装驱动包时出现的驱动签名提示 办法!
    Windows 7 瘦身大全 系统减肥 轻松 瘦身 减肥 3个G
    JS 判断 取 当前系统类型 可用来定义某些WIN7系统和XP系统下字体区别
    JS 判断 当前浏览器类型
    EasyBoot常用的命令
    Win7封装保持任务栏锁定项不变的解决方法
  • 原文地址:https://www.cnblogs.com/wangchuanfu/p/5891964.html
Copyright © 2020-2023  润新知