Spring整合MyBatis过程分析

2021-08-06  本文已影响0人  JohnYuCN

使用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

上一篇下一篇

猜你喜欢

热点阅读