Spring—学习笔记#day04

目录

1、spring中的JdbcTemplate[会用]

JdbcTemplate的作用

JdbcTemplate对象的创建

spring中配置数据源

在spring配置文件中配置 JdbcTemplate

最基本使用

使用xml文件

  保存、更新、删除、查询操作

在dao中使用 JdbcTemplate

第二种方式:让dao继承 JdbcDaoSupport

2、Spring中的事务控制

Spring事务控制我们要明确的

Spring中事务控制的 API 

PlatformTransactionManager

TransactionDefinition

TransactionStatus

基于XML的声明式事务控制(配置方式)重点

环境配置

配置步骤

基于注解的配置方式

环境配置

配置步骤

不使用 xml 的配置方式


1、spring中的JdbcTemplate[会用]

JdbcTemplate的作用

它就是用于和数据库交互的,实现对表的CRUD操作

它是 spring 框架中提供的一个对象,是对原始 Jdbc API 对象的简单封装。spring 框架为我们提供了很多
的操作模板类。
操作关系型数据的:
JdbcTemplate
HibernateTemplate
操作 nosql 数据库的:
RedisTemplate
操作消息队列的:
JmsTemplate
我们今天的主角在 spring-jdbc-5.0.2.RELEASE.jar 中,我们在导包的时候,除了要导入这个 jar 包
外,还需要导入一个 spring-tx-5.0.2.RELEASE.jar(它是和事务相关的)。

JdbcTemplate对象的创建

我们可以参考它的源码,来一探究竟:
public JdbcTemplate() {
}
public JdbcTemplate(DataSource dataSource) {
setDataSource(dataSource);
afterPropertiesSet();
}
public JdbcTemplate(DataSource dataSource, boolean lazyInit) {
setDataSource(dataSource);
setLazyInit(lazyInit);
afterPropertiesSet();
}
除了默认构造函数之外,都需要提供一个数据源。既然有set方法,依据我们之前学过的依赖注入,我们可以
在配置文件中配置这些对象。

spring中配置数据源

Spring—学习笔记#day04_第1张图片

在spring配置文件中配置 JdbcTemplate




    
    
        
        
    

    

    
    
        
        
        
        
    

最基本使用

/**
 * JdbcTemplate的最基本用法
 */
public class JdbcTemplateDemo1 {

    public static void main(String[] args) {
        //准备数据源:spring的内置数据源
        DriverManagerDataSource ds = new DriverManagerDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/eesy");
        ds.setUsername("root");
        ds.setPassword("1234");

        //1.创建JdbcTemplate对象
        JdbcTemplate jt = new JdbcTemplate();
        //给jt设置数据源
        jt.setDataSource(ds);
        //2.执行操作
        jt.execute("insert into account(name,money)values('ccc',1000)");
    }
}

使用xml文件

public class JdbcTemplateDemo2 {

    public static void main(String[] args) {
        //1.获取容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        //2.获取对象
        JdbcTemplate jt = ac.getBean("jdbcTemplate",JdbcTemplate.class);
        //3.执行操作
        jt.execute("insert into account(name,money)values('ddd',2222)");
    }
}

  保存、更新、删除、查询操作

/**
 * JdbcTemplate的CRUD操作
 */
public class JdbcTemplateDemo3 {

    public static void main(String[] args) {
        //1.获取容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        //2.获取对象
        JdbcTemplate jt = ac.getBean("jdbcTemplate",JdbcTemplate.class);
        //3.执行操作
        //保存
//        jt.update("insert into account(name,money)values(?,?)","eee",3333f);
        //更新
//        jt.update("update account set name=?,money=? where id=?","test",4567,7);
        //删除
//        jt.update("delete from account where id=?",8);
        //查询所有
//        List accounts = jt.query("select * from account where money > ?",new AccountRowMapper(),1000f);
//        List accounts = jt.query("select * from account where money > ?",new BeanPropertyRowMapper(Account.class),1000f);
//        for(Account account : accounts){
//            System.out.println(account);
//        }
        //查询一个
//        List accounts = jt.query("select * from account where id = ?",new BeanPropertyRowMapper(Account.class),1);
//        System.out.println(accounts.isEmpty()?"没有内容":accounts.get(0));

        //查询返回一行一列(使用聚合函数,但不加group by子句)
        Long count = jt.queryForObject("select count(*) from account where money > ?",Long.class,1000f);
        System.out.println(count);


    }
}

/**
 * 定义Account的封装策略
 */
class AccountRowMapper implements RowMapper{
    /**
     * 把结果集中的数据封装到Account中,然后由spring把每个Account加到集合中
     * @param rs
     * @param rowNum
     * @return
     * @throws SQLException
     */
    @Override
    public Account mapRow(ResultSet rs, int rowNum) throws SQLException {
        Account account = new Account();
        account.setId(rs.getInt("id"));
        account.setName(rs.getString("name"));
        account.setMoney(rs.getFloat("money"));
        return account;
    }
}

在dao中使用 JdbcTemplate

public class JdbcTemplateDemo4 {

    public static void main(String[] args) {
        //1.获取容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        //2.获取对象
        IAccountDao accountDao = ac.getBean("accountDao",IAccountDao.class);

        Account account = accountDao.findAccountById(1);
        System.out.println(account);

        account.setMoney(30000f);
        accountDao.updateAccount(account);
    }
}
/**
 * 账户的持久层实现类
 */
@Repository
public class AccountDaoImpl2 implements IAccountDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;


    @Override
    public Account findAccountById(Integer accountId) {
        List accounts = jdbcTemplate.query("select * from account where id = ?",new BeanPropertyRowMapper(Account.class),accountId);
        return accounts.isEmpty()?null:accounts.get(0);
    }

    @Override
    public Account findAccountByName(String accountName) {
        List accounts = jdbcTemplate.query("select * from account where name = ?",new BeanPropertyRowMapper(Account.class),accountName);
        if(accounts.isEmpty()){
            return null;
        }
        if(accounts.size()>1){
            throw new RuntimeException("结果集不唯一");
        }
        return accounts.get(0);
    }

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

有个小问题。就是我们的 dao 有很多时,每个 dao 都有一些重复性的代码。下面就是重复代码:
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;

第二种方式:让dao继承 JdbcDaoSupport

/**
 * 账户的持久层实现类
 */
public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao {

    @Override
    public Account findAccountById(Integer accountId) {
        List accounts = super.getJdbcTemplate().query("select * from account where id = ?",new BeanPropertyRowMapper(Account.class),accountId);
        return accounts.isEmpty()?null:accounts.get(0);
    }

    @Override
    public Account findAccountByName(String accountName) {
        List accounts = super.getJdbcTemplate().query("select * from account where name = ?",new BeanPropertyRowMapper(Account.class),accountName);
        if(accounts.isEmpty()){
            return null;
        }
        if(accounts.size()>1){
            throw new RuntimeException("结果集不唯一");
        }
        return accounts.get(0);
    }

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

思考:
两版 Dao  有什么区别呢?
答案:
在 第一种在 Dao  类中定义 JdbcTemplate  的方式,适用于所有配置方式(xml  和注解都可以)。
让 第二种让 Dao  继承 JdbcDaoSupport  的方式,只能用于基于 XML 的方式,注解用不了。

2、Spring中的事务控制

Spring事务控制我们要明确的

第一:JavaEE 体系进行分层开发,事务处理位于业务层,Spring 提供了分层设计 业务层的事务处理解决方案。
第二:spring 框架为我们提供了一组事务控制的接口。具体在后面的第二小节介绍。这组接口是在spring-tx-5.0.2.RELEASE.jar 中。
第三:spring 的事务控制都是基于 AOP 的,它既可以使用编程的方式实现,也可以使用配置的方式实现。我们学习的重点是使用配置的方式实现。

Spring中事务控制的 API 

PlatformTransactionManager

Spring—学习笔记#day04_第2张图片

TransactionDefinition

Spring—学习笔记#day04_第3张图片

事务的隔离级别

Spring—学习笔记#day04_第4张图片

事务的传播行为

REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。一般的选择(默认值)
SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行(没有事务)
MANDATORY:使用当前的事务,如果当前没有事务,就抛出异常
REQUERS_NEW:新建事务,如果当前在事务中,把当前事务挂起。
NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
NEVER:以非事务方式运行,如果当前存在事务,抛出异常
NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行 REQUIRED 类似的操作

超时时间

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

是否是只读事务

建议查询时设置为只读。

TransactionStatus

Spring—学习笔记#day04_第5张图片

基于XML的声明式事务控制(配置方式)重点

环境配置


        
            org.springframework
            spring-context
            5.0.2.RELEASE
        

        
            org.springframework
            spring-jdbc
            5.0.2.RELEASE
        

        
            org.springframework
            spring-tx
            5.0.2.RELEASE
        

        
            org.springframework
            spring-test
            5.0.2.RELEASE
        

        
            mysql
            mysql-connector-java
            5.1.6
        

        
            org.aspectj
            aspectjweaver
            1.8.7
        

        
            junit
            junit
            4.12
        
    

配置步骤




    
    
        
    

    
    
        
    


    
    
        
        
        
        
    

    
    
    
        
    

    
    
        
        
            
            
        
    

    
    
        
        
        
        
    

基于注解的配置方式

环境配置


        
            org.springframework
            spring-context
            5.0.2.RELEASE
        

        
            org.springframework
            spring-jdbc
            5.0.2.RELEASE
        

        
            org.springframework
            spring-tx
            5.0.2.RELEASE
        

        
            org.springframework
            spring-test
            5.0.2.RELEASE
        

        
            mysql
            mysql-connector-java
            5.1.6
        

        
            org.aspectj
            aspectjweaver
            1.8.7
        

        
            junit
            junit
            4.12
        
    

配置步骤




    
    

    
    
        
    


    
    
        
        
        
        
    

    
    
    
        
    


    
    

Spring—学习笔记#day04_第6张图片

Spring—学习笔记#day04_第7张图片

不使用 xml 的配置方式

@Configuration
@EnableTransactionManagement
public class SpringTxConfiguration {
//里面配置数据源,配置 JdbcTemplate,配置事务管理器。在之前的步骤已经写过了。
}

你可能感兴趣的:(Spring,Spring)