栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring学习第四天:JdbcTemplate,spring中的事务

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring学习第四天:JdbcTemplate,spring中的事务

JdbcTemplate 依赖项

除mysql驱动以外还需要以下两个jar包

		
            org.springframework
            spring-jdbc
            5.3.10
        
        
            org.springframework
            spring-tx
            5.3.10
        

其中spring-tx是事务控制相关的

最基本的使用

基本使用和c3p0和dbutils差别不大

    public static void main(String[] args) {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUsername("root");
        dataSource.setPassword("adminadmin");
        dataSource.setUrl("jdbc:mysql://localhost:3306/spring_test");
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        jdbcTemplate.execute("insert into account(name,money) values('ccc',123)");
    }

写到这里我们可以注意到这里有很多语句可以使用到spring中的IOC,那么下步我们就进行对spring的配置
JdbcTemplate的IOC配置:
xml配置文件




    
        
        
        
        
    

    
        
    

主函数

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("Bean.xml");
        JdbcTemplate jdbcTemplate = (JdbcTemplate)context.getBean("jdbcTemplate");
        jdbcTemplate.execute("insert into account(name,money) values('ccc',123)");
    }
改成原来常用的Dao模式

创建接口:

package com.spring.dao;

import com.spring.beans.Account;

import java.util.List;


public interface IAccountDao {
    
    public List findAll();

    
    public Account findById(Integer id);

    
    public void update(Account account);

    
    public void delete(Integer id);

    
    public void insert(Account account);

    
    public Integer moneyNumber(Integer money);

}

创建其实现类:

package com.spring.dao.impl;

import com.spring.beans.Account;
import com.spring.dao.IAccountDao;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;


public class AccountDao implements IAccountDao {
    private JdbcTemplate jdbcTemplate;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Override
    public List findAll() {
        return jdbcTemplate.query("select * from account", new BeanPropertyRowMapper(Account.class));
    }

    @Override
    public Account findById(Integer id) {
        try {
            return jdbcTemplate.query("select * from account where id = ?", new BeanPropertyRowMapper(Account.class),id).get(0);
        }
        catch (Exception e){
            Account account =new Account();
            account.setName("NOTFOUND");
            return account;
        }
    }

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

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

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

    @Override
    public Integer moneyNumber(Integer money) {
        return jdbcTemplate.queryForObject(" select count(*) from account where money > ? ", Integer.class, 900);
    }
}

再进行springIOC的配置即可使用



    
        
    

    
        
        
        
        
    

	
        
	

进行到这里,我们会发现一个问题,如果我们有多个dao接口的实现类,他们其中的

    private JdbcTemplate jdbcTemplate;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

这段代码是重复的
此时我们便可以提取这段代码 创建AccountDaoSupper类

package com.spring.dao.impl;

import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;

public class AccountDaoSupper {
    private JdbcTemplate jdbcTemplate;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public JdbcTemplate getJdbcTemplate() {
        return jdbcTemplate;
    }

    public void setDatasource(DataSource dataSource){
        jdbcTemplate = new JdbcTemplate(dataSource);
    }
}

然后再创建dao时就可以extends AccountDaoSupper implements IAccountDao了
对应的其中所有对jdbcTemplate都将改为getJdbcTemplate()
改后效果是这样的:

package com.spring.dao.impl;

import com.spring.beans.Account;
import com.spring.dao.IAccountDao;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;


public class AccountDao extends AccountDaoSupper implements IAccountDao {

    @Override
    public List findAll() {
        return getJdbcTemplate().query("select * from account", new BeanPropertyRowMapper(Account.class));
    }

    @Override
    public Account findById(Integer id) {
        try {
            return getJdbcTemplate().query("select * from account where id = ?", new BeanPropertyRowMapper(Account.class),id).get(0);
        }
        catch (Exception e){
            Account account =new Account();
            account.setName("NOTFOUND");
            return account;
        }
    }

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

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

    @Override
    public void insert(Account account) {
        getJdbcTemplate().update("insert into account(name,money) values(?,?)",account.getName(),account.getMoney());
    }

    @Override
    public Integer moneyNumber(Integer money) {
        return getJdbcTemplate().queryForObject(" select count(*) from account where money > ? ", Integer.class, 900);
    }
}

然后再进行xml的修改:



    
        
    

    
        
        
        
        
    


但实际上AccountDaoSupper中的代码Spring已经为我们提供好了,我们删除掉AccountDaoSupper换成继承JdbcDaoSupport这时便可以实现相同功能,而无需创建AccountDaoSupper了

package com.spring.dao.impl;

import com.spring.beans.Account;
import com.spring.dao.IAccountDao;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.support.JdbcDaoSupport;

import java.util.List;


public class AccountDao extends JdbcDaoSupport implements IAccountDao {

    @Override
    public List findAll() {
        return getJdbcTemplate().query("select * from account", new BeanPropertyRowMapper(Account.class));
    }

    @Override
    public Account findById(Integer id) {
        try {
            return getJdbcTemplate().query("select * from account where id = ?", new BeanPropertyRowMapper(Account.class),id).get(0);
        }
        catch (Exception e){
            Account account =new Account();
            account.setName("NOTFOUND");
            return account;
        }
    }

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

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

    @Override
    public void insert(Account account) {
        getJdbcTemplate().update("insert into account(name,money) values(?,?)",account.getName(),account.getMoney());
    }

    @Override
    public Integer moneyNumber(Integer money) {
        return getJdbcTemplate().queryForObject(" select count(*) from account where money > ? ", Integer.class, 900);
    }
}
spring中的事务

在需要事务时我们可以使用spring-tx这个jar包来进行事务管理
那么先进行maven导包的配置



    4.0.0

    org.example
    spring_day04_06TX_zhujie
    1.0-SNAPSHOT

    
        8
        8
    
    jar

    
        
            org.springframework
            spring-context
            5.3.9
        
        
            org.springframework
            spring-jdbc
            5.3.10
        
        
            org.springframework
            spring-tx
            5.3.10
        
        
            mysql
            mysql-connector-java
            8.0.25
        
        
            org.aspectj
            aspectjweaver
            1.9.8.M1
        
    


首先我们先看看xml版本

首先最基本的当然是创建数据库封装的bean对象

package com.spring.beans;


public class Account {

    private int id;

    private String name;

    private float money;

    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 float getMoney() {
        return money;
    }

    public void setMoney(float money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", name='" + name + ''' +
                ", money=" + money +
                '}';
    }
}

再来创建 持久层Dao的接口类

package com.spring.dao;

import com.spring.beans.Account;

import java.util.List;


public interface IAccountDao {
    
    public List findAll();

    
    public Account findById(Integer id);

    
    public void update(Account account);

    
    public void delete(Integer id);

    
    public void insert(Account account);

    
    public Integer moneyNumber(Integer money);

    
    public Account findByName(String name);


}

再来创建他的实现类AccountDao

package com.spring.dao.impl;

import com.spring.beans.Account;
import com.spring.dao.IAccountDao;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.support.JdbcDaoSupport;

import java.util.List;



public class AccountDao extends JdbcDaoSupport implements IAccountDao {

    @Override
    public List findAll() {
        return getJdbcTemplate().query("select * from account", new BeanPropertyRowMapper(Account.class));
    }

    @Override
    public Account findById(Integer id) {
        try {
            return getJdbcTemplate().query("select * from account where id = ?", new BeanPropertyRowMapper(Account.class),id).get(0);
        }
        catch (Exception e){
            Account account =new Account();
            account.setName("NOTFOUND");
            return account;
        }
    }

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

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

    @Override
    public void insert(Account account) {
        getJdbcTemplate().update("insert into account(name,money) values(?,?)",account.getName(),account.getMoney());
    }

    @Override
    public Integer moneyNumber(Integer money) {
        return getJdbcTemplate().queryForObject(" select count(*) from account where money > ? ", Integer.class, 900);
    }

    @Override
    public Account findByName(String name) {
        try {
            List query = getJdbcTemplate().query("select * from account where name = ?", new BeanPropertyRowMapper(Account.class), name);
            if (query.size()==1){
                return query.get(0);
            }
            else {
                return query.get(-1);
            }
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }
}

创建业务层接口

package com.spring.service;

import com.spring.beans.Account;


public interface IAccountService {
    
    Account findAccountById(Integer id);

    
    void transfer(String sourceName,String targetName,float money);
}

及业务层实现类

package com.spring.service.impl;

import com.spring.service.IAccountService;
import com.spring.beans.Account;
import com.spring.dao.IAccountDao;


public class AccountServiceImpl implements IAccountService {
    private IAccountDao accountDao;

    public void setAccountDao(IAccountDao accountDao) {
        this.accountDao = accountDao;
    }

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

    @Override
    public void transfer(String sourceName, String targetName, float money) {
        System.out.println("转账");
        Account sourceAccount = accountDao.findByName(sourceName);
        Account targetAccount = accountDao.findByName(targetName);
        sourceAccount.setMoney(sourceAccount.getMoney()-money);
        targetAccount.setMoney(targetAccount.getMoney()+money);
        accountDao.update(sourceAccount);
        int i= 1/0;
        accountDao.update(targetAccount);
    }
}

之后我们通过xml的方式对其进行配置
先看看不带事务的配置





    
        
    

    
        
    


    
        
        
        
        
    

编写主函数:

package com.spring.jdbcTemplate;
import com.spring.service.IAccountService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class JdbcTemplate_test {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("Bean.xml");
        IAccountService service = (IAccountService) context.getBean("accountServiceImpl");
        service.transfer("aaa","bbb",200);
    }
}

此时执行主函数,会抛出异常,异常原因是因为业务层实现类里int i= 1/0;,而且会进行错误的转账,这时我们就可以添加事务进行解决了
修改bean.xml





    
        
    

    
        
    


    
        
        
        
        
    


    
        
    


    
        
        
            
            
        
    


    

        

        
    


即可完成事务的配置,此时运行便可以得到正常的结果

再来看看注解的配置

修改原来xml的bean.xml
主要注意第一句和最后一句的修改



    
    

    
        
    

    
        
    


    
        
        
        
        
    


    
        
    
    
    


然后今天我们就只需要配置需要添加事务的类,这里专指业务层实现类AccountServiceImpl

package com.spring.service.impl;

import com.spring.service.IAccountService;
import com.spring.beans.Account;
import com.spring.dao.IAccountDao;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;


@Transactional
public class AccountServiceImpl implements IAccountService {
    private IAccountDao accountDao;

    public void setAccountDao(IAccountDao accountDao) {
        this.accountDao = accountDao;
    }

    @Transactional(propagation = Propagation.SUPPORTS,readonly = true)
    @Override
    public Account findAccountById(Integer id) {
        return accountDao.findById(id);
    }

    @Transactional(propagation = Propagation.REQUIRED,readonly = false)
    @Override
    public void transfer(String sourceName, String targetName, float money) {
        System.out.println("转账");
        Account sourceAccount = accountDao.findByName(sourceName);
        Account targetAccount = accountDao.findByName(targetName);
        sourceAccount.setMoney(sourceAccount.getMoney()-money);
        targetAccount.setMoney(targetAccount.getMoney()+money);
        accountDao.update(sourceAccount);
//        int i= 1/0;
        accountDao.update(targetAccount);
    }
}

这时我们对比xml和注解两种配置方式
我们发现注解要针对每个方法做出不同的配置
而xml则不需要

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/338116.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号