Spring框架 XML配置事務控制的步驟操作
基於 XML 的聲明式事務控制
1.環境搭建
拷貝必要的 jar 包到工程的 lib 目錄
2.創建 spring 的配置文件並導入約束
這裡直接給出本次測試的全部XML配置,具體細節在後面依次介紹。
<?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> <!-- 事務類/切面 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 通知: 1.告訴Spring容器采用哪種事務管理機制. 2.告訴Spring容器目標方法采用什麼樣的事務處理策略. --> <tx:advice id="tx" transaction-manager="transactionManager"> <tx:attributes> <!-- name 規定目標方法 isolation 事務隔離級別,默認是default propagation 傳播機制,默認是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.準備數據庫表和實體類
user數據庫表
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.業務層接口與實現類
業務層接口
package com.gql.service; import java.util.List; import com.gql.entity.User; /** * 類說明: * 業務層接口 * @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(); }
業務層實現類
package com.gql.service; import java.util.List; import com.gql.dao.UserDao; import com.gql.entity.User; /** * 類說明: * 業務層實現類 * @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.數據訪問層接口與實現類
數據訪問層接口
package com.gql.dao; import java.util.List; import com.gql.entity.User; /** * 類說明: * 數據訪問層接口 * @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(); }
數據訪問層實現類
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; /** * 類說明: * 數據訪問層實現類 * @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數據源/業務層/數據訪問層
配置c3p0數據源
<!-- 配置連接池對象 --> <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>
業務層
<!-- service --> <bean id="userService" class="com.gql.service.UserServiceImp"> <property name="userDao" ref="userDao"></property> </bean>
數據訪問層
<!-- dao --> <bean id="userDao" class="com.gql.dao.UserDaoImp"> <property name="jdbcTemplate" ref="jdbcTemplate"></property> </bean>
7.配置事務管理器
<!-- 事務管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 註入 DataSource--> <property name="dataSource" ref="dataSource"></property> </bean>
8.配置事務的通知
事務的通知:
- 配置事務的通知來引用事務管理器
- 告訴Spring容器采用哪種事務管理機制.
- 告訴Spring容器目標方法采用什麼樣的事務處理策略.
<!-- 事務的通知: 1.告訴Spring容器采用哪種事務管理機制. 2.告訴Spring容器目標方法采用什麼樣的事務處理策略. --> <tx:advice id="tx" transaction-manager="transactionManager"> <tx:attributes> <!-- name 規定目標方法 isolation 事務隔離級別,默認是default propagation 傳播機制,默認是REQUIREL --> <tx:method name="save" isolation="DEFAULT" propagation="REQUIRED" read-only="false" /> </tx:attributes> </tx:advice>
通知內配置事務的屬性
屬性 | 說明 |
---|---|
read-only | 是否是隻讀事務。默認 false,不隻讀。 |
isolation | 指定事務的隔離級別。默認值是使用數據庫的默認隔離級別。 |
propagation | 指定事務的傳播行為。 |
timeout | 指定超時時間。默認值為:-1。永不超時。 |
rollback-for | 用於指定一個異常,當執行產生該異常時,事務回滾。產生其他異常,事務不回滾。沒有默認值,任何異常都回滾。 |
no-rollback-for | 用於指定一個異常,當產生該異常時,事務不回滾,產生其他異常時,事務回 |
滾。沒有默認值,任何異常都回滾。 |
9.配置 AOP 切入點表達式
<!-- AOP切入點表達式 --> <aop:config> <aop:pointcut expression="execution (* com.gql.service.UserServiceImp.*(..))" id="point" /> <!-- 切入點表達式和事務的對應關系 --> <aop:advisor advice-ref="tx" pointcut-ref="point" /> </aop:config>
10.配置切入點表達式和事務通知的對應關系
<!-- AOP切入點表達式 --> <aop:config> <aop:pointcut expression="execution (* com.gql.service.UserServiceImp.*(..))" id="point" /> <!-- 切入點表達式和事務的對應關系 --> <aop:advisor advice-ref="tx" pointcut-ref="point" /> </aop:config>
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- Spring框架 註解配置事務控制的流程
- Spring操作JdbcTemplate數據庫的方法學習
- Java Spring 聲明式事務詳解
- Java Spring JdbcTemplate基本使用詳解
- Java Spring5學習之JdbcTemplate詳解