Spring 系列(三) 整合Mybatis
1. 回忆Mybatis
目录结构
- 编写工具类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34package top.qwwq.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
// SqlSessionFactory --> sqlSession
public class MybatisUtils {
private static final SqlSessionFactory sqlSessionFactory;
static {
try {
// 使用Mybatis第一步:获取sqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
// 既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。
// SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
} - 编写实体类
1
2
3
4
5
6
7
8import lombok.Data;
public class User {
private int id;
private String name;
private String pwd;
} - 编写核心配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!--核心配置文件-->
<configuration>
<typeAliases>
<package name="top.qwwq.pojo"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=UTF-8&useUnicode=true&serverTimezone=GMT"/>
<property name="username" value="root"/>
<property name="password" value="20021001"/>
</dataSource>
</environment>
</environments>
<!-- 每一个mapper.xml都需要在MyBatis核心配置文件中注册-->
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
</configuration> - 编写接口
1
2
3
4
5
6
7
8
9
10
11
12package top.qwwq.mapper;
import top.qwwq.pojo.User;
import java.util.List;
public interface UserMapper {
// 获取全部用户
List<User> selectUser();
} - 编写Mapper.xml
1
2
3
4
5
6
7
8
9
10
11
12
<!--namespace绑定一个对应的Mapper/Dao接口-->
<mapper namespace="top.qwwq.mapper.UserMapper">
<select id="selectUser" resultType="top.qwwq.pojo.User" >
select * from mybatis.user
</select>
</mapper> - 测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14public class Mytest {
public void test(){
// 第一步: 获取SqlSession对象
try(SqlSession sqlSession = MybatisUtils.getSqlSession()){
// 第二步: getMapper(方式一)
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
for (User user : mapper.selectUser()) {
System.out.println(user);
}
}
}
}
2. 整合Mybatis-Spring
官方快速上手 (👈点击这里)
方式一
代码实现
目录结构 👇
1. 编写spring-dao.xml 由Spring来管理数据源
spring-dao.xml编写DataSource,让Spring掌管数据源1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<!-- DataSource:使用Spring的数据源替换Mybatis的配置 c3p0 dbcp druid
我们治理使用Spring提供的JDBC : org.springframework.jdbc.datasource
-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=UTF-8&useUnicode=true&serverTimezone=GMT"/>
<property name="username" value="root"/>
<property name="password" value="20021001"/>
</bean>
<!-- sqlSessionFactory-->
</beans>spring-dao.xml编写 sqlSessionFactory1
2
3
4
5
6
7
8
9
10
11
12<!-- sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!-- 绑定Mybatis配置文件 (可要可不要)-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!-- 只能通过构造器注入sqlSessionFactory,因为它没有set方法-->
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>spring-dao.xml编写SqlSessionTemplate1
2
3
4<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!-- 只能通过构造器注入sqlSessionFactory,因为它没有set方法-->
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>UserMapperImpl.java需要给接口加实现类1
2
3
4
5
6
7
8
9
10
11
12
13
14public class UserMapperImpl implements UserMapper{
// 在原来,我们所有的操作,都是用sqlSession,现在都使用SqlSessionTemplate
private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
public List<User> selectUser() {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
return mapper.selectUser();
}
}spring-dao.xml把UserMapperImpl.java添加到Spring的bean (可以写xml,或者用注解)1
2
3<bean id="userMapper" class="top.qwwq.mapper.UserMapperImpl">
<property name="sqlSession" ref="sqlSession"/>
</bean>Mytest.java将自己写的实现类,注入到Spring中,测试使用1
2
3
4
5
6
7
8
9
10
11public class Mytest {
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring-dao.xml");
UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
for (User user : userMapper.selectUser()) {
System.out.println(user);
}
}
}
小结:
需要用到的文件只有 :
UserMapper.java(接口) 用来定义方法1
2
3
4public interface UserMapper {
// 获取全部用户
List<User> selectUser();
}UserMapperImpl.java(类) 用来实现接口中的方法 👆上面有这个文件的具体代码User.java(类) pojo实体类 👆上面有这个文件的具体代码UserMapper.xml绑定UserMapper.java接口,用来写SQL语句,也可以直接使用注解来实现mybatis-config.xmlSpring整合Mybatis后mybatis-config.xml这个文件可以不需要了,但是通常还是保留,用来给类起别名、存放一些设置信息(比如日志什么的)
方式二
新建一个UserMapper的实现类,然后去继承SqlSessionDaoSupport这个类,这个类会帮你做一些步骤一的工作
1 | public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper{ |
把UserMapperImpl2类注册到Spring
1 | <bean id="userMapper2" class="top.qwwq.mapper.UserMapperImpl2"> |
AI小提醒:
方式二 和 方式一 的不同
SqlSessionDaoSupport和直接使用SqlSessionFactory的主要区别在于SqlSessionDaoSupport提供了一些额外的便利性,尤其是在处理SqlSession生命周期方面。
生命周期管理:当你使用
SqlSessionDaoSupport时,你不需要手动打开和关闭SqlSession。这是因为SqlSessionDaoSupport在每次请求时都会自动打开一个新的SqlSession,并在请求结束时自动关闭这个SqlSession。这意味着你不需要在你的代码中管理SqlSession的生命周期,这可以使你的代码更简洁,也可以减少因为忘记关闭SqlSession而导致的资源泄露的可能性。依赖注入:
SqlSessionDaoSupport提供了一个设置SqlSessionFactory的方法,这意味着你可以使用Spring的依赖注入功能来注入SqlSessionFactory。这使得你的DAO类和Spring框架的集成更紧密,也使得你的DAO类更容易测试,因为你可以在测试时注入一个模拟的SqlSessionFactory。模板编程:
SqlSessionDaoSupport是Spring的模板编程风格的一部分。这种风格的主要思想是将一些常见的、重复的代码(如打开和关闭SqlSession)封装在模板类中,然后让用户的类继承这个模板类。这种方式可以减少代码重复,使代码更易于维护。相比之下,直接使用
SqlSessionFactory则需要手动管理SqlSession的生命周期,也需要手动注入SqlSessionFactory。然而,这也意味着你有更大的灵活性,因为你可以控制何时打开和关闭SqlSession,也可以选择不使用Spring的依赖注入。总的来说,选择使用
SqlSessionDaoSupport还是直接使用SqlSessionFactory主要取决于你的具体需求。如果你希望代码更简洁,或者你正在使用Spring框架,那么SqlSessionDaoSupport可能是一个好选择。如果你需要更大的灵活性,或者你不想让你的DAO类与Spring框架紧密集成,那么直接使用SqlSessionFactory可能是一个好选择。
在代码层面上,使用SqlSessionDaoSupport和直接使用SqlSessionFactory的主要区别在于如何管理SqlSession的生命周期,以及如何进行依赖注入。
生命周期管理:当你使用
SqlSessionDaoSupport时,你不需要手动打开和关闭SqlSession。例如:1
2
3
4
5public class MyDao extends SqlSessionDaoSupport {
public MyObject getMyObject(int id) {
return getSqlSession().selectOne("MyMapper.getMyObject", id);
}
}在上面的代码中,
getSqlSession()方法由SqlSessionDaoSupport提供,并且它会自动管理SqlSession的生命周期。相比之下,当你直接使用
SqlSessionFactory时,你需要手动打开和关闭SqlSession。例如:1
2
3
4
5
6
7
8
9
10
11
12
13public class MyDao {
private SqlSessionFactory sqlSessionFactory;
public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
public MyObject getMyObject(int id) {
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
return sqlSession.selectOne("MyMapper.getMyObject", id);
}
}
}在上面的代码中,
SqlSession是通过sqlSessionFactory.openSession()手动打开的,并且在try-with-resources语句中自动关闭。依赖注入:当你使用
SqlSessionDaoSupport时,你可以使用Spring的依赖注入功能来注入SqlSessionFactory。例如:1
2
3<bean id="myDao" class="org.mybatis.spring.support.SqlSessionDaoSupport">
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>在上面的配置中,
SqlSessionFactory是通过Spring的<property>配置注入的。相比之下,当你直接使用
SqlSessionFactory时,你也可以使用Spring的依赖注入功能来注入SqlSessionFactory,但是你需要在你的DAO类中提供一个设置SqlSessionFactory的方法。例如:1
2
3<bean id="myDao" class="com.example.MyDao">
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>在上面的配置中,
SqlSessionFactory是通过Spring的<property>配置注入的,但是这需要你的DAO类提供一个setSqlSessionFactory(SqlSessionFactory sqlSessionFactory)方法。
