• spring整合mybatis


    10.spring整合mybatis

    步骤:

    • 导入依赖

    junit/mybatis/mysql/spring/aop织入/mybatis-spring(new)

    • 编写配置文件
    • 测试
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.2</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.3.19</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.10</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.15</version>
    </dependency>
    <!--spring 操作数据库需要spring-jdbc,并且事务包也包含进去了spring-tx-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.3.20</version>
    </dependency>
     <dependency>
         <groupId>org.aspectj</groupId>
         <artifactId>aspectjweaver</artifactId>
         <version>1.9.9.1</version>
     </dependency>
    
     <dependency>
         <groupId>org.mybatis</groupId>
         <artifactId>mybatis-spring</artifactId>
         <version>2.0.7</version>
     </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 注意:MyBatis-Spring 版本区别:
    MyBatis-SpringMyBatisSpring FrameworkSpring BatchJava
    2.03.5+5.0+4.0+Java 8+
    1.33.4+3.2.2+2.1+Java 6+

    10.1 使用SqlSession

    • 官方文档:http://mybatis.org/spring/zh/index.html
    • Spring 使用 MyBatis,需要在 Spring 应用上下文中定义至少两样东西:一个 SqlSessionFactory 和至少一个数据映射器类。
    • 在 MyBatis-Spring 中,可使用 SqlSessionFactoryBean来创建 SqlSessionFactory。 要配置这个工厂 bean;
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <!--mybatis有mapper和configuration两种配置文件 后者中的所有配置都可以被Spring整合到sessionFactory中来-->
            <property name="configLocation" value="classpath:mybatis-config.xml"/>
            <property name="mapperLocations" value="classpath:com/zk/dao/*.xml"/>
        </bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    注意:SqlSessionFactory 需要一个 DataSource(数据源)。这可以是任意的 DataSource,只需要和配置其它 Spring 数据库连接一样配置它就可以了。

    • 数据库配置文件db.properties
    driver=com.mysql.cj.jdbc.Driver
    url=jdbc:mysql://localhost:3306/school?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
    #导入的properties文件中不要将user定为username,否者会获取系统用户名
    usernames=root
    password=123456
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 定义jdbc类型数据源
    <!--引入 db.properties 中的配置-->
    <context:property-placeholder location="classpath:db.properties"/>
    
    <!--定义数据源 Bean
    使用spring数据源替换mybatis的数据源c3p0,druid,dbcp,这里使用的是spring-jdbc提供的org.springframework.jdbc.datasource-->
    <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
        <property name="driverClassName" value="${driver}"/>
        <property name="username" value="${usernames}"/>
        <property name="url" value="${url}"/>
        <property name="password" value="${password}"/>
    </bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 定义c3p0类型数据源,其他类型的数据源配置与此相同
    	<!--1.关联数据库配置文件-->
        <context:property-placeholder location="classpath:database.properties"/>
    	<!--2.连接池
                dpcp:半自动化操作,不能自动连接
                c3p0:自动化操作(自动化的加载配置文件,并且可以自动设置到对象中)
                druid:
                hikari:-->
        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
            <property name="driverClass" value="${jdbc.driver}"/>
            <property name="jdbcUrl" value="${jdbc.url}"/>
            <property name="user" value="${jdbc.username}"/>
            <property name="password" value="${jdbc.password}"/>
            <!-- c3p0连接池的私有属性 -->
            <property name="maxPoolSize" value="30"/>
            <property name="minPoolSize" value="1"/>
            <!-- 关闭连接后不自动commit -->
            <property name="autoCommitOnClose" value="false"/>
            <!-- 获取连接超时时间 -->
            <property name="checkoutTimeout" value="10000"/>
            <!-- 当获取连接失败重试次数 -->
            <property name="acquireRetryAttempts" value="2"/>
        </bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 在SqlSessionFactory中整合mybatis,可以完全不用配置mybatis-config.xml文件,在SqlSessionFactoryBean中都有替换的属性,但一般保留mybatis-config.xml在其中配置别名和设置(日志)信息
    <!--要让Spring使用 MyBatis,需要在 Spring 应用上下文中定义至少两样东西:
    一个 SqlSessionFactory 和至少一个数据映射器类。-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!--mybatis有mapper和configuration两种配置文件 后者中的所有配置都可以被Spring整合到sessionFactory中来-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <property name="mapperLocations" value="classpath:com/zk/dao/*.xml"/>
    </bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • mybatis-config.xml文件留存信息
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <!--只保留两项,setting,typeAliases-->
        <settings>
            <setting name="logImpl" value="STDOUT_LOGGING"/>
        </settings>
        <typeAliases>
            <package name="com.zk.pojo"/>
        </typeAliases>
    </configuration>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 接下来就可以使用SqlSession了,可以通过以下两种方式来实现session

    在 MyBatis 中,你可以使用 SqlSessionFactory 来创建 SqlSession。 一旦你获得一个 session 之后,你可以使用它来执行映射了的语句,提交或回滚连接,最后,当不再需要它的时候,你可以关闭 session。

    使用 MyBatis-Spring 之后,你不再需要直接使用 SqlSessionFactory 了,因为你的 bean 可以被注入一个线程安全的 SqlSession,它能基于 Spring 的事务配置来自动提交、回滚、关闭 session。

    10.2 方式1:通过SqlSessionTemplate来实现通过SqlSession

    • SqlSessionTemplate 是 MyBatis-Spring 的核心。作为 SqlSession 的一个实现,这意味着可以使用它无缝代替你代码中已经在使用的 SqlSessionSqlSessionTemplate线程安全的,可以被多个 DAO 或映射器所共享使用。
    • SqlSessionTemplate使用的 SqlSession 与当前 Spring 的事务相关。 此外,它管理 session 的生命周期,包含必要的关闭、提交或回滚操作

    由于模板可以参与到 Spring 的事务管理中,并且由于其是线程安全的,可以供多个映射器类使用,你应该总是SqlSessionTemplate 来替换 MyBatis 默认的 DefaultSqlSession 实现。在同一应用程序中的不同类之间混杂使用可能会引起数据一致性的问题。

    <!--SqlSessionTemplate就是sqlSession,这个sqlSession是线程安全的,
    基于Spring 的事务配置来自动提交、回滚、关闭 session。
    批量创建一些 SqlSession-->
    <bean class="org.mybatis.spring.SqlSessionTemplate" id="sqlSession">
        <!--只能用构造器,SqlSessionTemplate没有setter方法-->
        <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 然后将这个 bean 就可以直接注入到你的 DAO bean 中了。你需要在你的 bean 中添加一个 SqlSession 属性,所以需要一个dao实现类来使用SqlSession,并将实现类注册bean,供业务层使用。

    要用spring管理的sqlSession,不能直接从容器中getBean取dao接口的bean,所以需要实现类来封装

    之前需要业务层实例sqlSession,管理sqlSession,现在只调用实现类即可,sqlSession管理交给spring去做

    public class UserMapperImpl implements UserMapper{
        /*
        * spring整合mybatis体现在这个sqlSession实例上
        * */
        private SqlSessionTemplate sqlSession;
    
        public void setSqlSession(SqlSessionTemplate sqlSession) {
            this.sqlSession = sqlSession;
        }
        @Override
        public List<User> getUserList() {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            List<User> userList = mapper.getUserList();
            return userList;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 注册实现类,之后就可以从spring中使用这个实现类,即spring整合mybatis步骤完成
    <bean class="com.zk.dao.UserMapperImpl" id="userMapper">
        <property name="sqlSession" ref="sqlSession"/>
    </bean>
    
    • 1
    • 2
    • 3
    • 完整整合步骤见下面例子:

    • 实体类

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User {
        private int id;
        private String name;
        private String pwd;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • dao接口及mapper.xml
    public interface UserMapper {
    
        List<User> getUserList();
    }
    
    • 1
    • 2
    • 3
    • 4
    <?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">
    <!--namespace绑定对应的UserMapper即实现-->
    <mapper namespace="com.zk.dao.UserMapper">
    
        <!--返回集合对象类型也是用resultType指明集合泛型-->
        <select id="getUserList" resultType="user">
            select * from school.user
        </select>
    </mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 编写数据源db.properties
    driver=com.mysql.cj.jdbc.Driver
    url=jdbc:mysql://localhost:3306/school?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
    #导入的properties文件中不要将user定为username,否者会获取系统用户名
    usernames=root
    password=123456
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 在spring配置文件整合mybatis,spring-mybatis-congfig.xml
    • spring管理数据源
    • spring管理sqlSessionFactory
    • spring管理SqlSessionTemplate
    <?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:context="http://www.springframework.org/schema/context"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop.xsd">
        
        <!--引入 db.properties 中的配置-->
        <context:property-placeholder location="classpath:db.properties"/>
    
        <!--定义数据源 Bean
        使用spring数据源替换mybatis的数据源c3p0,druid,dbcp,这里使用的是spring-jdbc提供的org.springframework.jdbc.datasource-->
        <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
            <property name="driverClassName" value="${driver}"/>
            <property name="username" value="${usernames}"/>
            <property name="url" value="${url}"/>
            <property name="password" value="${password}"/>
        </bean>
        <!--要让Spring使用 MyBatis,需要在 Spring 应用上下文中定义至少两样东西:
        一个 SqlSessionFactory 和至少一个数据映射器类。-->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <!--mybatis有mapper和configuration两种配置文件 后者中的所有配置都可以被Spring整合到sessionFactory中来-->
            <property name="configLocation" value="classpath:mybatis-config.xml"/>
            <property name="mapperLocations" value="classpath:com/zk/dao/*.xml"/>
        </bean>
    
        <!--SqlSessionTemplate就是sqlSession,这个sqlSession是线程安全的,
        基于Spring 的事务配置来自动提交、回滚、关闭 session。
        批量创建一些 SqlSession-->
        <bean class="org.mybatis.spring.SqlSessionTemplate" id="sqlSession">
            <!--只能用构造器,SqlSessionTemplate没有setter方法-->
            <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
        </bean>
    
    </beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 依据面向对象封装思想,引用spring管理的SqlSessionTemplate进行dao操作需要一个dao接口实现类
    /**
     *  面向对象:封装思想:service不要直接使用sqlSession操作数据库,
     *  要调用mapper的方法,但是mapper是个接口,没有实现类,这边要给他建一个实现类来让mapper去调用
     * 主要是三个mapper放在一个包里显得乱,xml该放在resources里面,然后实现类放在mapper下面的impl包里会好一点
     **/
    public class UserMapperImpl implements UserMapper{
        /*
        * spring整合mybatis体现在这个sqlSession实例上
        * */
        private SqlSessionTemplate sqlSession;
    
        public void setSqlSession(SqlSessionTemplate sqlSession) {
            this.sqlSession = sqlSession;
        }
        @Override
        public List<User> getUserList() {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            List<User> userList = mapper.getUserList();
            return userList;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 将dao接口实现类注册到spring中,此处注意分工思想applicationContext.xml
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop.xsd">
        <!--开启注解扫描-->
        <context:component-scan base-package="com.zk"/>
    
        <!--spring-mybatis-congfig整合逻辑放这个配置文件不动了-->
        <import resource="classpath:spring-mybatis-congfig.xml"/>
        <!--同样的还有spring-mvc配置也是这样集成进来-->
    
        <!--本文件注入bean被调用-->
        <bean class="com.zk.dao.UserMapperImpl" id="userMapper">
            <property name="sqlSession" ref="sqlSession"/>
        </bean>
    </beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 测试及结果
    @Test
    public void test02(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //要用spring管理的sqlSession,不能直接getBean取dao接口的bean,所以需要实现类来封装
        UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
        //之前需要业务层实例sqlSession,管理sqlSession,现在只调用实现类即可,sqlSession管理交给spring去做
        List<User> userList = userMapper.getUserList();
        userList.forEach(var-> System.out.println(var.toString()));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    Connected to the target VM, address: '127.0.0.1:50031', transport: 'socket'
    User(id=1, name=zs, pwd=123456)
    User(id=2, name=mary, pwd=123456)
    User(id=3, name=sandy, pwd=789456)
    User(id=4, name=tony, pwd=132456)
    User(id=5, name=test, pwd=111111)
    User(id=6, name=tom, pwd=789456)
    User(id=7, name=Jom, pwd=123456)
    User(id=8, name=小明, pwd=789)
    User(id=9, name=小龙, pwd=456)
    User(id=10, name=小林, pwd=123)
    User(id=11, name=Jom, pwd=123456)
    User(id=12, name=hom, pwd=123456)
    User(id=13, name=zail, pwd=987654)
    Disconnected from the target VM, address: '127.0.0.1:50031', transport: 'socket'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    10.3 方式二:使用SqlSessionDaoSupport

    • SqlSessionDaoSupport 是一个抽象的支持类,用来为你提供 SqlSession。调用 getSqlSession() 方法你会得到一个 SqlSessionTemplate,之后可以用于执行 SQL 方法,使得整合过程更加简单。

    • 修改dao实现类,会发现不用在实现类中注入SqlSession,容器也不用在配置SqlSessionTemplate类型的bean了,SqlSessionDaoSupport帮助做了SqlSessionTemplate的注入。

    public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper{
    
        @Override
        public List<User> getUserList() {
            return getSqlSession().getMapper(UserMapper.class).getUserList();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 注册这个实现类,需要注入sqlSessionFactory这个属性。

    SqlSessionDaoSupport 需要通过属性设置一个 sqlSessionFactorySqlSessionTemplate。如果两个属性都被设置了,那么 SqlSessionFactory 将被忽略。

    <bean class="com.zk.dao.UserMapperImpl2" id="userMapperImpl2">
        <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>
    
    • 1
    • 2
    • 3
    • 测试即结果
    @Test
    public void test03(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //要用spring管理的sqlSession,不能直接getBean取dao接口的bean,所以需要实现类来封装
        UserMapper userMapper = context.getBean("userMapperImpl2", UserMapper.class);
        //之前需要业务层实例sqlSession,管理sqlSession,现在只调用实现类即可,sqlSession管理交给spring去做
        List<User> userList = userMapper.getUserList();
        userList.forEach(var-> System.out.println(var.toString()));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@82ea68c] will not be managed by Spring
    ==>  Preparing: select * from school.user
    ==> Parameters: 
    <==    Columns: id, name, pwd
    <==        Row: 1, zs, 123456
    <==        Row: 2, mary, 123456
    <==        Row: 3, sandy, 789456
    <==        Row: 4, tony, 132456
    <==        Row: 5, test, 111111
    <==        Row: 6, tom, 789456
    <==        Row: 7, Jom, 123456
    <==        Row: 8, 小明, 789
    <==        Row: 9, 小龙, 456
    <==        Row: 10, 小林, 123
    <==        Row: 11, Jom, 123456
    <==        Row: 12, hom, 123456
    <==        Row: 13, zail, 987654
    <==      Total: 13
    Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@272ed83b]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    本专栏下一篇:声明式事务

  • 相关阅读:
    百度编辑器 Ueditor 视频上传时 目录创建失败 解决办法
    java毕业设计中国民航酒店分销系统Mybatis+系统+数据库+调试部署
    设计模式之备忘录模式
    MySQL遵循最左前缀匹配原则!面试官:回去等通知吧
    MySQL 及 jdbc 问题汇总
    为什么电脑运行越来越慢?解决方法又是什么呢?
    DayDayUp:计算机技术与软件专业技术资格证书之《系统集成项目管理工程师》课程讲解之十大知识领域之4核心—项目进度管理
    RocketMQ安装部署
    linux 常用命令
    关于#sql#的问题:高斯库中查询一个字段所有值中是否包含某个值,有没有简单的函数,不用切割函数的sql语录比较简单的推荐下
  • 原文地址:https://blog.csdn.net/weixin_42045639/article/details/125530236