使用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>
- 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));
}
}
附录:
- 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>
- Employee.java
package cn.johnyu.pojo;
import lombok.Data;
@Data
public class Employee {
private Integer id;
private String ename;
private String job;
}
- 项目结构:
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
网友评论