SpringJDBC和事务



一、Spring JdbcTemplate

在这里插入图片描述

方法简介

1.execute()
建表

调用存储过程
//验证是否有该用户
public boolean callexecute(String LoginId, String password) {
         return jdbcTemplate.execute(new CallableStatementCreator() {
                                        @Override
                                        public CallableStatement createCallableStatement(Connection connection) throws SQLException {
                                            String sql = "{call spring(?,?)}";
                                            CallableStatement callableStatement = connection.prepareCall(sql);
                                            callableStatement.setString(1, LoginId);
                                            callableStatement.setString(2, password);
                                            return callableStatement;
                                        }
                                    }, new CallableStatementCallback<Boolean>() {
                                        @Override
                                        public Boolean doInCallableStatement(CallableStatement callableStatement) throws SQLException, DataAccessException {
                                            callableStatement.execute();
                                            ResultSet resultSet = callableStatement.getResultSet();
                                            if (resultSet.next()) {
                                                return true;
                                            } else
                                                return false;
                                        }
                                    }
        );
    }
 public List<user> finduserbyname(final String name){
        //用call调用存储过程,实现按照用户名进行模糊查询
         List<SqlParameter> parameters=new ArrayList<SqlParameter>();
         parameters.add(new SqlParameter("name", Types.VARCHAR));//设置查询参数
         //设置返回user集合
         parameters.add(new SqlReturnResultSet("result", new ResultSetExtractor<List<user>>() {
             @Override
             public List<user> extractData(ResultSet resultSet) throws SQLException, DataAccessException {
                     List<user> users=new ArrayList<user>();
                     while (resultSet.next()) {
                         user user1=new user();
                         user1.setLoginId(resultSet.getString(1));
                         user1.setLoginPwd(resultSet.getString(3));
                         user1.setName(resultSet.getString(2));
                         users.add(user1);
                     }
                 return users;
             }
         }));
         Map<String,Object> resulyMap=jdbcTemplate.call(new CallableStatementCreator() {
             @Override
             public CallableStatement createCallableStatement(Connection connection) throws SQLException {
                 CallableStatement callableStatement = connection.prepareCall("{call spring2(?)}");
                 callableStatement.setString(1,name);
                 return callableStatement;
             }
         },parameters);
         return (List<user>)resulyMap.get("result");
     }

2.update()插删更
大体上就是定义sql,设置参数数组

        String sql = "INSERT INTO account(username,balance) VALUES(?,?)";
//     定义参数
        Object[] obj = new Object[]{
                account.getUsername(),
                account.getBalance()
        };
        int num = this.jdbcTemplate.update(sql, obj);

3.List query()

    String sql = "select * from user1 where id=? and password=?";
        RowMapper<user> row = new BeanPropertyRowMapper<user>(user.class);
        Object[] pa = new Object[]{id, oldpaassword};
        // t= jdbcTemplate.queryForObject(sql, pa, row);//若没查到就直接报错
        List<user> query = jdbcTemplate.query(sql, pa, row);

4.queryForObject()若没查到就直接报错,一般用于返回行数

  String sql = "select count(*) from user1";
        int count = jdbcTemplate.queryForObject(sql, Integer.class);
        return count;

————————————————

二、配置

springjdbc由4个模块组成

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--   配置数据源-->
    <bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mysql"/>
        <property name="username" value="admin"/>
        <property name="password" value="123456"/>
    </bean>
<!--    配置管理类-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="datasource"/>
    </bean>
    <bean id="userdaoimpl" class="userDaoimpl">
    <property name="jdbcTemplate" ref="jdbcTemplate"/>
    </bean>

</beans>

四、事务

(1)原子性(Atomicity)
    事务最基本的操作单元,要么全部成功,要么全部失败,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚到事务开始前的状态,就像这个事务从来没有执行过一样。
(2)一致性(Consistency)
    事务的一致性指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态。如果事务成功地完成,那么系统中所有变化将正确地应用,系统处于有效状态。如果在事务中出现错误,那么系统中的所有变化将自动地回滚,系统返回到原始状态。
(3)隔离性(Isolation)
    指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。事务查看数据更新时,数据所处的状态要么是另一事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看到中间状态的数据。
(4)持久性(Durability)
    指的是只要事务成功结束,它对数据库所做的更新就必须永久保存下来。即使发生系统崩溃,重新启动数据库系统后,数据库还能恢复到事务成功结束时的状态。

导包:spring-tx-4.36…jar

编程式事务管理

通过编写代码来控制事务

声明式事务管理

通过AOP技术将事务管理封装到切面类中

xml

1.配置事务管理器,以及事务xml通知
2.配置切入点和通知结合

<!--

isolation="DEFAULT" 隔离级别

propagation="REQUIRED" 传播行为

read-only="false" 只读

timeout="-1" 过期时间

rollback-for="" -Exception

no-rollback-for="" +Exception

-->

<!--

对进行事务操作的方法(一般是业务层方法)设置匹配规则,

如:transfer* 即所有以 transfer 开头的方法
name=* 表示任意方法

-->
<!-- 配置事务管理器 -->
<beanid="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<propertyname="dataSource"ref="dataSource"/>
</bean>
<!-- 配置事务的通知(增强) -->
<tx:advice id="txAdvice"transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*"propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
//将通知与接入点结合
 <aop:config>
            <aop:pointcut expression="execution(* com.xml.UserDaoImpl.*(..))" id="myPointCut"/>
            <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut  />
   </aop:config>

Annotation

1.配置事务管理器
2.注册事务管理器驱动
3.在需要进行事务的方法上添加注释

Jdbcconfig配置类代替xml

1.配置事务管理器
jdbcconfig类:
在这里插入图片描述
2.注册事务管理器驱动
在容器加载配置类Springconfig中添加
在这里插入图片描述

在这里插入图片描述

坑:

关于@Transaction 事务不起作用的总结:

@Transaction不起作用的情况:1.静态(static )方法

2.(private)私有化方法

3.当本类的使用@Transactional的方法被本类的其它没有开启事务的方法调用时,不会开启事务。

使用@Transactional的方法被其它类调用时,按照正常的事务传播行为规则开启事务

4.未开启注解解析: 配置文件必须加,否则不解析@Transactional

5.异常被try{}catch(){}捕捉到了,有异常就不会回滚。
可以再抛一个异常就可以了

  1. 数据库引擎要支持事务: 如果是mysql,注意表要使用支持事务的引擎,比如innodb,如果是myisam,事务是不起作用的
public void addInfo(){
    create();
}
@Transactional
public void create(){
}

虽然create()方法开启了事务,但是调用addinfo()来调用create()方法不会开启事务。

<!-- 配置事务管理器 -->
<beanid="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<propertyname="dataSource"ref="dataSource"/>
</bean>
注册事务管理器驱动
<tx:annotation-driven transaction-manager="transactionManager" />
@Transactional(propagation = Propagation.NESTED, timeout = 1000, isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class, noRollbackFor = CustomRuntimeException.class)
	public void doComplexLogic() {

@Transactional 的所有可选属性:
链接: link.

Spring事务回滚的默认条件是1.运行时异常。2.error错误比如内存溢出等等
假设抛出了一个IO异常(编译异常)
在这里插入图片描述

这里事务就不会回滚
在这里插入图片描述
这就必须加一个需要回滚的异常

spring事务注解会把该注解方法下的所有操作当成一个整体事务处理,当出现某些需求时,需要设置事务传播行为
比如在存取前操作前加入一个记录操作

在这里插入图片描述
当transfer方法某一子方法出现异常,则日志记录也不会执行。则实现该功能需要设置以下:
在这里插入图片描述
创建一个新事务,不受整体事务的回滚影响

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值