4、Spring整合MyBatis
学习资源:动力节点的2020最新Spring框架教程【IDEA版】-Spring框架从入门到精通
目录
1、整合原理分析
回顾 MyBatis 的使用步骤:
- 定义 dao 接口,StudentDao
- 定义 mapper 文件,StudentDao.xml
- 定义 MyBatis 主配置文件,mybatis-config.xml
- 创建 dao 的代理对象,
StudentDao dao = sqlSession.getMapper(StudentDao.class);
List\<Student>students = dao.selectAll();
MyBatis 操作数据库流程的逆向分析:
- 使用 dao 对象
- 使用
sqlSession.getMapper(xxx.class)
获取 dao 对象 - 使用
SqlSessionFactory.openSession()
获取sqlSession
对象 - 使用
SqlSessionFactoryBuilder().build(mybatis配置文件)
获取SqlSessionFactory
对象 - 读取 mybatis 的主配置文件,获取创建有关对象需要用到的信息
<!-- 这是操作数据库需要用到的信息 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<!-- mybatis 默认的连接池性能较差,现在项目开发一般使用 druid 连接池 -->
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/chen/dao/StudentDao.xml"/>
</mappers>
综上,spring 整合 mybatis,就是让 spring 通过 IoC 创建以下对象:
- druid 连接池对象,druid会根据数据库 url 前缀,自动识别并加载数据库驱动
- SqlSessionFactory 对象
- dao 对象
一并交由 spring 容器同意管理,使得整合后,spring + mybatis = spring,成为一个整体。
2、整合入门实例
2.1、创建 maven 工程
2.2、加入 maven 依赖
- spring 依赖
- mybatis 依赖
- mysql 依赖
- spring 事务依赖
- mybatis 和 spring 集成依赖,由 MyBatis 官方提供
<dependencies>
<!-- 测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<!-- ioc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!-- 事务 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<!-- 整合 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.4</version>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
<!-- 德鲁伊连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.21</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory><!--所在的目录-->
<includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
2.3、创建实体类
package com.chen.pojo;
public class Student {
//属性名和列名一样
private Integer id;
private String name;
private String email;
private Integer age;
public Student(Integer id, String name, String email, Integer age) {
this.id = id;
this.name = name;
this.email = email;
this.age = age;
}
// set ,get , toString
}
2.4、创建 dao 接口和 mapper 文件
package com.chen.dao;
public interface StudentDao {
int insertStudent(Student student)
List<Student> selectStudents();
}
<?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="com.chen.dao.StudentDao">
<insert id="insertStudent">
insert into student values(#{id}, #{name}, #{email}, #{age})
</insert>
<select id="selectStudents" resultType="student">
select id, name, email, age from student
</select>
</mapper>
2.5、创建 mybatis 主配置文件
mybatis-config.xml
<?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>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!-- 给每一个pojo单独起别名 -->
<typeAliases>
<package name="com.chen.pojo"/>
</typeAliases>
<!-- sql映射文件的位置 -->
<mappers>
<mapper resource="com/chen/dao/StudentDao.xml"/>
</mappers>
</configuration>
2.5、创建 service 接口和实现类
service 类就是调用 dao 来完成数据库数据的修改,所以其内部会私有化一个 dao 的对象
package com.chen.service;
public interface StudentService {
int addStudent(Student student);
List<Student> queryAllStudents();
}
package com.chen.service.impl;
public class StudentServiceImpl implements StudentService {
private StudentDao dao;
@Override
public int addStudent(Student student) {
dao.insertStudent(sutdent);
return 0;
}
@Override
public List<Student> queryAllStudents() {
List<Student> students = dao.selectStudents();
return students;
}
}
2.7、创建 spring 配置文件
applicationContext.xml,创建 mybatis 的对象
- 数据库连接池对象(数据源):通过配置文件创建 druid 数据连接池对象
- 通常你需要配置url、username、password,maxActive 这四项。
- Druid会自动跟 url 识别驱动类名,如果连接的数据库非常见数据库,配置属性 driverClassName
# url=jdbc_url
# username=jdbc_user
# password=jdbc_password
使用 druid,直接用 username 作为mysql访问用户名称,会与windows当前用户名冲突,所以将所有属性名附上前缀
jdbc.url=jdbc:mysql://localhost:3306/ssm?useSSL=true&useUnicode=true&characterEncoding=UTF-8
#用户名
jdbc.username=root
#用户密码
jdbc.password=
#新版本的MySQL8驱动
jdbc.driver=com.mysql.cj.jdbc.Driver
<!-- 加载属性配置文件中的数据库属性的值 -->
<context:property-placeholder location="classpath:druid.properties"/>
<!-- 官方参考配置 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!--这三项必须配置,用于连接数据库 -->
<!-- set注入给 druid数据源提供连接数据库的信息 -->
<property name="url" value="${jdbc_url}" />
<property name="username" value="${jdbc_user}" />
<property name="password" value="${jdbc_password}" />
<!--
druid 会根据 url 前缀自动识别并加载数据库驱动
mysql8.0的驱动是下面这个
-->
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="filters" value="stat" />
<property name="maxActive" value="20" />
<property name="initialSize" value="1" />
<property name="maxWait" value="60000" />
<property name="minIdle" value="1" />
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<property name="minEvictableIdleTimeMillis" value="300000" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<property name="poolPreparedStatements" value="true" />
<property name="maxOpenPreparedStatements" value="20" />
<property name="asyncInit" value="true" />
</bean>
- SqlSessionFactory 对象
在配置文件中声明,这里声明创建的是 mybatis 中提供的SqlSessionFactoryBean
类的对象,在这个对象的内部会创建SqlSessionFactory
。
SqlSessionFactory
原来通过读取 mybatis-config.xml 中的数据源信息和mapper信息,才可以获取到 dao 对象,因此这里需要给SqlSessionFactoryBean
对象注入这些信息。
<!-- 创建这个对象,用于创建 SqlSessionFactory 对象-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- set 注入 -->
<!-- 数据源信息,就是上面那个 druid -->
<property name="dataSource" ref="datsource"/>
<!-- mybatis 配置文件的位置,用于获取 mapper信息 -->
<property name="configLocation" value="classpath:mybatic-config.xml"/>
</bean>
- dao 对象
创建 dao 对象,使用sqlSession.getMapper(xxxDao.class)
,而SqlSession
要由SqlSessionFactory
来创建。
我们在容器中创建MapperScannerConfigurer
对象,该对象会在调用getMapper()
生成 mybatis-config.xml 中注册的所有 dao 接口的代理对象。
dao 对象的默认名称是 dao接口名首字母小写。
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<!-- MapperScannerConfigurer 会扫描包中的所有接口,并执行getMapper()创建出所有的dao代理对象,添加到容器中 -->
<property name="basePackage" value="com.chen.dao,com.chen.dao2"/>
<bean/>
- service 对象:
因为前面已经在容器中创建了 dao 的对象,所以向 service 类的对象的 dao 属性赋值,直接从容器中"拿"即可。
<bean id="studentService" class="com.chen.service.impl.StudentServiceImpl">
<property name="studentDao" ref="studentDao"/>
</bean>
2.8、测试
@Test
public void test(){
String resource = "applicationContext.xml";
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(resource);
StudentService stuService = (StudentService) context.getBean("studentService");
int rows = stuService.addStudent(new Student(1006, "马飞", "62666202@163.com", 29));
List<Student> students = stuService.queryAllStudents();
}