持久层整合总述
1、Spring 框架为什么要与持久层技术进行整合?
- JavaEE开发需要持久层进行数据库的访问操作
- JDBC、Hibernate、MyBatis 进行持久开发过程存在大量的代码冗余
- Spring 基于模板设计模式对于上述的持久层技术进行了封装
2、Spring 可以与哪些持久层技术进行整合?
- JDBC ——
JDBCTemplate
- Hibernate(JPA)——
HibernateTemplate
- MyBatis ——
SqlSessionFactoryBean
、MapperScannerConfigure
Mybatis 开发步骤回顾
- 实体类
User
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 34 35 36 37 38 39
| public class User implements Serializable { private Integer id; private String name; private String password;
public User() { }
public User(Integer id, String name, String password) { this.id = id; this.name = name; this.password = password; }
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; } } 1234567891011121314151617181920212223242526272829303132333435363738
|
- 实体别名
mybatis-config.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Confi 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <typeAliases> <typeAlias alias="user" type="com.yusael.mybatis.User"/> </typeAliases> <environments default="mysql"> <environment id="mysql"> <transactionManager type="JDBC"></transactionManager> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/yus?useSSL=false"/> <property name="username" value="root"/> <property name="password" value="1234"/> </dataSource> </environment> </environments> </configuration> 123456789101112131415161718192021
|
- 表 t_users
1 2 3 4 5 6
| create table t_users values ( id int(11) primary key auto_increment, name varchar(12), password varchar(12) ); 12345
|
- 创建 DAO 接口:
UserDAO
1 2 3 4
| public interface UserDAO { public void save(User user); } 123
|
- 实现Mapper文件:
UserDAOMapper.xml
1 2 3 4 5 6 7 8 9 10
| <?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.yusael.mybatis.UserDAO"> <insert id="save" parameterType="user"> insert into t_users(name, password) values (#{name}, #{password}) </insert> </mapper> 123456789
|
- 注册 Mapper 文件
mybatis-config.xml
1 2 3 4
| <mappers> <mapper resource="UserDAOMapper.xml"/> </mappers> 123
|
- MybatisAPI 调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class TestMybatis { public static void main(String[] args) throws IOException { InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession session = sqlSessionFactory.openSession(); UserDAO userDAO = session.getMapper(UserDAO.class);
User user = new User(); user.setName("yusael"); user.setPassword("123456"); userDAO.save(user);
session.commit(); } } 123456789101112131415
|
Mybatis 开发中存在的问题
问题:配置繁琐、代码冗余
1 2 3 4 5 6 7 8
| 1. 实体 2. 实体别名 配置繁琐 3. 表 4. 创建 DAO 接口 5. 实现 Mapper 文件 6. 注册 Mapper 文件 配置繁琐 7. Mybatis API 调用 代码冗余 1234567
|
Spring 与 Mybatis 整合思路
Spring 与 Mybatis 整合的开发步骤
- 配置文件(ApplicationContext.xml)进行相关配置(只需要配置一次)
- 编码
1.实体类
2.表
3.创建DAO接口
4.Mapper文件配置
Spring 与 Mybatis 整合的编码
搭建开发环境 pom.xml
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
| <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.6.RELEASE</version> </dependency>
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.4</version> </dependency>
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.12</version> </dependency>
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.43</version> </dependency>
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.4</version> </dependency>
|
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 25 26 27 28 29 30 31 32 33
| <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/yus?useSSL=false"/> <property name="username" value="root"/> <property name="password" value="1234"/> </bean>
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="typeAliasesPackage" value="com.yusael.entity"/> <property name="mapperLocations"> <list> <value>classpath:com.yusael.dao/*Mapper.xml</value> </list> </property> </bean>
<bean id="scanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean"/> <property name="basePackage" value="com.yusael.dao"/> </bean>
</beans>
|
编码
- 实体
com.yusael.entity.User
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
| public class User implements Serializable { private Integer id; private String name; private String password;
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; } }
123456789101112131415161718192021222324252627282930
|
- 表
t_user
1 2 3 4 5 6
| create table t_users values ( id int(11) primary key auto_increment, name varchar(12), password varchar(12) ); 12345
|
- DAO接口
com.yusael.dao.UserDAO
1 2 3 4
| public interface UserDAO { public void save(User user); } 123
|
- Mapper文件配置
resources/applicationContext.xml
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
| <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/yus?useSSL=false"/> <property name="username" value="root"/> <property name="password" value="1234"/> </bean>
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="typeAliasesPackage" value="com.yusael.entity"/> <property name="mapperLocations"> <list> <value>classpath:com.yusael.dao/*Mapper.xml</value> </list> </property> </bean>
<bean id="scanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean"/> <property name="basePackage" value="com.yusael.dao"/> </bean>
</beans> 123456789101112131415161718192021222324252627282930
|
- 测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
@Test public void test() { ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml"); UserDAO userDAO = (UserDAO) ctx.getBean("userDAO");
User user = new User(); user.setName("xiaojr"); user.setPassword("999999");
userDAO.save(user); } 1234567891011121314
|
Spring 与 Mybatis 整合细节
问题:Spring 与 Myabatis 整合后,为什么 DAO 不提交事务,但是数据能够插入数据库中?
- Mybatis 提供的连接池对象 —> 创建
Connection
Connection.setAutoCommit(false)
手工的控制了事务,操作完成后,需要手工提交。
- Druid(C3P0、DBCP)作为连接池 —> 创建
Connection
Connection.setAutoCommit(true)
默认值为 true
,保持自动控制事务,一条 sql 自动提交。
答案:因为 Spring 与 Mybatis 整合时,引入了外部连接池对象,保持自动的事务提交这个机制Connection.setAutoCommit(true)
,不需要手工进行事务的操作,也能进行事务的提交。
注意:实战中,还是会手工控制事务(多条SQL一起成功,一起失败),后续 Spring 通过 事务控制 解决这个问题。