Spring框架 XML配置事務(wù)控制的步驟操作
基于 XML 的聲明式事務(wù)控制
1.環(huán)境搭建
拷貝必要的 jar 包到工程的 lib 目錄
2.創(chuàng)建 spring 的配置文件并導(dǎo)入約束
這里直接給出本次測試的全部XML配置,具體細節(jié)在后面依次介紹。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd "> <!-- 配置連接池對象 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver" /> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mybase2" /> <property name="user" value="root" /> <property name="password" value="Hudie" /> </bean> <!-- 配置JdbcTemplate模板對象 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- dao --> <bean id="userDao" class="com.gql.dao.UserDaoImp"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean> <!-- service --> <bean id="userService" class="com.gql.service.UserServiceImp"> <property name="userDao" ref="userDao"></property> </bean> <!-- 事務(wù)類/切面 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 通知: 1.告訴Spring容器采用哪種事務(wù)管理機制. 2.告訴Spring容器目標(biāo)方法采用什么樣的事務(wù)處理策略. --> <tx:advice id="tx" transaction-manager="transactionManager"> <tx:attributes> <!-- name 規(guī)定目標(biāo)方法 isolation 事務(wù)隔離級別,默認(rèn)是default propagation 傳播機制,默認(rèn)是REQUIREL --> <tx:method name="save" isolation="DEFAULT" propagation="REQUIRED" read-only="false" /> <tx:method name="up*" isolation="DEFAULT" propagation="REQUIRED" read-only="false" /> <tx:method name="de*" isolation="DEFAULT" propagation="REQUIRED" read-only="false" /> <tx:method name="get*" isolation="DEFAULT" propagation="REQUIRED" read-only="true" /> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut expression="execution (* com.gql.service.UserServiceImp.*(..))" id="point" /> <aop:advisor advice-ref="tx" pointcut-ref="point" /> </aop:config> </beans>
3.準(zhǔn)備數(shù)據(jù)庫表和實體類
user數(shù)據(jù)庫表
create database mybase2; USE mybase2; CREATE TABLE `user` ( `id` INT(10) NOT NULL AUTO_INCREMENT COMMENT '主鍵', `name` VARCHAR(20) NOT NULL DEFAULT '0', `age` INT(10) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) COLLATE='utf8_general_ci' ENGINE=InnoDB ; INSERT INTO user values(NULL,'周冬雨',21); INSERT INTO user values(NULL,'馬冬梅',18); INSERT INTO user values(NULL,'馬西梅',19);
User實體類
package com.gql.entity; import java.io.Serializable; /** * 類說明: * User實體類 * @guoqianliang1998. */ public class User implements Serializable { /** * 生成序列號 */ private static final long serialVersionUID = -4492760954899814333L; private int id; private String name; private int age; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
4.業(yè)務(wù)層接口與實現(xiàn)類
業(yè)務(wù)層接口
package com.gql.service; import java.util.List; import com.gql.entity.User; /** * 類說明: * 業(yè)務(wù)層接口 * @guoqianliang1998. */ public interface UserService { void save(User user); void update(int id, User user); void delete(int id); User getUser(int id); List<User> getUserList(int[] ids); List<User> getUserList(); }
業(yè)務(wù)層實現(xiàn)類
package com.gql.service; import java.util.List; import com.gql.dao.UserDao; import com.gql.entity.User; /** * 類說明: * 業(yè)務(wù)層實現(xiàn)類 * @guoqianliang1998. */ public class UserServiceImp implements UserService { private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } @Override public void save(User user) { userDao.save(user); int i = 1/0; } @Override public void update(int id, User user) { userDao.update(id, user); } @Override public void delete(int id) { userDao.delete(id); } @Override public User getUser(int id) { User user = userDao.getUser(id); return user; } @Override public List<User> getUserList(int[] ids) { List<User> userList = userDao.getUserList(ids); return userList; } @Override public List<User> getUserList() { List<User> list = userDao.getUserList(); return list; } }
5.數(shù)據(jù)訪問層接口與實現(xiàn)類
數(shù)據(jù)訪問層接口
package com.gql.dao; import java.util.List; import com.gql.entity.User; /** * 類說明: * 數(shù)據(jù)訪問層接口 * @guoqianliang1998. */ public interface UserDao { void save(User user); void update(int id, User user); void delete(int id); User getUser(int id); List<User> getUserList(int[] ids); List<User> getUserList(); }
數(shù)據(jù)訪問層實現(xiàn)類
package com.gql.dao; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import com.gql.RowMapper.UserRowMapper; import com.gql.entity.User; /** * 類說明: * 數(shù)據(jù)訪問層實現(xiàn)類 * @guoqianliang1998. */ public class UserDaoImp implements UserDao { private JdbcTemplate jdbcTemplate; public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } @Override public void save(User user) { String sql = "INSERT INTO user values(NULL,?,?)"; jdbcTemplate.update(sql, user.getName(), user.getAge()); } @Override public void update(int id, User user) { String sql = "update user set name=?,age=? WHERE id = ?"; jdbcTemplate.update(sql, user.getName(), user.getAge(), id); } @Override public void delete(int id) { String sql = "DELETE FROM user WHERE id = ?;"; jdbcTemplate.update(sql, id); } @Override public User getUser(int id) { String sql = "select * from user where id = ?"; User user = jdbcTemplate.queryForObject(sql, new RowMapper<User>() { @Override public User mapRow(ResultSet rs, int rowNum) throws SQLException { User user = new User(); user.setId(rs.getInt(1)); user.setName(rs.getString(2)); user.setAge(rs.getInt(3)); return user; } }, id); return user; } @Override public List<User> getUserList(int[] ids) { String sql = "select * from user where id in(:ids)"; NamedParameterJdbcTemplate n = new NamedParameterJdbcTemplate(jdbcTemplate.getDataSource()); Map<String,Object> paramMap = new HashMap<String,Object>(); List list = new ArrayList(); for (int i = 0; i < ids.length; i++) { list.add(ids[i]); } paramMap.put("ids", list); List<User> userList = n.query(sql, paramMap, new RowMapper<User>(){ @Override public User mapRow(ResultSet rs, int rowNum) throws SQLException { User user = new User(); user.setId(rs.getInt(1)); user.setName(rs.getString(2)); user.setAge(rs.getInt(3)); return user; } }); return userList; // 第二種寫法↓↓↓ // StringBuilder sb = new StringBuilder(); // sb.append("SELECT * FROM user WHERE id = ?"); // for(int i=0;i<ids.length-1;i++){ // sb.append(" or id = ?"); // } // Integer[] in = new Integer[ids.length]; // for(int i=0;i<ids.length;i++){ // in[i] = ids[i]; // } // Object[] args = in; // List<User> userList = jdbcTemplate.query(sb.toString(),args,new RowMapper() { // // @Override // public Object mapRow(ResultSet rs, int rowNum) throws SQLException { // User user = new User(); // user.setId(rs.getInt(1)); // user.setName(rs.getString(2)); // user.setAge(rs.getInt(3)); // return user; // } // }); // return userList; } @Override public List<User> getUserList() { String sql = "select * from user"; List<User> list = jdbcTemplate.query(sql, new UserRowMapper()); return list; } }
6.配置c3p0數(shù)據(jù)源/業(yè)務(wù)層/數(shù)據(jù)訪問層
配置c3p0數(shù)據(jù)源
<!-- 配置連接池對象 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver" /> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mybase2" /> <property name="user" value="root" /> <property name="password" value="Hudie" /> </bean> <!-- 配置JdbcTemplate模板對象 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean>
業(yè)務(wù)層
<!-- service --> <bean id="userService" class="com.gql.service.UserServiceImp"> <property name="userDao" ref="userDao"></property> </bean>
數(shù)據(jù)訪問層
<!-- dao --> <bean id="userDao" class="com.gql.dao.UserDaoImp"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean>
7.配置事務(wù)管理器
<!-- 事務(wù)管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 注入 DataSource--> <property name="dataSource" ref="dataSource"></property> </bean>
8.配置事務(wù)的通知
事務(wù)的通知:
- 配置事務(wù)的通知來引用事務(wù)管理器
- 告訴Spring容器采用哪種事務(wù)管理機制.
- 告訴Spring容器目標(biāo)方法采用什么樣的事務(wù)處理策略.
<!-- 事務(wù)的通知: 1.告訴Spring容器采用哪種事務(wù)管理機制. 2.告訴Spring容器目標(biāo)方法采用什么樣的事務(wù)處理策略. --> <tx:advice id="tx" transaction-manager="transactionManager"> <tx:attributes> <!-- name 規(guī)定目標(biāo)方法 isolation 事務(wù)隔離級別,默認(rèn)是default propagation 傳播機制,默認(rèn)是REQUIREL --> <tx:method name="save" isolation="DEFAULT" propagation="REQUIRED" read-only="false" /> </tx:attributes> </tx:advice>
通知內(nèi)配置事務(wù)的屬性
屬性 | 說明 |
---|---|
read-only | 是否是只讀事務(wù)。默認(rèn) false,不只讀。 |
isolation | 指定事務(wù)的隔離級別。默認(rèn)值是使用數(shù)據(jù)庫的默認(rèn)隔離級別。 |
propagation | 指定事務(wù)的傳播行為。 |
timeout | 指定超時時間。默認(rèn)值為:-1。永不超時。 |
rollback-for | 用于指定一個異常,當(dāng)執(zhí)行產(chǎn)生該異常時,事務(wù)回滾。產(chǎn)生其他異常,事務(wù)不回滾。沒有默認(rèn)值,任何異常都回滾。 |
no-rollback-for | 用于指定一個異常,當(dāng)產(chǎn)生該異常時,事務(wù)不回滾,產(chǎn)生其他異常時,事務(wù)回 |
滾。沒有默認(rèn)值,任何異常都回滾。 |
9.配置 AOP 切入點表達式
<!-- AOP切入點表達式 --> <aop:config> <aop:pointcut expression="execution (* com.gql.service.UserServiceImp.*(..))" id="point" /> <!-- 切入點表達式和事務(wù)的對應(yīng)關(guān)系 --> <aop:advisor advice-ref="tx" pointcut-ref="point" /> </aop:config>
10.配置切入點表達式和事務(wù)通知的對應(yīng)關(guān)系
<!-- AOP切入點表達式 --> <aop:config> <aop:pointcut expression="execution (* com.gql.service.UserServiceImp.*(..))" id="point" /> <!-- 切入點表達式和事務(wù)的對應(yīng)關(guān)系 --> <aop:advisor advice-ref="tx" pointcut-ref="point" /> </aop:config>
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
簡單了解Spring中BeanFactory與FactoryBean的區(qū)別
這篇文章主要介紹了簡單了解Spring中BeanFactory與FactoryBean的區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-12-12Java應(yīng)用層協(xié)議WebSocket實現(xiàn)消息推送
后端向前端推送消息就需要長連接,首先想到的就是websocket,下面這篇文章主要給大家介紹了關(guān)于java后端+前端使用WebSocket實現(xiàn)消息推送的詳細流程,需要的朋友可以參考下2023-02-02dubbo集成zipkin獲取Traceid的實現(xiàn)
這篇文章主要介紹了dubbo集成zipkin獲取Traceid的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07spring boot+vue 的前后端分離與合并方案實例詳解
這篇文章主要介紹了spring boot+vue 的前后端分離與合并方案實例詳解,需要的朋友可以參考下2017-11-11Springboot實現(xiàn)Shiro整合JWT的示例代碼
這篇文章主要介紹了Springboot實現(xiàn)Shiro整合JWT的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12