JavaEE(12)Spring整合Mybaits、宣告式事務
1. Spring整合Mybatis
1. 回顧Mybatis
(1)環境配置
- 匯入相關jar包
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring_study</artifactId>
<groupId>com.nelws</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring_09_mybatis</artifactId>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.26</version>
</dependency>
<!--spring相關-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<!--aop織入-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<!--mybatis-spring整合包【重點】-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
</dependencies>
</project>
- 編寫實體類
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String name;
private String pwd;
}
- 編寫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">
<!--mybatis的主配置檔案-->
<configuration>
<typeAliases>
<package name="com.nelws.domain"/>
</typeAliases>
<!--配置環境-->
<environments default="mysql">
<!--配置mysql的環境-->
<environment id="mysql">
<!--配置事務的型別-->
<transactionManager type="JDBC"/>
<!--配置資料來源(連線池)-->
<dataSource type="POOLED">
<!--配置資料庫的4個資訊-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/nelws/mapper/UserMapper.xml"/>
</mappers>
</configuration>
- 編寫Mapper介面
public interface UserMapper {
List<User> selectUser();
}
- 編寫Mapper.xml
<?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.nelws.mapper.UserMapper">
<select id="selectUser" resultType="user">
select * from user
</select>
</mapper>
(2)測試
@Test
public void test01() throws IOException {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> users = mapper.selectUser();
for (User user : users) {
System.out.println(user);
}
}
/*
User(id=1, name=張三, pwd=123456)
User(id=2, name=UZI, pwd=123432)
User(id=3, name=aaa1, pwd=123456)
User(id=4, name=王八, pwd=123333)
*/
2. Spring整合Mybatis方式1
(1)環境搭建
- 實體類
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String name;
private String pwd;
}
- mybaits-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">
<!--mybatis的主配置檔案-->
<configuration>
<typeAliases>
<package name="com.nelws.domain"/>
</typeAliases>
</configuration>
- 引入Spring配置檔案beans.xml
- 配置資料來源替換mybatis的資料來源
- 配置SqlSessionFactory,關聯mybatis
- 註冊sqlSessionTemplate,關聯SqlSessionFactory
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc.xsd">
<!--配置資料來源替換mybatis的資料來源-->
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<!--配置SqlSessionFactory,關聯MyBatis-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">
<property name="dataSource" ref="dataSource"/>
<!--關聯mybatis-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/nelws/mapper/UserMapper.xml"/>
</bean>
<!--註冊sqlSessionTemplate,關聯sqlSessionFactory-->
<bean class="org.mybatis.spring.SqlSessionTemplate" id="sqlSessionTemplate">
<!--利用構造器注入-->
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
</beans>
- 編寫Mapper介面
public interface UserMapper {
List<User> selectUser();
}
- Mapper.xml
<?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.nelws.mapper.UserMapper">
<select id="selectUser" resultType="user">
select * from user
</select>
</mapper>
- 增加Mapper介面的實現類,私有化sqlSessionTemplate
public class UserMapperImpl implements UserMapper {
//sqlSession不用我們自己建立了,Spring來管理
private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
@Override
public List<User> selectUser() {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
return mapper.selectUser();
}
}
- 註冊bean
<?xml version="1.0" encoding="UTF-8"?>
<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">
<import resource="beans-dao.xml"/>
<bean class="com.nelws.mapper.UserMapperImpl" id="userMapper">
<property name="sqlSession" ref="sqlSessionTemplate"/>
</bean>
</beans>
(2)測試
@Test
public void test01(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
List<User> users = userMapper.selectUser();
for (User user : users) {
System.out.println(user);
}
/*
User(id=1, name=張三, pwd=123456)
User(id=2, name=UZI, pwd=123432)
User(id=3, name=aaa1, pwd=123456)
User(id=4, name=王八, pwd=123333)
*/
}
3. Spring整合Mybatis方式2
(1)說明:mapper繼承Support類 , 直接利用 getSqlSession() 獲得 , 然後直接注入SqlSessionFactory . 比起方式1 , 不需要管理SqlSessionTemplate , 而且對事務的支援更加友好
(2)實現
- 將上面的UserMapperImpl修改一下
public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper {
@Override
public List<User> selectUser() {
UserMapper mapper = getSqlSession().getMapper(UserMapper.class);
return mapper.selectUser();
}
}
- 修改bean的配置
<bean class="com.nelws.mapper.UserMapperImpl2" id="userMapper2">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
- 測試
@Test
public void test02(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserMapper userMapper = context.getBean("userMapper2", UserMapper.class);
List<User> users = userMapper.selectUser();
for (User user : users) {
System.out.println(user);
}
/*
User(id=1, name=張三, pwd=123456)
User(id=2, name=UZI, pwd=123432)
User(id=3, name=aaa1, pwd=123456)
User(id=4, name=王八, pwd=123333)
*/
}
2. 宣告式事務
1. 回顧事務
(1)事務的重要性
- 事務在專案開發過程非常重要,涉及到資料的一致性的問題,不容馬虎!
- 事務管理是企業級應用程式開發中必備技術,用來確保資料的完整性和一致性
- 事務就是把一系列的動作當成一個獨立的工作單元,這些動作要麼全部完成,要麼全部不起作用
(2)事務的ACID屬性
1. 原子性:事務是原子性操作,由一系列動作組成,事務的原子性確保動作要麼全部完成,要麼完全不起作用
2. 一致性:一旦所有事務動作完成,事務就要被提交。資料和資源處於一種滿足業務規則的一致性狀態中
3. 隔離性:可能多個事務會同時處理相同的資料,因此每個事務都應該與其他事務隔離開來,防止資料損壞
4. 永續性:事務一旦完成,無論系統發生什麼錯誤,結果都不會受到影響。通常情況下,事務的結果被寫到持久化儲存器中
(3) 測試
- 將上面的程式碼改造,給UserMapper介面中新增加兩個方法(增加使用者與刪除使用者)
public interface UserMapper {
List<User> selectUser();
//增加使用者
int addUser(User user);
//刪除使用者
int deleteUser(int id);
}
- 在Mapper.xml中,故意把deletes寫錯
<?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.nelws.mapper.UserMapper">
<select id="selectUser" resultType="user">
select * from user
</select>
<insert id="addUser" parameterType="com.nelws.domain.User">
insert into user (id,name,pwd) values (#{id},#{name},#{pwd})
</insert>
<delete id="deleteUser" parameterType="int">
deletes from user where id = #{id}
</delete>
</mapper>
- 更改UserMapper介面的實現類
public class UserMapperImpl implements UserMapper {
private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
@Override
public List<User> selectUser() {
User user = new User(5, "小注", "12312");
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.addUser(user);
mapper.deleteUser(5);
return mapper.selectUser();
}
@Override
public int addUser(User user) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
return mapper.addUser(user);
}
@Override
public int deleteUser(int id) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
return mapper.deleteUser(id);
}
}
- 測試
@Test
public void test03(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
List<User> users = userMapper.selectUser();
for (User user : users) {
System.out.println(user);
}
}
報錯:sql異常,因為delete寫錯了
結果:使用者新增成功
分析:沒有進行事務管理,所以新增成功。但是我們想讓他們都成功才成功,有一個失敗,就都失敗,我們就應該需要事務!
2. 宣告式事務管理
(1)說明:將事務管理作為橫切關注點,通過aop方法模組化。Spring中通過Spring AOP框架支援宣告式事務管理
(2)使用
- 使用Spring管理事務,首先在標頭檔案中匯入約束
- 在Spring配置檔案中注入事務管理器
- 配置好事務管理器後,再去配置事務通知
- 匯入AOP標頭檔案並配置AOP(以上所有都是在beans-dao.xml中)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">
<property name="dataSource" ref="dataSource"/>
<!--關聯mybatis-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/nelws/mapper/UserMapper.xml"/>
</bean>
<bean class="org.mybatis.spring.SqlSessionTemplate" id="sqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
<!--在Spring配置檔案中注入事務管理器-->
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--配置好事務管理器後,再去配置事務通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!--配置aop-->
<aop:config>
<aop:pointcut id="txPointCut" expression="execution(* com.nelws.mapper.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>
</beans>
- 測試
@Test
public void test03(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
List<User> users = userMapper.selectUser();
for (User user : users) {
System.out.println(user);
}
}
報錯:sql異常,因為delete寫錯了
結果:使用者也沒有新增
分析:因為進行了事務管理
相關文章
- 三 Spring 宣告式事務Spring
- Spring-宣告式事務Spring
- Spring宣告式事務控制Spring
- Spring宣告式事務@Transactional使用Spring
- spring宣告式事務管理配置Spring
- Spring的事務管理(二)宣告式事務管理Spring
- 深刻理解Spring宣告式事務Spring
- Spring @Transactional 宣告式事務揭祕Spring
- 五(二)、spring 宣告式事務xml配置SpringXML
- Springboot資料庫事務處理——Spring宣告式事務Spring Boot資料庫
- Spring宣告式事務控制原理之宣告式事務的重要元件在AOP中的應用Spring元件
- Spring宣告式事務純xml模式回顧SpringXML模式
- Spring筆記(4) - Spring的程式設計式事務和宣告式事務詳解Spring筆記程式設計
- 筆記53-Spring jdbcTemplate&宣告式事務筆記SpringJDBC
- Spring宣告式事務的兩種實現方式Spring
- Spring程式設計式和宣告式事務例項講解Spring程式設計
- Spring事務的介紹,以及基於註解@Transactional的宣告式事務Spring
- day15-宣告式事務
- 保護億萬資料安全,Spring有“宣告式事務”絕招Spring
- day16-宣告式事務-02
- springboot專案-宣告式事務失效Spring Boot
- spring boot使用註解的方式整合mybaitsSpring BootAI
- Spring Cloud Feign 宣告式服務呼叫SpringCloud
- 宣告式服務呼叫 Spring Cloud FeignSpringCloud
- Spring Boot 整合 Seata 解決分散式事務問題Spring Boot分散式
- mybaits原始碼分析--事務管理(八)AI原始碼
- spring事物配置,宣告式事務管理和基於@Transactional註解的使用Spring
- Spring Data JPA系列4——Spring宣告式數事務處理與多資料來源支援Spring
- 分散式事務之Spring事務與JMS事務(二)分散式Spring
- Spring/SpringBoot中的宣告式事務和程式設計式事務原始碼、區別、優缺點、適用場景、實戰Spring Boot程式設計原始碼
- Spring 程式設計式事務管理Spring程式設計
- 分散式鎖和spring事務管理分散式Spring
- 使用Spring Boot實現分散式事務Spring Boot分散式
- Spring的事務管理入門:程式設計式事務管理(TransactionTemplate)Spring程式設計
- Spring 事務Spring
- spring事務Spring
- Spring Cloud OpenFeign:基於Ribbon和Hystrix的宣告式服務呼叫SpringCloud
- JavaEE PayPal 全球支付快速整合Java