Spring整合Mybatis
在Spring中,除了将自己写的类让Spring管理之外,还有一部分重要的工作就是使用第三方的技术。下面结合IoC和DI,整合Mybatis技术,进一步加深对Spring的使用理解。
环境准备
-
准备数据库
因为mybatis是用来操作数据库的,所有先创建一个数据库和表。下面是的count表有 id,usernamename,password三个字段。create database mybatis character set utf8; use spring_db; create table tb_user( id int primary key auto_increment, usernamename varchar(35), password varchar(35) );
-
创建maven项目导入相应的依赖坐标:spring,Druid数据源,mybatis,mysql.
<dependencies> <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> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.6</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> </dependencies>
-
根据表来创建实体类
public class Account implements Serializable { private Integer id; private String username; private Integer password; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Integer getPassword() { return password; } public void setPassword(Integer password) { this.password = password; } @Override public String toString() { return "Account{" + "id=" + id + ", username='" + username + '\'' + ", password=" + password + '}'; } }
-
创建Dao接口用来操作数据库
public interface AccountDao { //增加数据 @Insert("insert into tb_user(username,password)values(#{username},#{password})") void save(Account account); //删除数据 @Delete("delete from tb_user where id = #{id} ") void delete(Integer id); //修改数据 @Update("update tb_user set username = #{username} , password = #{password} where id = #{id} ") void update(Account account); //查看所有数据 @Select("select * from tb_user") List<Account> findAll(); //根据id值查看数据 @Select("select * from tb_user where id = #{id} ") Account findById(Integer id); }
-
创建Service接口及其实现类,这里用注解配置Bean和Autowired依赖注入。
public interface AccountService { void save(Account account); void delete(Integer id); void update(Account account); List<Account> findAll(); Account findById(Integer id); } @Service public class AccountServiceImpl implements AccountService { @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() { List<Account> all = accountDao.findAll(); return all; } @Override public Account findById(Integer id) { Account byId = accountDao.findById(id); return byId; } }
-
添加Properties文件
在resources文件夹下创建,用于配置数据库连接信息。这里根据自己数据库的信息进行配置。jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mybatis?useSSL=false jdbc.username=root jdbc.password=1234
-
配置Mybatis核心配置文件
<?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> <!--读取外部properties配置文件--> <properties resource="jdbc.properties"></properties> <!--别名扫描的包路径--> <typeAliases> <package name="com.itheima.domain"/> </typeAliases> <!--数据源--> <environments default="mysql"> <environment id="mysql"> <transactionManager type="JDBC"></transactionManager> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"></property> <property name="url" value="${jdbc.url}"></property> <property name="username" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> </dataSource> </environment> </environments> <!--映射文件扫描包路径--> <mappers> <package name="com.itheima.dao"></package> </mappers> </configuration>
-
创建测试类
public class App { public static void main(String[] args) throws IOException { // 1. 创建SqlSessionFactoryBuilder对象 SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); // 2. 加载SqlMapConfig.xml配置文件 InputStream inputStream = Resources.getResourceAsStream("Mybatis-config"); // 3. 创建SqlSessionFactory对象 SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream); // 4. 获取SqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); // 5. 执行SqlSession对象执行查询,获取结果User AccountDao accountDao = sqlSession.getMapper(AccountDao.class); List<Account> all = accountDao.findAll(); Account ac = accountDao.findById(2); System.out.println(ac); System.out.println(all); // 6. 释放资源 sqlSession.close(); } }
这里调用两个查询方法并打印到控制台
整合mybatis
Mybatis的基础环境我们已经准备好了,接下来就得分析下在上述的内容中,哪些对象可以交给Spring来管理?
-
Mybatis程序核心对象分析
- 这三行是初始化创建SqlSessionFactory
// 1. 创建SqlSessionFactoryBuilder对象 SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); // 2. 加载SqlMapConfig.xml配置文件 InputStream inputStream = Resources.getResourceAsStream("Mybatis-config"); // 3. 创建SqlSessionFactory对象 SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
-
这两行是获取连接,获取实现
// 4. 获取SqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); // 5. 执行SqlSession对象执行查询,获取结果User AccountDao accountDao = sqlSession.getMapper(AccountDao.class);
-
这两行是获取数据层接口
List<Account> all = accountDao.findAll(); Account ac = accountDao.findById(2);
-
最后一行为关闭资源
sqlSession.close();
从分析中可以获取到,真正需要交给Spring管理的是SqlSessionFactory
-
整合Mybatis分析配置文件
-
初始化属性数据
<properties resource="jdbc.properties"></properties>
-
初始化类型别名
<typeAliases> <package name="com.itheima.domain"/> </typeAliases>
-
数据源的配置,初始化dataSource
<environments default="mysql"> <environment id="mysql"> <transactionManager type="JDBC"></transactionManager> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"></property> <property name="url" value="${jdbc.url}"></property> <property name="username" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> </dataSource> </environment> </environments>
-
初始化配置映射
<mappers> <package name="com.itheima.dao"></package> </mappers>
说明:
- 第一行读取外部properties配置文件,Spring有提供具体的解决方案
@PropertySource
,需要交给Spring - 第二行起别名包扫描,为SqlSessionFactory服务的,需要交给Spring
- 第三行主要用于做连接池,Spring之前我们已经整合了Druid连接池,这块也需要交给Spring
- 前面三行一起都是为了创建SqlSession对象用的,那么用Spring管理SqlSession对象吗?回忆下SqlSession是由SqlSessionFactory创建出来的,所以只需要将SqlSessionFactory交给Spring管理即可。
- 第四行是Mapper接口和映射文件[如果使用注解就没有该映射文件],在·以后执行具体操作的时候用,所以它和SqlSessionFactory创建的时机都不在同一个时间,可能需要单独管理。
-
从上面的分析得出可以让Spring进行管理的有Mybatis中的SqlSessionFactory和初始化配置映射 Mapper接口还有数据库的配置。
-
在项目中Pom.xml文件中导入mybatis整合Spring的依赖坐标
<dependency> <!--Spring操作数据库需要该jar包--> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.10.RELEASE</version> </dependency> <dependency> <!-- Spring与Mybatis整合的jar包 这个jar包mybatis在前面,是Mybatis提供的 --> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.0</version> </dependency>
-
创建Spring的配置类
//配置类注解 @Configuration //包扫描,主要扫描的是项目中的AccountServiceImpl类 @ComponentScan("com.itheima") public class SpringConfig { }
-
创建数据源的配置类,并在类中完成数据源的创建。
public class jdbcConfig { @Value("${jdbc.driver}") private String driver; @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; @Bean public DataSource getDataSource(){ DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName(driver); dataSource.setUrl(url); dataSource.setUsername(username); dataSource.setPassword(password); return dataSource; } }
-
主配置类中读properties并引入数据源配置类
@Configuration @ComponentScan("com.itheima") @PropertySource("jdbc.properties") @Import(jdbcConfig.class) public class SpringConfig { }
@PropertySource:加载properties文件(“文件名称”)
@Import:加载其它类为Spring配置类中的Bean(类名.class)
-
创建Mybatis配置类并配置SqlSessionFactory和Mapper
public class MybatisConfig { //定义bean,SqlSessionFactoryBean,用于产生SqlSessionFactory对象 @Bean public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){ SqlSessionFactoryBean ssfd = new SqlSessionFactoryBean(); //设置模型类的别名扫描 ssfd.setTypeAliasesPackage("com.itheima.domain"); //设置数据源 ssfd.setDataSource(dataSource); return ssfd; } @Bean //定义bean,返回MapperScannerConfigurer对象 public MapperScannerConfigurer mapperScannerConfigurer(){ MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer(); mapperScannerConfigurer.setBasePackage("com.itheima.dao"); return mapperScannerConfigurer; } }
- SqlSessionFactoryBean是FactoryBean的一个子类,在该类中将SqlSessionFactory的创建进行了封装,简化对象的创建,现在只需要将其需要的内容设置即可。
- 方法中有一个参数为dataSource,当前Spring容器中已经创建了Druid数据源,类型刚好是DataSource类型,此时在初始化SqlSessionFactoryBean这个对象的时候,发现需要使用DataSource对象,而容器中刚好有这么一个对象,就自动加载了DruidDataSource对象。
- 这个MapperScannerConfigurer对象也是MyBatis提供的专用于整合的jar包中的类,用来处理原始配置文件中的mappers相关配置,加载数据层的Mapper接口类
- MapperScannerConfigurer有一个核心属性basePackage,就是用来设置所扫描的包路径
-
主配置文件引入Mybatis配置类
@Configuration @ComponentScan("com.itheima") @PropertySource("jdbc.properties") @Import({jdbcConfig.class,MybatisConfig.class}) public class SpringConfig { }
-
编写测试类代码,测试
public class App2 { public static void main(String[] args) { //根据spring核心配置类创建容器 ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfig.class); //使用getBean方法通过类型获取对象 AccountService bean = app.getBean(AccountService.class); //这里调用根据id查找 Account byId = bean.findById(1); System.out.println(byId); } }
总结一下:Spring整合Mybatis主要就是将SqlSessionFactory和mappers这两个配置设置为Bean。用到的是SqlSessionFactoryBean和MapperScannerConfigurer这两个类。注意要将数据源配置到Spring核心配置类中。