小码农的代码(二)----------SpringJDBC事务控制

2024-09-04 12:38

本文主要是介绍小码农的代码(二)----------SpringJDBC事务控制,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

今年年初遇到一个对接ERP与WMS的项目,只做后端数据同步,不进行页面展示,简而言之就是我们接收ERP http请求传送过来的数据然后转存到自己的数据库并将数据同步到WMS系统的数据库中,(ps:我也比较奇怪为什么不直接用http请求进行对接,而来中间再转存一次)。由于项目较小又不需要前端展示就直接只用SpringJDBC进行数据库操作,项目涉及的内容包括http请求接口的开发、多数据库操作,本文先拉出来整理下SpringJDBC的直接使用。 
SpringJDBC的使用目前来看非常简单,主要就是三个步骤。 
一、maven加载所需要的jar包; 
一、Spring配置文件进行数据源与jdbctemple的配置; 
二、直接在数据访问层使用。 
以下是spring配置文件的内容:
Java代码   收藏代码
  1. <!-- 引入属性文件 -->  
  2.     <context:property-placeholder location="classpath:config.properties" />  
  3.     <!-- 自动扫描dao和service包( 自动注入) -->  
  4.     <context:component-scan base-package="com.zh.demo" />  
  5.     <!-- 数据连接池C3P0 -->  
  6.     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"  
  7.         destroy-method="close">  
  8.         <property name="driverClass" value="${jdbc.driverClass}" />  
  9.         <property name="jdbcUrl" value="${jdbc.jdbcUrl}" />  
  10.         <property name="user" value="${jdbc.user}" />  
  11.         <property name="password" value="${jdbc.password}" />  
  12.     </bean>  
  13.   
  14.     <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  
  15.         <property name="dataSource" ref="dataSource" />  
  16.     </bean>  

这里的注意点在于spring的数据源配置,不直接使用DriverManagerDataSource的原因是由于其没有实现连接池的机制,因此使用C3P0,这时需要加载c3p0的支持JAR包; 
另外在数据访问层进行数据操作时如下
Java代码   收藏代码
  1. public class BaseDaoImpl implements BaseDao{  
  2.   
  3.     @Autowired  
  4.     private JdbcTemplate jdbcTemplate;  
  5.       
  6.     /** 
  7.      * sql = "insert into user (name,age) values(?,?)" 
  8.      * */  
  9.     public void addBySql(String sql,final Object[] params) {  
  10.         //--------------methods01------------------------------------//  
  11.         jdbcTemplate.execute(sql);  
  12.         //-----------------or methods02------------------------------//  
  13.         //just like updateBySql  
  14.     }  
  15.   
  16.     /** 
  17.      * sql = “update table_name set name=?,age=?” 
  18.      * */  
  19.     public void updateBySql(String sql,final Object[] params) {  
  20.         //--------------methods01------------------------------------//  
  21.         jdbcTemplate.update(sql,  
  22.                 new PreparedStatementSetter() {  
  23.                     public void setValues(PreparedStatement ps)  
  24.                             throws SQLException {  
  25.                         ps.setInt(1, Integer.parseInt(params[0].toString()));  
  26.                     }  
  27.                 });       
  28.         //-----------------or methods02------------------------------//  
  29.         //jdbcTemplate.update(sql, params);  
  30.     }  
  31.   
  32.     /** 
  33.      * sql = "delete user where id =? and name = ?;" 
  34.      * */  
  35.     public void deleteBySql(String sql,final Object[] params) {  
  36.         //----------just like update---------------//  
  37.         jdbcTemplate.update(sql, params);  
  38.     }  
  39.   
  40.     /** 
  41.      * RowMapper接口封装返回集合,可自定义 
  42.      * */  
  43.     public List<UserEntity> getQueryBySql(String sql) {  
  44.         return (List<UserEntity>) jdbcTemplate.query(sql,  
  45.                 new BeanPropertyRowMapper<UserEntity>(UserEntity.class));  
  46.     }  
  47.   
  48.       
  49. }  
因为Spring配置文件中已经配置,可以直接依赖注入jdbcTemplate; 
另外也可以继承JdbcDaoSupport类,来使用jdbcTemplate
,
Java代码   收藏代码
  1. public class BaseDaoImpl2 extends JdbcDaoSupport implements BaseDao{  
  2.   
  3.       
  4.     public void addBySql(String sql,final Object[] params) {  
  5.         this.getJdbcTemplate().update(sql);  
  6.     }  
  7. }  
。 
这两个类进一步论证一个接口可以有多个实现类,谁实例化则调用哪个实现类中的方法。 
具体的代码例子与测试文件可以下载附件参考,欢迎大家斧正。 
另外对于jdbcTemplate的事务控制就是使用Spring对于事务的控制,具体内容会在后续文章中补充说明。
  • SpringJDBC.rar (20.5 KB)
  • 下载次数: 3


继续上一篇文章中所述项目的代码整理学习,前面提到直接使用springJDBC的进行数据层的操作,事务控制是必须要有的,那么这里整理一下之前使用的事务控制内容。 
首先Spring的事务控制是很完善的,能够满足本人目前遇到的几乎所有项目,具体的内容就不展开论述了,因为太多了 。这里贴一张图,基本就可以理清Spring事务控制的最基本配置。本图来源于博客园
 
由于实际项目周期的问题以及个人习惯能注解就注解=。=,当然因为某种原因,这里并不是使用纯注解的方式进行事务配置,而是使用了tx拦截器的方式进行声明式事务配置(入乡随俗,充分利用Spring特色),其中运用到的aop面向切面编程后续文章中会专门对他的aspectj代理机制进行总结,这里就不对其展开代码编写试验了,当然这里的项目aspectjweaver的JAR包是肯定要添加的 。 
首先由于是直接使用SpringJdbc因而使用DataSourceTransactionManager进行事务管理
Java代码   收藏代码
  1. <bean id="transactionManager"  
  2.         class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  3.         <property name="dataSource" ref="dataSource" />  
  4.     </bean>其次自然需要开启tx标签注解事务  
  5. [code="java<!-- 开启注解事务 只对当前配置文件有效 -->  
  6.     <tx:annotation-driven transaction-manager="transactionManager" />  
  7.   
  8.     <!-- 事务管理配置 -->  
  9.     <tx:advice id="txAdvice" transaction-manager="transactionManager">  
  10.         <tx:attributes>  
  11.             <tx:method name="save*" propagation="REQUIRED" />  
  12.             <tx:method name="create*" propagation="REQUIRED" />  
  13.             <tx:method name="insert*" propagation="REQUIRED" />  
  14.             <tx:method name="update*" propagation="REQUIRED" />  
  15.             <tx:method name="add*" propagation="REQUIRED" />  
  16.             <tx:method name="delete*" propagation="REQUIRED" />  
  17.             <tx:method name="remove*" propagation="REQUIRED" />  
  18.             <tx:method name="cancel*" propagation="REQUIRED" />  
  19.   
  20.             <tx:method name="get*" propagation="REQUIRED" read-only="true" />  
  21.             <tx:method name="query*" propagation="REQUIRED" read-only="true" />  
  22.             <tx:method name="find*" propagation="REQUIRED" read-only="true" />  
  23.             <tx:method name="load*" propagation="REQUIRED" read-only="true" />  
  24.             <tx:method name="count*" propagation="REQUIRED" read-only="true" />  
  25.             <tx:method name="list*" propagation="REQUIRED" read-only="true" />  
  26.             <tx:method name="*" read-only="true" />  
  27.         </tx:attributes>  
  28.     </tx:advice>  
最后开启Aop的监听与监听切面
Java代码   收藏代码
  1. <aop:aspectj-autoproxy expose-proxy="true" /><aop:config expose-proxy="true">  
  2.         <!-- 只对业务逻辑层实施事务 -->  
  3.         <aop:pointcut id="txPointcut"  
  4.             expression="execution(* com.zh..service.impl.*ServiceImpl.*(..))" />  
  5.         <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" />  
  6.     </aop:config>  
这样配置就结束了。对于不想使用切面直接使用纯注解方式后续的文章总结中可以尝试使用。 
接下去就可以展开编码测试了,在上文的基础上新建了Service类,并加入@service注解,使得调用的时候可以自动注入
Java代码   收藏代码
  1. @Service("userService")  
  2. public class UserServiceImpl implements UserService{  
  3.   
  4.     @Autowired  
  5.     private BaseDao baseDao;  
  6.       
  7.         public void saveUser(String sql) {  
  8.         try {  
  9.             baseDao.addBySql("insert into user (name,age)values('张三',13)"null);  
  10.             baseDao.addBySql("insert into user (id,name,age)values(2,'张三',13)"null);  
  11.         } catch (Exception e) {  
  12.             System.out.println("代码错误新增事务回滚");  
  13.         }  
  14.     }  
  15.   
  16. }  
如果事务正常控制则因为第二条新增语句错误(因id为2的记录已存在,可自行修改)而catch到异常并且数据库中没有新增的记录(ps.数据库很简单,就死一张user表,有id,name,age三个字段,id为主键自增)。经测试,测试结果与预测一致。 
ps:注意点:在dao层新增时,如果是以下情况则数据库直接新增前一条记录
Java代码   收藏代码
  1. public void addBySql(String sql,final Object[] params) {  
  2.                 jdbcTemplate.execute(sql);  
  3.               
  4.         }  
因而保存语句应该使用PreparedStatement,
Java代码   收藏代码
  1. jdbcTemplate.update(sql,  
  2.                 new PreparedStatementSetter() {  
  3.                     public void setValues(PreparedStatement ps)  
  4.                             throws SQLException {  
  5.                         ps.setInt(1, Integer.parseInt(params[0].toString()));  
  6.                     }  
  7.                 });   
进入jdbcTemplate.execute()方法可以发现它是直接调用Statement.execute直接执行因为事实上数据库事务已经提交而调用update方法时是使用PreparedStatement进行预编译的。 
测试代码见附件,以上内容如有错误 烦请斧正,希望能够在大家的指导下更进一步,谢谢。 
下一篇博文将会对SpringJDBC的多数据源在本项目中的实际运用进行总结。
  • SpringJDBC_事务控制_.rar (26.2 KB)
  • 下载次数: 6

这篇关于小码农的代码(二)----------SpringJDBC事务控制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1136048

相关文章

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

代码随想录冲冲冲 Day39 动态规划Part7

198. 打家劫舍 dp数组的意义是在第i位的时候偷的最大钱数是多少 如果nums的size为0 总价值当然就是0 如果nums的size为1 总价值是nums[0] 遍历顺序就是从小到大遍历 之后是递推公式 对于dp[i]的最大价值来说有两种可能 1.偷第i个 那么最大价值就是dp[i-2]+nums[i] 2.不偷第i个 那么价值就是dp[i-1] 之后取这两个的最大值就是d

pip-tools:打造可重复、可控的 Python 开发环境,解决依赖关系,让代码更稳定

在 Python 开发中,管理依赖关系是一项繁琐且容易出错的任务。手动更新依赖版本、处理冲突、确保一致性等等,都可能让开发者感到头疼。而 pip-tools 为开发者提供了一套稳定可靠的解决方案。 什么是 pip-tools? pip-tools 是一组命令行工具,旨在简化 Python 依赖关系的管理,确保项目环境的稳定性和可重复性。它主要包含两个核心工具:pip-compile 和 pip

D4代码AC集

贪心问题解决的步骤: (局部贪心能导致全局贪心)    1.确定贪心策略    2.验证贪心策略是否正确 排队接水 #include<bits/stdc++.h>using namespace std;int main(){int w,n,a[32000];cin>>w>>n;for(int i=1;i<=n;i++){cin>>a[i];}sort(a+1,a+n+1);int i=1

MySql 事务练习

事务(transaction) -- 事务 transaction-- 事务是一组操作的集合,是一个不可分割的工作单位,事务会将所有的操作作为一个整体一起向系统提交或撤销请求-- 事务的操作要么同时成功,要么同时失败-- MySql的事务默认是自动提交的,当执行一个DML语句,MySql会立即自动隐式提交事务-- 常见案例:银行转账-- 逻辑:A给B转账1000:1.查询

html css jquery选项卡 代码练习小项目

在学习 html 和 css jquery 结合使用的时候 做好是能尝试做一些简单的小功能,来提高自己的 逻辑能力,熟悉代码的编写语法 下面分享一段代码 使用html css jquery选项卡 代码练习 <div class="box"><dl class="tab"><dd class="active">手机</dd><dd>家电</dd><dd>服装</dd><dd>数码</dd><dd

控制反转 的种类

之前对控制反转的定义和解释都不是很清晰。最近翻书发现在《Pro Spring 5》(免费电子版在文章最后)有一段非常不错的解释。记录一下,有道翻译贴出来方便查看。如有请直接跳过中文,看后面的原文。 控制反转的类型 控制反转的类型您可能想知道为什么有两种类型的IoC,以及为什么这些类型被进一步划分为不同的实现。这个问题似乎没有明确的答案;当然,不同的类型提供了一定程度的灵活性,但