1.注解开发和xml配置对比图
2.Spring整合mybatis
在进行企业级开发的时候,除了将自己写的类让Spring管理之外,还有一部分重要的工作就是使用第三方的技术。下面结合IoC和DI,整合2个常用技术。
我们需要通过spring来简化开发,之前我们使用mybatis都是导入一些配置,比如mybatis的xml配置,但是spring可以通过注解来舍弃掉配置,下面是一个整合案例,我放在这只是想回过头来看的时候有个大致整合结构哈哈哈
1.Mybatis程序核心对象分析
- 从图中可以获取到,真正需要交给Spring管理的是SqlSessionFactory
- 整合Mybatis,就是将Mybatis用到的内容交给Spring管理,分析下配置文件
说明:
- 第一行读取外部properties配置文件,Spring有提供具体的解决方案
@PropertySource
,需要交给Spring - 第二行起别名包扫描,为SqlSessionFactory服务的,需要交给Spring
- 第三行主要用于做连接池,Spring可以通过Druid连接池,这块也需要交给Spring
- 前面三行一起都是为了创建SqlSession对象用的,那么用Spring管理SqlSession对象吗?SqlSession是由SqlSessionFactory创建出来的,所以只需要将SqlSessionFactory交给Spring管理即可。
- 第四行是Mapper接口和映射文件
如果使用注解就没有该映射文件
,这个是在获取到SqlSession以后执行具体操作的时候用,所以它和SqlSessionFactory创建的时机都不在同一个时间,可能需要单独管理。
2.spring整合mybatis大致需要做两件事
第一件事是:Spring要管理MyBatis中的SqlSessionFactory
第二件事是:Spring要管理Mapper接口的扫描
3.需要导入依赖
<dependencies>
<--spring依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<--连接池依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<--mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<!--mysql 驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
<!-- 引入spring的jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.8</version>
</dependency>
<dependency>
<!--Spring与Mybatis整合的jar包这个jar包mybatis在前面,是Mybatis提供的-->
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<--这是整合junit需要的依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<--测试依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
4.创建spring主配置类SpringConfig
主配置类中读properties并引入数据源配置类
主配置类中引入Mybatis配置类
package com.hnu.config;
//配置类注解
@Configuration
//包扫描,主要扫描的是项目中的AccountServiceImpl类
@ComponentScan({"com.hnu"})
//加载配置文件,里面存放连接jdbc的信息,就是下图中的需要注入的简单数据类型
@PropertySource("classpath:jdbc.properties")
//@Import注解在配置类中只能写一次
@Import({JdbcConfig.class,MybatisConfig.class})
public class SpringConfig {
}
5.创建数据源的配置类JdbcConfig
package com.hnu.config;
public class JdbcConfig {
//简单数据类型注入,只有加载了配置文件才会通过${key}引用成功
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.userName}")
private String userName;
@Value("${jdbc.passWord}")
private String passWord;
//引用数据类型注入只需要传入需要传入的类的类型,就是在dataSource()括号内传入接口名,例如public DataSource dataSource(BookDao bookDao){...}
@Bean
public DataSource dataSource() {
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(userName);
ds.setPassword(passWord);
System.out.println(ds.getUrl());
System.out.println(ds.getUsername());
//返回数据可连接信息,作为连接数据库使用
return ds;
}
}
6.创建Mybatis配置类MybatisConfig并配置SqlSessionFactory
package com.hnu.config;
public class MybatisConfig {
//定义bean,SqlSessionFactoryBean,用于产生SqlSessionFactory对象
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
//设置模型类的别名扫描
ssfb.setTypeAliasesPackage("com.hnu.domain");
//设置数据源,就是数据库连接必要的用户名密码url和驱动这些,在jdbcconfig配置中返回的datasource
ssfb.setDataSource(dataSource);
return ssfb;
}
//定义bean,返回MapperScannerConfigurer对象
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer msc = new MapperScannerConfigurer();
msc.setBasePackage("com.hnu.dao");
return msc;
}
}
设置模型类的别名扫描相当于xml配置文件中的这部分
定义bean,返回MapperScannerConfigurer对象相当于xml配置文件中的这部分
xml配置与spring整合各部分对比:
-
方法中有一个参数为dataSource,当前Spring容器中已经创建了Druid数据源,类型刚好是DataSource类型,此时在初始化SqlSessionFactoryBean这个对象的时候,发现需要使用DataSource对象,而容器中刚好有这么一个对象,就自动加载了DruidDataSource对象。
-
使用MapperScannerConfigurer加载Dao接口,创建代理对象保存到IOC容器中
- 这个MapperScannerConfigurer对象也是MyBatis提供的专用于整合的jar包中的类,用来处理原始配置文件中的mappers相关配置,加载数据层的Mapper接口类
- MapperScannerConfigurer有一个核心属性basePackage,就是用来设置所扫描的包路径
7.Spring与Mybatis的整合其中主要用到的两个类分别是:
- SqlSessionFactoryBean
- MapperScannerConfigurer
8.mapper接口与xml中sql语句书写在spring中的对应的位置
没整合时:
整合后:
AccountService中书写的相当于没整合时的mapper
例如这个例子中的增删改查
package com.hnu.service;
public interface AccountService {
void save(Account account);
void delete(Integer id);
void update(Account account);
List<Account> findAll();
Account findById(Integer id);
}
AccountServiceImpl是AccountService的实现类,实现接口中的方法
package com.hnu.service.impl;
@Service
public class AccountServiceImpl implements AccountService {
//按类型注入依赖,在AccountDao中书写了sql语句,需要注入到实现类中使用
@Autowired
private AccountDao accountDao;
@Override
public void save(Account account) {
accountDao.save(account);
}
@Override
public void delete(Integer id) {
accountDao.delete(id);
}
@Override
public void update(Account account) {
accountDao.update(account);
}
@Override
public List<Account> findAll() {
return accountDao.findAll();
}
@Override
public Account findById(Integer id) {
return accountDao.findById(id);
}
}
AccountDao相当于xml,在里面书写sql语句
package com.hnu.dao;
public interface AccountDao {
@Insert("insert into tbl_account(name,money)values(#{name},#{money})")
void save(Account account);
@Delete("delete from tbl_account where id = #{id} ")
void delete(Integer id);
@Update("update tbl_account set name = #{name} , money = #{money} where id = #{id} ")
void update(Account account);
@Select("select * from tbl_account")
List<Account> findAll();
@Select("select * from tbl_account where id = #{id} ")
Account findById(Integer id);
}
9.最后运行查看一下吧~
package com.hnu;
public class App2 {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
//创建AccountService类型对象,来调用实现类中的方法,实现类中注入了sql语句的依赖,这样就可以完成对数据库的操作了
AccountService accountService = ctx.getBean(AccountService.class);
//调用按id查询
Account account = accountService.findById(1);
System.out.println(account);
}
}
3.spring整合junit
在上述环境的基础上,我们来对Junit进行整合。
步骤1:引入整合junit的依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
步骤2:编写测试类
//设置类运行器
@RunWith(SpringJUnit4ClassRunner.class)
//设置Spring环境对应的配置类
@ContextConfiguration(classes = {SpringConfig.class})//加载配置类
public class AccountServiceTest {
//支持自动装配注入bean
@Autowired
private AccountService accountService;
@Test
public void testFindById(){
System.out.println(accountService.findById(1));
}
@Test
public void testFindAll(){
System.out.println(accountService.findAll());
}
}
注意事项:
- 单元测试,如果测试的是注解配置类,则使用
@ContextConfiguration(classes = 配置类.class)
- 单元测试,如果测试的是配置文件,则使用
@ContextConfiguration(locations={配置文件名,...})
- Junit运行后是基于Spring环境运行的,所以Spring提供了一个专用的类运行器,这个务必要设置,这个类运行器就在Spring的测试专用包中提供的,导入的坐标就是这个东西
SpringJUnit4ClassRunner
- 上面两个配置都是固定格式,当需要测试哪个bean时,使用自动装配加载对应的对象,下面的工作就和以前做Junit单元测试完全一样了
- @RunWith 测试类注解 测试类定义上方 设置Junit运行器
- @ContextConfiguration 测试类注解 测试类定义上方 设置Junit加载的Spring核心配置
4.结束语
每天把自己学的内容用博客记录下来,一天写一点,记一点,慢慢的就多了,以后忘记了回来找也方便,继续加油!奥利给!!