从零开始学习Spring - JdbcTemplate、Spring事务

从零开始学习Spring - JdbcTemplate、Spring事务,第1张

从零开始学习Spring - JdbcTemplate、Spring事务 1. jdbcTemplate 1.1 基本概念

JdbcTemplate是spring框架中提供的一个模板对象,是对原始繁琐的Jdbc API对象的简单封装

核心对象

JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSource dataSource);

核心方法

执行增、删、改语句 
int update(); 
// // 查询多个
List query(); 
// 查询一个 
T queryForObject(); 
// 实现ORM映射封装
new BeanPropertyRowMapper<>(); 
1.2 Spring整合 1.2.1 Maven配置
  
        
            mysql
            mysql-connector-java
            8.0.25
        
        
            com.alibaba
            druid
            1.2.8
        
        
            org.springframework
            spring-context
            5.3.15
        
        
            org.aspectj
            aspectjweaver
            1.9.7
        
        
            org.springframework
            spring-jdbc
            5.3.15
        
        
            org.springframework
            spring-tx
            5.3.15
        
        
            junit
            junit
            4.13.2
        
        
            org.springframework
            spring-test
            5.3.15
        
    
1.2.2 实体类

Account

public class Account {

    private Integer id;
    private String name;
    private Double money;
    
}
1.2.3 Dao层接口

AccountDao

package cn.knightzz.dao;

import cn.knightzz.entity.Account;

import java.util.List;

public interface AccountDao {

    
    public List findAll();

    
    public Account findById(Integer id);

    
    public void save(Account account);

    
    public void update(Account account);

    
    public void delete(Integer id);
}

AccountDaoImpl

package cn.knightzz.dao.impl;

import cn.knightzz.dao.AccountDao;
import cn.knightzz.entity.Account;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.util.List;


@Repository("accountDao")
public class AccountDaoImpl implements AccountDao {

    @Resource
    JdbcTemplate jdbcTemplate;

    @Override
    public List findAll() {

        String sql = "select * from account";
        List accountList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Account.class));
        return accountList;
    }

    @Override
    public Account findById(Integer id) {

        String sql = "select * from account where id = ?";
        Account account = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(Account.class), id);
        return account;
    }

    @Override
    public void save(Account account) {
        String sql = "insert into account(id, name ,money) values(null ,  ?,  ?)";
        jdbcTemplate.update(sql, account.getName(), account.getMoney());
    }

    @Override
    public void update(Account account) {
        String sql = "update account set name = ?, money = ? where id = ?";
        jdbcTemplate.update(sql, account.getName(), account.getMoney(), account.getId());
    }

    @Override
    public void delete(Integer id) {
        String sql = "delete from account where id = ?";
        jdbcTemplate.update(sql, id);
    }
}


1.3.4 Service 层接口

AccountService接口

package cn.knightzz.service;

import cn.knightzz.entity.Account;

import java.util.List;

public interface AccountService {
    
    public List findAll();

    
    public Account findById(Integer id);

    
    public void save(Account account);

    
    public void update(Account account);

    
    public void delete(Integer id);


}

AccountServiceImpl

package cn.knightzz.service.impl;

import cn.knightzz.dao.AccountDao;
import cn.knightzz.entity.Account;
import cn.knightzz.service.AccountService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

@Service("accountService")
public class AccountServiceImpl implements AccountService {

    @Resource
    AccountDao accountDao;

    @Override
    public List findAll() {
        return accountDao.findAll();
    }

    @Override
    public Account findById(Integer id) {
        return accountDao.findById(id);
    }

    @Override
    public void save(Account account) {
        accountDao.save(account);
    }

    @Override
    public void update(Account account) {
        accountDao.update(account);
    }

    @Override
    public void delete(Integer id) {
        accountDao.delete(id);
    }
}

1.3.5 测试代码

AccountServiceTest

package cn.knightzz.service;

import cn.knightzz.config.SpringConfig;
import cn.knightzz.entity.Account;
import junit.framework.TestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;
import java.util.List;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfig.class})
public class AccountServiceTest extends TestCase {

    @Resource
    AccountService accountService;

    @Test
    public void testFindAll() {
        List accountList = accountService.findAll();
        for (Account account : accountList) {
            System.out.println(account);
        }
    }

    @Test
    public void testFindById() {
        Account account = accountService.findById(1);
        System.out.println(account);
    }

    @Test
    public void testSave() {
        Account accout = new Account();
        accout.setId(3);
        accout.setName("kiss");
        accout.setMoney(300d);
        accountService.save(accout);
    }

    @Test
    public void testUpdate() {
        Account accout = new Account();
        accout.setId(3);
        accout.setName("knightzz");
        accout.setMoney(400d);
        accountService.update(accout);
    }

    public void testDelete() {
    }
}
2. Spring事务 2.1 Spring事务控制方式

Spring的事务控制可以分为编程式事务控制和声明式事务控制。 2.1.1 编程式事务

开发者直接把事务的代码和业务代码耦合到一起,在实际开发中不用 2.1.2 声明式事务

开发者采用配置的方式来实现的事务控制,业务代码与事务代码实现解耦合,使用的AOP思想。 2.2 编程式事务控制对象 2.2.1 不同的Dao层实现对象

PlatformTransactionManager 是接口类型,不同的 Dao 层技术则有不同的实现类。Dao层技术是jdbcTemplate或mybatis时: DataSourceTransactionManagerDao层技术是hibernate时: HibernateTransactionManagerDao层技术是JPA时: JpaTransactionManager 2.2.2 PlatformTransactionManager

PlatformTransactionManager接口,是spring的事务管理器

里面提供了我们常用的 *** 作事务的方法

常用方法

2.2.3 TransactionDefinition

TransactionDefinition接口提供事务的定义信息(事务隔离级别、事务传播行为等等)

常用方法

2.2.4 事务隔离级别

脏写、脏读、不可重复读和幻读

设置隔离级别,可以解决事务并发产生的问题,如脏读、不可重复读和虚读(幻读)。

ISOLATION_DEFAULT 使用数据库默认级别

ISOLATION_READ_UNCOMMITTED 读未提交

ISOLATION_READ_COMMITTED 读已提交

ISOLATION_REPEATABLE_READ 可重复读

ISOLATION_SERIALIZABLE 串行化

2.2.5 事务传播行为

事务传播行为指的就是当一个业务方法【被】另一个业务方法调用时,应该如何进行事务控制

read-only(是否只读):建议查询时设置为只读

timeout(超时时间):默认值是-1,没有超时限制。如果有,以秒为单位进行设置

2.2.6 TransactionStatus

TransactionStatus 接口提供的是事务具体的运行状态。

可以简单的理解三者的关系:事务管理器通过读取事务定义参数进行事务管理,然后会产生一系列的事
务状态。

2.2.7 代码实现

SpringConfig

@Bean("transactionManager")
public DataSourceTransactionManager getDataSourceTransactionManager(@Autowired DataSource dataSource){
    return new DataSourceTransactionManager(dataSource);
}

Service

 @Resource
    private PlatformTransactionManager transactionManager;

    
    @Override
    public void transfer(String outUser, String inUser, Double money) {
            // 创建事务定义对象
            DefaultTransactionDefinition def = new DefaultTransactionDefinition();
            // 设置是否只读,false支持事务
            def.setReadOnly(false);
            // 设置事务隔离级别,可重复读mysql默认级别
            def.setIsolationLevel(TransactionDefinition.ISOLATION_REPEATABLE_READ);
            // 设置事务传播行为,必须有事务
            def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
            // 配置事务管理器
            TransactionStatus status = transactionManager.getTransaction(def);
            try {
                // 转账
                accountDao.out(outUser, money);
                accountDao.in(inUser, money);
                // 提交事务
                transactionManager.commit(status);
            } catch (Exception e) {
                e.printStackTrace();
                // 回滚事务
                transactionManager.rollback(status);
            }
    }
2.3 基于XML的声明式事务控制 2.3.1 开发步骤

引入tx命名空间事务管理器通知配置事务管理器AOP配置测试事务控制转账业务代码 2.3.2 引入tx命名空间

 

    

2.3.3 事务管理器通知配置
 
 
     
  
 
     	
     
     
	 

2.3.4 事务管理器AOP配置
 
  
      

2.3.5 事务参数的配置

name:切点方法名称

isolation:事务的隔离级别

propogation:事务的传播行为

timeout:超时时间

read-only:是否只读

2.3.6 CRUD事务常用配置
 
    
     
     
     
	 

2.4 基于注解的声明式事务控制 2.4.1 基本步骤

修改service层,增加事务注解修改spring核心配置文件,开启事务注解支持 2.4.2 开启事务配置

SpringConfig : @EnableTransactionManagement 开启事务

@Configuration
@ComponentScan("cn.knightzz")
@EnableAspectJAutoProxy
@EnableTransactionManagement
@import(DataSourceConfig.class)
public class SpringConfig {
2.4.3 Service添加注解

注意 : 事务注解的代码不要使用try catch 包裹, 否则无法捕获异常, 并进行回滚

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ, timeout = -1, readonly = false)
    @Override
    public void transfer(String outUser, String inUser, Double money) {
        accountDao.out(outUser, money);
        int i = 1 / 0;
        accountDao.in(inUser, money);
    }

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5719085.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存