【spring5】-【JdbcTemplate】

JdbcTemplate

JdbcTemplate:Spring框架对JDBC进行封装,使用JdbcTemplate方便实现对数据库操作

准备工作

一、引入相关jar包:

  1. 新建项目spring5_txdemo1,将以下jar包复制到lib文件夹中
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  2. 再将上面这些jar包引入项目:
    在这里插入图片描述
    二、在spring配置文件src/bean1.xml中配置数据库连接池
<!-- 数据库连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
	<property name="url" value="jdbc:mysql:///user_db" />
	<property name="username" value="root" />
	<property name="password" value="root" />
	<property name="driverClassName" value="com.mysql.jdbc.Driver" />
</bean>

当然,你也可以将上面这些配置写在property配置文件中,然后在spring配置文件src/bean1.xml中通过表达式取值
三、在spring配置文件src/bean1.xml中配置JdbcTemplate对象,注入DataSource

 <!-- 配置JdbcTemplate对象
    class:指定JdbcTemplate对象
-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
	<!--注入dataSource 
		name="dataSource"是固定写法,表示注入dataSource 
		ref="dataSource"这个dataSource指的是你上面数据库连接池时bean的id
	-->
	<property name="dataSource" ref="dataSource"></property>
</bean>

四、创建service类,创建dao类及其实现类:

public class UserService {}
public interface UserDao {}
public class UserDaoImpl implements UserDao {}

使用注解实现在service类中注入dao,在dao中注入jdbcTemplate对象。

  1. 在spring配置文件src/bean1.xml中开启注解扫描:<context:component-scan base-package="com.atguigu"></context:component-scan>
  2. 创建service对象、dao对象,在service类和dao实现类上面添加注解:
@Service
public class UserService {}

@Repository
public class UserDaoImpl implements UserDao {}
  1. 在service类中注入dao
@Service
public class UserService {
    //注入dao
    @Autowired
    private UserDao userDao;
}
  1. 在dao中注入jdbcTemplate对象,jdbcTemplate对象是在配置文件中创建的,所以他会根据类型,把配置文件的jdbcTemplate对象注入进来
@Repository
public class UserDaoImpl implements UserDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;
}

操作数据库

添加

一、本文用的数据库t_book对应内容如下:
在这里插入图片描述
二、对应数据库t_book创建实体类out/production/spring5_demo5/com/atguigu/spring5/entity/Book.class,代码如下:

public class Book {
    private String userId;
    private String username;
    private String ustatus;

    public Book() {}

    public String toString() {
        return "Book{userId='" + this.userId + '\'' + ", username='" + this.username + '\'' + ", ustatus='" + this.ustatus + '\'' + '}';
    }

    public void setUserId(String userId) {this.userId = userId;}
    public void setUsername(String username) {this.username = username;}
    public void setUstatus(String ustatus) {this.ustatus = ustatus;}
    public String getUserId() {return this.userId;}
    public String getUsername() {return this.username;}
    public String getUstatus() {return this.ustatus;}
}

三、编写service和dao

  1. 新建out/production/spring5_demo5/com/atguigu/spring5/service/BookService.class代码如下:
@Service
public class BookService {
    @Autowired
    private BookDao bookDao;
	// 添加的方法,调用dao中的方法实现。
    public void addBook(Book book) {
        bookDao.add(book);
    }
}
  1. 在dao中进行数据库添加操作,创建out/production/spring5_demo5/com/atguigu/spring5/dao/BookDao.class及其实现类out/production/spring5_demo5/com/atguigu/spring5/dao/BookDaoImpl.classBookDao类中代码如下:
public interface BookDao {
	// 添加的方法
	void add(Book var1);
}
  1. BookDaoImpl中调用JdbcTemplate对象里面的update(String sql, Object... args)方法实现添加操作
    (1)有两个参数:
    第一个参数:sql语句
    第二个参数:可变参数,设置sql语句值
    (2)BookDao的实现类BookDaoImpl中代码如下:
@Repository
public class BookDaoImpl implements BookDao {
	//注入 JdbcTemplate,JdbcTemplate对象我们通过配置文件已经创建了
    @Autowired
    private JdbcTemplate jdbcTemplate;
    //添加的方法
    @Override
    public void add(Book book) {
    	//1 创建 sql 语句
    	// t_book是数据库名称
    	// values(?,?,?)代表该数据库中有三个字段,每个字段用?表示
        String sql = "insert into t_book values(?,?,?)";
         //2 调用方法实现
        Object[] args = new Object[]{book.getUserId(), book.getUsername(), book.getUstatus()};
        int update = this.jdbcTemplate.update(sql, args);
        System.out.println(update);
    }
}

四、测试

@Test
public void testJdbcTemplate() {
	ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
	BookService bookService = context.getBean("bookService", 
BookService.class);
	Book book = new Book();
 	book.setUserId("1");
 	book.setUsername("java");
 	book.setUstatus("a");
 	bookService.addBook(book);
}

在这里插入图片描述

修改和删除

在service中新增两个方法updateBookdeleteBook

@Service
public class BookService {
    @Autowired
    private BookDao bookDao;

    public void addBook(Book book) {
        this.bookDao.add(book);
    }
	// 修改的方法
    public void updateBook(Book book) {
        this.bookDao.updateBook(book);
    }
	// 删除的方法,根据id删除,所以传入的参数是id
    public void deleteBook(String id) {
        this.bookDao.delete(id);
    }
}

在BookDao中新增两个方法updateBookdelete

public interface BookDao {
    void add(Book var1);
    void updateBook(Book var1);
    void delete(String var1);
}

BookDaoImpl中完成修改、删除操作,新增以下代码:

@Override
public void updateBook(Book book) {
	// 根据用户id修改username和ustatus的值
 	String sql = "update t_book set username=?,ustatus=? where user_id=?";
 	Object[] args = {book.getUsername(), book.getUstatus(),book.getUserId()};
 	int update = jdbcTemplate.update(sql, args);
 	System.out.println(update);
}

@Override
public void delete(String id) {
 	String sql = "delete from t_book where user_id=?";
 	int update = jdbcTemplate.update(sql, id);
 	System.out.println(update);
}

测试修改:

@Test
public void testJdbcTemplate() {
	ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
	BookService bookService = context.getBean("bookService", 
BookService.class);
	Book book = new Book();
 	book.setUserId("1");
 	book.setUsername("javaupup");
 	book.setUstatus("atguigu");
 	bookService.addBook(book);
}

测试删除:

@Test
public void testJdbcTemplate() {
	ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
	BookService bookService = context.getBean("bookService", 
BookService.class);
	bookService。deleteBook("1");
}

查询

查询返回某个值

一、查询表里面有多少条记录,返回是某个值
二、在service中添加以下代码,查询表记录数:public int findCount() {return bookDao.selectCount();}
三、在DAO中创建方法int selectCount();
四、在实现类BookDaoImpl中使用JdbcTemplate的queryForObject(String sql, Class<T> requiredType)方法实现查询返回某个值,该方法有两个参数:

  1. 第一个参数:sql语句
  2. 第二个参数:返回类型的Class
//查询表记录数
@Override
public int selectCount() {
 	String sql = "select count(*) from t_book";
 	Integer count = jdbcTemplate.queryForObject(sql, Integer.class);
	return count;
}

五、测试:

@Test
public void testJdbcTemplate() {
	ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
	BookService bookService = context.getBean("bookService", 
BookService.class);
	// 查询返回某个值
	int count = bookService.findCount();
	System.out.println(count);
}
查询返回对象

一、需求:查询图书详情
二、在service中添加以下代码,查询返回对象,因为是根据id查询,所以将id作为参数传进去:public Book findOne(String id) {return bookDao.findBookInfo(id);}
三、在DAO中创建方法Book findBookInfo(String var1);
四、在实现类BookDaoImpl中使用JdbcTemplate的queryForObject(String sql, RowMapper<T> rowMapper,Object.. args)方法实现查询返回某个对象,该方法有三个参数:

  1. 第一个参数:sql语句
  2. 第二个参数:RowMapper是接口,针对返回不同类型数据,使用这个接口里面实现类完成数据封装,在实际中写new BeanPropertyRowMapper<返回的对象的名字>(返回的对象的类型的class)
  3. 第三个参数:sql语句值,也就是sql语句中?的值
//查询返回对象
@Override
public Book findBookInfo(String id) {
	String sql = "select * from t_book where user_id=?";
 	//调用方法
 	Book book = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Book>(Book.class), id);
 	return book;
}

五、测试:

@Test
public void testJdbcTemplate() {
	ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
	BookService bookService = context.getBean("bookService", 
BookService.class);
	// 查询返回对象
	Book book = bookService.findOne("1");
	System.out.println(book);
}

JdbcTemplate帮你把查询的数据取到,帮你调Book类中的set方法,把值依次设置进去,然后再通过System.out.println(book);输出值

查询返回集合

一、需求:查询图书列表分页
二、在service中添加以下代码,查询返回对象,因为是根据id查询,所以将id作为参数传进去:public List<Book> findAll() {return this.bookDao.findAllBook();}
三、在DAO中创建方法List<Book> findAllBook();
四、在实现类BookDaoImpl中使用JdbcTemplate的query(String sql, RowMapper<T> rowMapper,Object.. args)方法实现查询返回某个对象,该方法有三个参数:

  1. 第一个参数:sql语句
  2. 第二个参数:RowMapper是接口,针对返回不同类型数据,使用这个接口里面实现类完成数据封装
  3. 第三个参数:sql语句值,可以省略不写
//查询返回集合
@Override
public int selectCount() {
	String sql = "select count(*) from t_book";
    Integer count = (Integer)this.jdbcTemplate.queryForObject(sql, Integer.class);
    return count;
}

五、测试:

@Test
public void testJdbcTemplate() {
	ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
	BookService bookService = context.getBean("bookService", 
BookService.class);
	// 查询返回对象
	List<Book> all = bookService.findAll();
	System.out.println(all);
}

JdbcTemplate帮你把查询的数据取到,先放到Book对象中,然后将多个Book对象放在List<Book>集合中返回

批量操作

一、批量操作:操作表里面多条记录
二、使用JdbcTemplate的batchUpdate(String sql, List<Object[]> batchArgs)实现批量操作,该方法有两个参数:

  1. 第一个参数:sql语句
  2. 第二个参数:List集合,添加多条记录数据
批量添加

一、在service中添加以下代码,进行批量添加:public void batchAdd(List<Object[]> batchArgs) {bookDao.batchAddBook(batchArgs);}
二、在DAO中创建方法void batchAddBook(List<Object[]> var1);
三、在实现类BookDaoImpl中使用JdbcTemplate实现批量添加操作

//批量添加
@Override
public void batchAddBook(List<Object[]> batchArgs) {
 	String sql = "insert into t_book values(?,?,?)";
 	int[] ints = jdbcTemplate.batchUpdate(sql, batchArgs);
 	System.out.println(Arrays.toString(ints));
}

底层逻辑:遍历List<Object[]> batchArgs集合,给每个对象Object[]执行"insert into t_book values(?,?,?)"语句进行添加,
四、测试:

@Test
public void testJdbcTemplate() {
	ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
	BookService bookService = context.getBean("bookService", 
BookService.class);
	List<Object[]> batchArgs = new ArrayList<>();
	Object[] o1 = {"3","java","a"};
	Object[] o2 = {"4","c++","b"};
	Object[] o3 = {"5","MySQL","c"};
	batchArgs.add(o1);
	batchArgs.add(o2);
	batchArgs.add(o3);
	//调用批量添加
	bookService.batchAdd(batchArgs);
}
批量修改

一、在service中添加以下代码,进行批量添加:public void batchUpdate(List<Object[]> batchArgs) {bookDao.batchUpdateBook(batchArgs);}
二、在DAO中创建方法void batchUpdateBook(List<Object[]> var1);
三、在实现类BookDaoImpl中使用JdbcTemplate实现批量修改操作

@Override
public void batchUpdateBook(List<Object[]> batchArgs) {
 	String sql = "update t_book set username=?,ustatus=? where user_id=?";
 	int[] ints = jdbcTemplate.batchUpdate(sql, batchArgs);
 	System.out.println(Arrays.toString(ints));
}

四、测试:

@Test
public void testJdbcTemplate() {
	ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
	BookService bookService = context.getBean("bookService", 
BookService.class);
	List<Object[]> batchArgs = new ArrayList<>();
	Object[] o1 = {"java0909","a3","3"};
	Object[] o2 = {"c++1010","b4","4"};
	Object[] o3 = {"MySQL1111","c5","5"};
	batchArgs.add(o1);
	batchArgs.add(o2);
	batchArgs.add(o3);
	//调用方法实现批量修改
	bookService.batchUpdate(batchArgs);
}
批量删除

一、在service中添加以下代码,进行批量添加:public void batchDelete(List<Object[]> batchArgs) {this.bookDao.batchDeleteBook(batchArgs);}
二、在DAO中创建方法void batchDeleteBook(List<Object[]> var1);
三、在实现类BookDaoImpl中使用JdbcTemplate的batchUpdate(String sql, List<Object[]> batchArgs)实现删除操作

@Override
public void batchDeleteBook(List<Object[]> batchArgs) {
 	String sql = "delete from t_book where user_id=?";
 	int[] ints = jdbcTemplate.batchUpdate(sql, batchArgs);
 	System.out.println(Arrays.toString(ints));
}

四、测试:

@Test
public void testJdbcTemplate() {
	ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
	BookService bookService = context.getBean("bookService", 
BookService.class);
	List<Object[]> batchArgs = new ArrayList<>();
	Object[] o1 = {"3"};
	Object[] o2 = {"4"};
	batchArgs.add(o1);
	batchArgs.add(o2);
	//调用方法实现批量删除
	bookService.batchDelete(batchArgs);
}

事务

一、什么事务

  1. 事务是数据库操作最基本单元,逻辑上一组操作,要么都成功,如果有一个失败所有操作都失败
  2. 典型场景:银行转账,如lucy转账100元给mary,lucy少100,mary多100

二、事务四个特性(ACID)

  1. 原子性:这个过程不可分割,要么都成功,一个失败都失败
  2. 一致性:操作前和操作后总量不变
  3. 隔离性:多事务操作时,每个事务不会有影响
  4. 持久性:事务提交后,表中数据真正发生变化

搭建事务操作环境

在这里插入图片描述
一、创建数据库表,添加记录
在这里插入图片描述
二、创建service,搭建dao,完成对象创建和注入关系

  1. service注入dao,在dao注入JdbcTemplate,代码如下:
@Service
public class UserService {
 	//注入 dao
 	@Autowired
 	private UserDao userDao;
}

@Repository
public class UserDaoImpl implements UserDao {
 	@Autowired
	private JdbcTemplate jdbcTemplate;
}
  1. 在JdbcTemplate注入DataSource,配置文件src/bean1.xml代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
                        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 组件扫描 -->
    <context:component-scan base-package="com.atguigu"></context:component-scan>

    <!-- 数据库连接池 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          destroy-method="close">
        <property name="url" value="jdbc:mysql:///user_db" />
        <property name="username" value="root" />
        <property name="password" value="root" />
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    </bean>

    <!-- JdbcTemplate对象
    class:指定JdbcTemplate对象
    -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--注入dataSource-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>
</beans>

三、在dao创建两个方法:多钱和少钱的方法,在service创建方法(转账的方法)

@Repository
public class UserDaoImpl implements UserDao {
 	@Autowired
 	private JdbcTemplate jdbcTemplate;
 	//lucy 转账 100 给 mary
 	//少钱
 	@Override
 	public void reduceMoney() {
 		String sql = "update t_account set money=money-? where username=?";
 		jdbcTemplate.update(sql,100,"lucy");
 	}
 	//多钱
 	@Override
 	public void addMoney() {
 		String sql = "update t_account set money=money+? where username=?";
 		jdbcTemplate.update(sql,100,"mary");
 	}
}
@Service
public class UserService {
 	//注入 dao
 	@Autowired
 	private UserDao userDao;
 	//转账的方法
 	public void accountMoney() {
 		//lucy 少 100
 		userDao.reduceMoney();
 		//mary 多 100
 		userDao.addMoney();
 	}
}

四、测试

public class TestBook {
    @Test
    public void testAccount() {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        UserService userService = context.getBean("userService", UserService.class);
        userService.accountMoney();
    }
}

五、上面代码,如果正常执行没有问题的,但是如果代码执行过程中出现异常,就会出现问题,可能Lucy少了100,但是Mary没有增加,那么需要使用事务解决。事务操作过程:
在这里插入图片描述

Spring事务管理

一、JavaEE中有三层结构:WEB、Service、DAO,将事务添加到Service 层(业务逻辑层)
二、在Spring进行事务管理操作有两种方式:编程式事务管理和声明式事务管理(使用)。不适用编程式事务管理方式是因为他需要通过代码来实现,会在每个需要事务管理的地方都写一些相同的代码,很冗余
三、声明式事务管理

  1. 基于注解方式(使用)
  2. 基于xml配置文件方式

四、在Spring进行声明式事务管理,底层使用AOP原理
五、创建对象不是new接口,而是new接口的实现类
六、Spring事务管理API:提供了一个接口,代表事务管理器,这个接口针对不同的框架提供不同的实现类
在这里插入图片描述

注解声明式事务管理

一、在spring配置文件src/bean1.xml引入名称空间tx
在这里插入图片描述
二、在spring配置文件配置事务管理器

<!--创建事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入数据源
	name="dataSource":表示注入dataSource
	ref="dataSource":指定注入的dataSource的id,也就是你在数据库连接池中设置的bean标签的id
-->
	<property name="dataSource" ref="dataSource"></property>
</bean>

三、开启事务注解

<!--开启事务注解 transaction-manager="事务管理器,即创建事务管理器的bean的id"-->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

四、在service类上面(或者service类里面方法上面)添加事务注解@Transactional

  1. 这个注解添加到类上面,也可以添加方法上面
  2. 如果把这个注解添加类上面,这个类里面所有的方法都添加事务,本文加在了类上面:
@Service
@Transactional
public class UserService {}
  1. 如果把这个注解添加方法上面,为这个方法添加事务

五、运行测试代码后显示:
在这里插入图片描述

声明式事务管理参数配置

在service类上面添加注解@Transactional,在这个注解里面可以配置事务相关参数:
在这里插入图片描述
一、propagation:事务传播行为。事务传播行为指的是多事务方法直接进行调用,这个过程中事务是如何进行管理的,即一个事务的方法被另一个事务的方法调用时,这个事务该如何进行处理?
在这里插入图片描述

  1. REQUIRED:事务A中有方法2,事务B中有方法1。如果单独执行事务B中的方法1,这个方法肯定会开启一个事务,即开启事务B。如果方法A中的方法2调用事务B中的方法1,那么首先方法2会开启事务A,方法2调用方法1时,方法1会加入到当前事务A中
  2. REQUIRED_NEW:事务A中有方法A,事务B中有方法B。如果方法A中的方法A调用事务B中的方法B,那么首先方法A会开启事务A,方法A调用方法B时,方法B会开启事务B,将事务A称为外层事务,事务B称为内层事务,内外层事务互不相干,加入外层事务调完方法B后出现异常,方法B依然能提交,不会回滚
  3. SUPPORTS:事务A中有方法A且事务A是REQUIRED方式,事务B中有方法B且事务B是SUPPORTS方式。如果单独执行事务B中的方法B,那方法B可以在非事务状态下进行。如果方法A中的方法A调用事务B中的方法B,那么首先方法A会开启事务A,方法A调用方法B时,方法B会加入到当前事务A中

二、isolation:事务隔离级别

  1. 隔离级别是为了解决事务中的隔离性而出现的概念
  2. 事务隔离性:多事务操作之间不会产生影响。不考虑隔离性产生很多问题,如三个读问题:脏读、不可重复读、虚(幻)读
    (1)脏读:一个未提交事务读取到另一个未提交事务的数据
    数据库中有一条记录:Lucy有5000元。现在东方不败和岳不群都想操作这条记录,不管谁操作这条记录都会开启一个事务,东方不败开启的事务为事务A,岳不群开启的事务为事务B,他将Lucy的钱改成了60000,但还没有提交事务,在脏读情况下,事务A读取这条记录时,获得的是事务B修改后的数据60000,然后事务B回滚了,数据又变回了5000,那么事务A读到的数据就是不准的。脏读指的是两个事务都没有提交,事务B改变了数据,事务A可以读到改变后的数,但是事务可以回滚,事务B回滚了,事务A读到的数据就不对了
    (2)不可重复读:一个未提交事务读取到另一提交事务修改数据
    数据库中有一条记录:Lucy有5000元。现在东方不败和岳不群都想操作这条记录,不管谁操作这条记录都会开启一个事务,东方不败开启的事务为事务A,岳不群开启的事务为事务B,假如两个人都开启了事务并且都得到了这条记录,事务B将数据改成了900,然后马上提交了事务,事务A没有提交但可以读到900。假如事务A在统计工资,那么他每次得到的数据都不一样
    (3)虚读:一个未提交事务读取到另一提交事务添加数据
  3. 通过设置事务隔离级别来解决以上三个读的问题:通过给service上的注解@Transactional添加参数来设置隔离级别:@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.REPEATABLE_READ)。隔离级别isolation可选参数如下:
    在这里插入图片描述
    MySQL中默认的隔离级别:REPEATABLE READ

三、timeout:超时时间

  1. 事务需要在一定时间timeout内进行提交,如果不提交进行回滚
  2. 默认值是-1 ,设置时间以秒单位进行计算
    四、readOnly:是否只读
  3. 读:查询操作,写:添加修改删除操作
  4. readOnly 默认值 false,表示可以查询,可以添加修改删除操作
  5. 设置 readOnly 值是 true,设置成 true 之后,只能查询
    五、rollbackFor:回滚。设置出现哪些异常进行事务回滚
    六、noRollbackFor:不回滚。设置出现哪些异常不进行事务回滚

XML声明式事务管理

在spring配置文件src/bean2.xml中进行配置:

  1. 配置事务管理器
  2. 配置通知
  3. 配置切入点和切面
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
                        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 组件扫描 -->
    <context:component-scan base-package="com.atguigu"></context:component-scan>

    <!-- 数据库连接池 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          destroy-method="close">
        <property name="url" value="jdbc:mysql:///user_db" />
        <property name="username" value="root" />
        <property name="password" value="root" />
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    </bean>

    <!-- JdbcTemplate对象 -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--注入dataSource-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--1 创建事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--注入数据源-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--2 配置通知-->
    <tx:advice id="txadvice">
        <!--配置事务参数-->
        <tx:attributes>
            <!--指定哪种规则的方法上面添加事务 
            我现在想在service的accountMoney方法上添加事务,所以name属性值为accountMoney,
            name属性值也可以写作account*,表示方法名以account开头的都加上事务-->
            <tx:method name="accountMoney" propagation="REQUIRED"/>
            <!--<tx:method name="account*"/>-->
        </tx:attributes>
    </tx:advice>

    <!--3 配置切入点和切面-->
    <aop:config>
        <!--配置切入点-->
        <aop:pointcut id="pt" expression="execution(* com.atguigu.spring5.service.UserService.*(..))"/>
        <!--配置切面
			advice-ref:指定通知
			pointcut-ref:指定切入点
			下面这行代码的意思是将事务的通知设置到pt方法上
		-->
        <aop:advisor advice-ref="txadvice" pointcut-ref="pt"/>
    </aop:config>
</beans>

完全注解声明式事务管理

1、创建配置类src/com/atguigu/spring5/config/TxConfig.java,使用配置类替代xml配置文件

@Configuration //表明这是个配置类
@ComponentScan(basePackages = "com.atguigu") //开启组件扫描
@EnableTransactionManagement //开启事务
public class TxConfig {
 	//创建数据库连接池。配置文件中使用bean标签实现,我们这使用@Bean创建
 	@Bean
 	public DruidDataSource getDruidDataSource() {
 		DruidDataSource dataSource = new DruidDataSource();
 		dataSource.setDriverClassName("com.mysql.jdbc.Driver");
 		dataSource.setUrl("jdbc:mysql:///user_db");
 		dataSource.setUsername("root");
 		dataSource.setPassword("root");
 		return dataSource;
 	}
 	//创建JdbcTemplate对象 上面的getDruidDataSource()一执行,在IOC容器中就有了一个dataSource对象
//    getJdbcTemplate(DataSource dataSource)把ataSource dataSource作为参数传进来
//    表示根据dataSource的类型在IOC容器中找到对象,把这个对象注入
 	@Bean
 	public JdbcTemplate getJdbcTemplate(DataSource dataSource) {
 		//到 ioc 容器中根据类型找到 dataSource
 		JdbcTemplate jdbcTemplate = new JdbcTemplate();
 		//注入 dataSource
 		jdbcTemplate.setDataSource(dataSource);
 		return jdbcTemplate;
 	}
 	//创建事务管理器
 	@Bean
 	public DataSourceTransactionManager getDataSourceTransactionManager(DataSource dataSource) {
 		DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
 		transactionManager.setDataSource(dataSource);
 		return transactionManager;
 	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值