全部章节   >>>>


本章目录

4.1 配置数据源资源

4.1.1 JdbcTemplate介绍

4.1.2通过ComboPooledDataSource创建数据源

4.1.3 通过Spring配置创建数据源

4.1.4 读取外部properties文件配置创建数据源

4.1.5 实践练习

4.2  JdbcTemplate的单表操作

4.2.1 通过JdbcTemplate模板对象修改数据

4.2.2 通过JdbcTemplate模板对象删除数据

4.2.3 通过JdbcTemplate模板对象查询数据

4.2.4 实践练习

4.3 Spring的事务管理

4.3.1 Spring事务管理的核心接口

4.3.1 事务属性的定义

4.3.2 XML方式配置AOP完成Spring事务管理

4.3.3 注解方式配置AOP完成Spring事务管理

4.3.4 实践练习

4.4 综合案例

4.4.1 需求说明

4.4.1 实现思路

4.4.2 实践练习

总结


4.1 配置数据源资源

4.1.1 JdbcTemplate介绍

JdbcTemplate简介

传统的JDBC操作方法比较繁琐,为了使JDBC更加易于使用,Spring框架整合了JDBC,以此建立一个JDBC存取框架。

JdbcTemplate对象包含五类方法:

Execute()方法:可以用于执行任何SQL语句,一般用于执行DDL语句。

update()方法:update()方法用于执行新增、修改和删除等语句。

batchUpdate()方法:batchUpdate()方法用于执行批处理相关语句。

query()方法及queryForXXX()方法:用于执行查询相关语句。

call()方法:用于执行存储过程、函数相关语句。

4.1.2通过ComboPooledDataSource创建数据源

在实际开发中,通过C3P0连接池配置来获取数据源是现在比较流行的做法。C3P0提供核心工具类:ComboPooledDataSource存储数据源连接池。

示例:通过编码式的方法来创建数据源,然后获取JdbcTemplate对象,操作数据库中的t00_book表。

4.1.3 通过Spring配置创建数据源

示例:使用Spring配置方式来获取数据源

	<!-- 开启注解扫描功能 -->
<context:component-scan base-package="com.mhys"></context:component-scan>
<!-- 将连接池注册到容器 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/mysql"></property>
<property name="user" value="root"></property>
<property name="password" value="1q2w3e"></property>
</bean>
<!-- 将JdbcTemplate对象注册到容器 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
@Override
public int insertBook(Book book) {
String sql = "insert into t00_book values (?,?,?,?,?)";
int row = template.update(sql,book.getBookId(),book.getBookName(),book.getAuthor(),book.getPages(),book.getFlag()); return row;
}

4.1.4 读取外部properties文件配置创建数据源

在企业开发中,程序员开发的代码会放到多套环境中运行,比如:开发环境,多套测试环境,准生产环境,生产环境等,这样的话,数据源的配置会经常的更改,为了便于维护,经常会将数据源的信息保存在.properties配置文件中

示例:读取外部properties配置文件来获取数据源

jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://127.0.0.1:3306/mysql
jdbc.user=root
jdbc.password=1q2w3e
	<!-- 指定Spring容器读取db.properties文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 将连接池注册到容器 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>

4.1.5 实践练习

4.2  JdbcTemplate的单表操作

创建数据源的几种方式已经讲解完成,在后面的课程中都将使用读取外部properties文件的方式配置数据源。

Spring对数据库的操作在JDBC上面做了深层次的封装,使用Spring的注入功能,可以把DataSource注册到JdbcTemplate之中。

4.2.1 通过JdbcTemplate模板对象修改数据

示例:在MySQL数据库中创建t00_customer表,添加customerId、customerName、telphone和address四个字段,录入初始化数据;然后在applicationContext.xml配置文件中配置数据源;接着编写业务方法;最后执行业务方法,查看结果

@Repository("customerDao")
public class CustomerDaoImpl implements CustomerDao {
@Resource(name="jdbcTemplate")
private JdbcTemplate template; @Override
// 根据客户编号修改电话号码
public int modifyCustomerById(Customer customer) {
String telphone = customer.getTelphone();
String customerId= customer.getCustomerId();
String sql = "update t00_customer set telphone=? where customerId=?";
int row = template.update(sql, customer.getTelphone(), customer.getCustomerId());
return row;
}
}

4.2.2 通过JdbcTemplate模板对象删除数据

示例:通过JdbcTemplate模板对象根据客户编号删除一条客户信息

@Repository("customerDao")
public class CustomerDaoImpl implements CustomerDao {
// 原有代码省略
@Override
// 根据客户编号删除一条数据
public int deleteCustomerById(Customer customer) {
String customerId= customer.getCustomerId();
String sql = "delete from t00_customer where customerId=?";
int row = template.update(sql,customer.getCustomerId());
return row;
}
}

4.2.3 通过JdbcTemplate模板对象查询数据

通过JdbcTemplate模板对象根据客户编号查询一条客户信息

public Customer getCustomerById(String customerId) {
String sql =
"select customerId,customerName,telphone,address from t00_customer where customerId=?";
Customer customerTemp = template.queryForObject(sql,
new RowMapper<Customer>(){
@Override
public Customer mapRow(ResultSet rs, int arg1)
throws SQLException {
Customer customer = new Customer();
customer.setCustomerId(rs.getString("customerId"));
customer.setCustomerName(rs.getString("customerName"));
customer.setTelphone(rs.getString("telphone"));
customer.setAddress(rs.getString("address"));
return customer;
}
},
customerId); return customerTemp;
}

4.2.4 实践练习

4.3 Spring的事务管理

4.3.1 Spring事务管理的核心接口

学习Spring事务管理需要了解Spring事务管理涉及的接口,如果对整个接口框架有个大体了解会非常有利于学习Spring事务管理。

Spring事物管理高层抽象主要包括3个接口:PlatformTransactionManager(事务管理器)、TransactionDefinition(事物定义信息)和TransactionStatus(事物具体运行状态)。

Spring事务管理器的接口是org.springframework.transaction.PlatformTransactionManager,通过这个接口,Spring为各个平台如JDBC、Hibernate等都提供了对应的事务管理器,但是具体的实现是各个平台自己的事情。

事务管理器派生类型

对应持久层版本

org.springframework.jdbc.datasource.DataSourceTransactionManager

使用Spring JDBC或者MyBatis时使用

org.springframework.orm.hibernate3.HibernateTransactionManager

使用Hibernate3.0时使用

org.springframework.orm.jpa.JpaTransactionManager

使用JPA时使用

org.springframework.transaction.jta.JtaTransactionManager

使用JTA时使用

4.3.1 事务属性的定义

事务属性可以理解成事务的一些基本配置,描述了事务策略如何应用到方法上。事务属性包含了5个方面。

最常用的传播行为是PROPAGATION_REQUIRED传播行为,表示当前方法必须运行在事务中。如果当前事务存在,方法将会在该事务中运行。否则,会启动一个新的事务

4.3.2 XML方式配置AOP完成Spring事务管理

Spring提供了对事务控制的实现。用户如果想用Spring的声明式事务管理,只需要在配置文件中配置即可; 不想使用时直接移除配置,这个实现了对事务控制的最大程度的解耦。

示例:通过Spring事务管理,模拟银行转账的功能。

@Repository("t00_accountDao")
public class T00_accountDaoImpl implements T00_accountDao {
@Resource(name="jdbcTemplate")
private JdbcTemplate template; @Override
public void increaseMoney(String accountid, double money) {
String sql = "update t00_account set money=money+? where accountid=?";
template.update(sql, money, accountid);
}
@Override
public void decreaseMoney(String accountid, double money) {
String sql = "update t00_account set money=money-? where accountid=?";
template.update(sql, money, accountid);
}
}
@Service("t00_accountService")
public class T00_accountServiceImpl implements T00_accountService {
@Resource(name="t00_accountDao")
private T00_accountDao t00_accountDao; @Override
public void transferMoney(String from, String to, double money) {
t00_accountDao.decreaseMoney(from, money);
t00_accountDao.increaseMoney(to, money);
}
}
<!-- 事务核心管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean> <!-- 配置事务通知 -->
<tx:advice transaction-manager="transactionManager" id="txAdvice">
<tx:attributes>
<tx:method name="*Money" isolation="DEFAULT" read-only="false" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice> <!-- 配置织入 -->
<aop:config>
<aop:pointcut expression="execution(* com.mhys.demo.service..*ServiceImpl.*Money(..))" id="txPointcut"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
</aop:config>

4.3.3 注解方式配置AOP完成Spring事务管理

在实际开发中,注解方式配置AOP事务也是常见的一种方式,只需要在配置文件中,开启注解管理AOP事务的驱动,在通过@Transactional注解就实现了声明式事务的管理。

示例:通过注解方式配置AOP事务,模拟银行转账的功能。

@Service("t00_accountService")
@Transactional
public class T00_accountServiceImpl implements T00_accountService {
@Resource(name="t00_accountDao")
private T00_accountDao t00_accountDao; @Override
public void transferMoney(String from, String to, double money) {
t00_accountDao.decreaseMoney(from, money);
// 增减异常
int i= 1/0;
t00_accountDao.increaseMoney(to, money);
}
}
<!-- 配置数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${db.driverClass}"></property>
<property name="jdbcUrl" value="${db.jdbcUrl}"></property>
<property name="user" value="${db.user}"></property>
<property name="password" value="${db.password}"></property>
</bean>
<!-- 配置JdbcTemplate对象 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置事务核心管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 开启注解方式管理AOP事务 -->
<tx:annotation-driven />

@Transactional注解可以作用于接口、接口方法、类以及类方法上。当作用于类上时,该类的所有public方法将都具有该类型的事务属性,同时也可以在方法级别使用该标注来覆盖类级别的定义。

4.3.4 实践练习

4.4 综合案例

4.4.1 需求说明

根据本章所学知识,开发一个简易的学生信息模块,实现学生信息录入功能、学生信息删除功能以及学生信息查询功能。

要求:

使用外部properties文件获取数据源。

使用Template对象操作数据库。

使用注解方式开启事务管理。

4.4.1 实现思路

需求说明解决思路:

创建学生表,并创建学生实体类。

在applicaioinContext.xml配置文件中开启注解扫描、配置数据源、注册JdbcTemplate对象、配置事务核心管理器和开启注解方式管理AOP事务。

创建学生数据访问接口及实现类。

创建学生业务接口类及实现类。

编写主方法完成业务接口方法调用,并模拟异常回滚。

4.4.2 实践练习

总结

JdbcTemplate对象主要提供的五类方法。

  • Execute()方法:可以用于执行任何SQL语句,一般用于执行DDL语句。
  • update()方法:update()方法用于执行新增、修改以及删除等语句。
  • batchUpdate()方法:batchUpdate()方法用于执行批处理相关语句。
  • query()方法及queryForXXX()方法:用于执行查询相关语句。
  • call()方法:用于执行存储过程、函数相关语句。

通过ComboPooledDataSource创建数据源、通过Spring配置创建数据源和读取外部properties文件配置创建数据源

Spring企业级程序设计 • 【第4章 Spring持久化层和事务管理】的更多相关文章

  1. Spring企业级程序设计 • 【目录】

    章节 内容 实践练习 Spring企业级程序设计目录(作业笔记) 第1章 Spring企业级程序设计 • [第1章 Spring之旅] 第2章 Spring企业级程序设计 • [第2章 Spring ...

  2. Spring企业级程序设计作业目录(作业笔记)

    Spring企业级程序设计 • [目录] 第1章 Spring之旅  >>> 1.1.6 使用Eclipse搭建的Spring开发环境,使用set注入方式为Bean对象注入属性值并打 ...

  3. Spring企业级程序设计 • 【第7章 Spring框架整合】

    全部章节   >>>> 本章目录 7.1 模型数据解析及控制器返回值 7.1.1 SSM框架环境搭建 7.1.1 ModelAndView多种用法 7.1.2 整合MyBati ...

  4. Spring企业级程序设计 • 【第5章 Spring MVC快速入门】

    全部章节   >>>> 本章目录 5.1 Spring MVC设计概述及其框架结构 5.1.1 Spring MVC介绍 5.1.1 Spring MVC优势 5.1.2  S ...

  5. Spring企业级程序设计 • 【第3章 面向切面编程】

    全部章节   >>>> 本章目录 3.1 AOP基本概念和术语 3.1.1 AOP概念 3.1.2 AOP的术语解释 3.1.3 通知类型介绍 3.1.4 通过AOP模拟事务操 ...

  6. Spring企业级程序设计 • 【第2章 Spring Bean管理进阶】

    全部章节   >>>> 本章目录 2.1 bean标签和import标签 2.1.1 标签中的id属性和name属性 2.1.2 Bean的作用范围和生命周期 2.1.2 Be ...

  7. Spring企业级程序设计 • 【第1章 Spring之旅】

    全部章节   >>>> 本章目录 1.1 Spring框架基础 1.1.1 Spring特点及体系结构 1.1.1 Spring的体系结构 1.1.2  使用Eclipse搭建 ...

  8. Spring入门篇——第7章 Spring对AspectJ的支持

    第7章 Spring对AspectJ的支持 介绍Spring对AspectJ的支持 7-1 AspectJ介绍及Pointcut注解应用 实例 完成了在xml文件的配置 7-2 Advice定义及实例 ...

  9. Spring入门篇——第6章 Spring AOP的API介绍

    第6章 Spring AOP的API介绍 主要介绍Spring AOP中常用的API. 6-1 Spring AOP API的Pointcut.advice概念及应用 映射方法是sa开头的所有方法 如 ...

随机推荐

  1. JS控制元素的显示和隐藏

    利用来JS控制页面控件显示和隐藏有两种方法,两种方法分别利用HTML的style中的两个属性,两种方法的不同之处在于控件隐藏后是否还在页面上占空位. 方法一: document.getElementB ...

  2. css相关,flex布局全通!

    寻根溯源话布局 一切都始于这样一个问题:怎样通过 CSS 简单而优雅的实现水平.垂直同时居中. 记得刚开始学习 CSS 的时候,看到 float 属性不由得感觉眼前一亮,顺理成章的联想到 Word 文 ...

  3. 【leetcode】721. Accounts Merge(账户合并)

    Given a list of accounts where each element accounts[i] is a list of strings, where the first elemen ...

  4. 03-Collection用例管理及批量执行

    当我们对一个或多个系统中的很多用例进行维护时,首先想到的就是对用例进行分类管理,同时还希望对这批用例做回归测试 .在postman也提供了这样一个功能,就是Collection .通过这个Collec ...

  5. linux vi(vim)常用命令汇总(转)

    前言 首先解析一个vim vi是unix/linux下极为普遍的一种文本编辑器,大部分机器上都有vi的各种变种,在不同的机器上常用不同的变种软件,其中vim比较好用也用的比较广泛.vim是Vi Imp ...

  6. sonic 安装记录

    https://github.com/valeriansaliou/sonic $ rustc --versionrustc 1.50.0-dev ubantu环境 rocksdb 安装依赖 apt ...

  7. redis入门到精通系列(三):key的通用操作和redis内部db的通用操作

    五种数据类型都用到了key,key本身是一种字符串,通过key可以获取redis中保存的对象.这一篇博客就将介绍key的通用操作. (一)key基本操作 删除key del key key是否存在 e ...

  8. 『学了就忘』Linux服务管理 — 79、源码包安装的服务管理

    目录 1.源码包服务的启动管理 2.源码包服务的自启动管理 3.让源码包服务被服务管理命令识别 1.源码包服务的启动管理 # 通过源码包的安装路径,找到该服务的启动脚本, # 也就是获得该服务的启动脚 ...

  9. Python的 垃圾回收机制

    垃圾回收 1. 小整数对象池 整数在程序中的使用非常广泛,Python为了优化速度,使用了小整数对象池, 避免为整数频繁申请和销毁内存空间. Python 对小整数的定义是 [-5, 257) 这些整 ...

  10. JAVA发送xml格式的接口请求

    /** * * @param urlStr 接口地址 * @param xmlInfo xml格式参数数据 * @return */ public static String sendMsgXml(S ...