美文网首页
Spring整合MyBatis过程分析

Spring整合MyBatis过程分析

作者: JohnYuCN | 来源:发表于2021-08-06 23:31 被阅读0次

    使用SpringBoot让我们逐渐丢失了对Spring整合原理的追求。


    东京千代田区 皇居外苑 2019-01-29

    1. pom.xml

            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-spring</artifactId>
                <version>2.0.6</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.5.7</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.26</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.20</version>
            </dependency>
    
    1. DataSource及SqlSessionFactory的指定:
      (1)此处使用基础配置的方式产生SessionFactory,同时为其指定了MapperLocation,为此后的Mapper的生成方式相衔接。
      (2)EmpMapper.xml的内容不是关键,附录中会列出。
        @Bean
        public DataSource dataSource() throws Exception{
            SimpleDriverDataSource ds=new SimpleDriverDataSource();
            ds.setDriverClass(com.mysql.cj.jdbc.Driver.class);
            ds.setUrl("jdbc:mysql://localhost:3306/test");
            ds.setUsername("root");
            ds.setPassword("123");
            return ds;
        }
        @Value("classpath:cn/johnyu/mapper/EmpMapper.xml")
        private Resource resource;
        @Bean
        public SqlSessionFactory sqlSessionFactory() throws Exception{
            SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
            factoryBean.setDataSource(dataSource());
            factoryBean.setMapperLocations(resource);
            return factoryBean.getObject();
        }
    

    3. 两种不同方式的Mapper的生成:

    (1)使用MapperFactoryBean的方式:

        @Bean
        public EmpMapper empMapper() throws Exception{
            MapperFactoryBean<EmpMapper> factoryBean=new MapperFactoryBean<>();
            factoryBean.setSqlSessionFactory(sqlSessionFactory());
            factoryBean.setMapperInterface(EmpMapper.class);
            return factoryBean.getObject();
        }
    

    (2) 使用SqlSessionTemplate的方式:

        @Bean
        public EmpMapper empMapper() throws Exception{
            SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory());
            return sqlSessionTemplate.getMapper(EmpMapper.class);
        }
    

    以上,两种方式都是使用了人肉方式使用了SqlSessionFactory,来产生Mapper对象,这也是整合的基础,但方式较为笨重,也不无法利用声明式事务管理。

    4. 改良:

    (1)为Mapper接口添加注解:

    package cn.johnyu.mapper;
    
    import cn.johnyu.pojo.Employee;
    import org.apache.ibatis.annotations.Mapper;
    import org.apache.ibatis.annotations.Param;
    import org.springframework.stereotype.Component;
    
    @Mapper
    @Component
    public interface EmpMapper {
        Employee load(Integer id);
        int add(Employee employee);
    }
    

    (2) 在配置类上进行注解:

    @Configuration
    @MapperScan(basePackages = "cn.johnyu.mapper")
    @ComponentScan(basePackages = "cn.johnyu.mapper")
    public class MyApp {
    ...
    

    (3) SqlSessionFactory产生方式没有变化,但需要注意:

        /**
         * 在使用MapperScan模式下,如果保证xml与mapper的classpath相同,则无需进行以下配置
         */
        @Value("classpath:cn/johnyu/mapper/EmpMapper.xml")
        private Resource resource;
    
        @Bean
        public SqlSessionFactory sqlSessionFactory() throws Exception{
            SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
            factoryBean.setDataSource(dataSource());
            //在使用MapperScan模式下,如果保证xml与mapper的classpath相同,则无需进行以下配置
            factoryBean.setMapperLocations(resource);
            return factoryBean.getObject();
        }
    

    此时的mapper便会由Mbatis和Spring共同生产代理对象。

    (4) 声明式事务管理:
    配置类上的变化:

    @Configuration
    @MapperScan(basePackages = "cn.johnyu.mapper")
    @ComponentScan(basePackages = {"cn.johnyu.mapper","cn.johnyu.service"})
    @EnableTransactionManagement
    public class MyApp {
        @Bean
        public TransactionManager transactionManager() throws Exception{
            DataSourceTransactionManager manager = new DataSourceTransactionManager();
            manager.setDataSource(dataSource());
            return manager;
        }
    

    (5) 业务类--声明式事务:

    package cn.johnyu.service;
    
    import cn.johnyu.mapper.EmpMapper;
    import cn.johnyu.pojo.Employee;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    import java.util.List;
    
    @Service
    public class EmpServiceImpl implements EmpService{
        @Autowired
        private EmpMapper mapper;
        @Transactional
        @Override
        public void add(List<Employee> list) {
            list.stream().forEach(employee -> mapper.add(employee));
        }
    }
    
    

    附录:

    1. EmpMapper.xml
    <?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">
    <mapper namespace="cn.johnyu.mapper.EmpMapper">
        <select id="load" resultType="cn.johnyu.pojo.Employee">
            select empno as id,ename,job from emp where empno=#{id}
        </select>
        <insert id="add" parameterType="cn.johnyu.pojo.Employee" keyProperty="id" useGeneratedKeys="true">
            insert into emp (ename,job) values (#{ename},#{job})
        </insert>
    </mapper>
    
    1. Employee.java
    package cn.johnyu.pojo;
    
    import lombok.Data;
    
    @Data
    public class Employee {
        private Integer id;
        private String ename;
        private String job;
    }
    
    1. 项目结构:
    src $ tree -L 6 .
    .
    ├── main
    │   ├── java
    │   │   └── cn
    │   │       └── johnyu
    │   │           ├── MyApp.java
    │   │           ├── mapper
    │   │           │   └── EmpMapper.java
    │   │           ├── pojo
    │   │           │   └── Employee.java
    │   │           └── service
    │   │               ├── EmpService.java
    │   │               └── EmpServiceImpl.java
    │   └── resources
    │       └── cn
    │           └── johnyu
    │               └── mapper
    │                   └── EmpMapper.xml
    └── test
        └── java
    
    

    相关文章

      网友评论

          本文标题:Spring整合MyBatis过程分析

          本文链接:https://www.haomeiwen.com/subject/qlnivltx.html