Spring整合JDBC与事务管理
程序员文章站
2022-07-13 21:21:05
...
package com.kkb.test;
import com.kkb.bean.SpringTest;
import com.kkb.dao.StudentDao;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.kkb.service.StudentService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import java.beans.PropertyVetoException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Test01 {
private ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
/*
Day1025测试:Spring整合JDBC1
以最基础的方式连接数据库,使用Spring专用的数据库连接的封装类JdbcTemplate连接
知识点:
1.创建数据源连接信息,确定连接的Driver类型以及Jdbc连接的地址信息
2.输入账号密码
3.用数据源连接信息创建JdbcTemplate
4.编写要运行的数据库语句,利用JdbcTemplate执行sql语句
优点:
1.较最初连接数据库的方法简易许多
劣势:
1.由于是初次使用,只是简单的建立了与数据库的连接,没有进行基本的封装
2.创建对象依旧是用new方法,没有利用Spring框架中创建对象的方式,需要修改
*/
@Test
public void test() throws PropertyVetoException {
//创建数据源连接
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/mydb1?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false");
dataSource.setUser("root");
dataSource.setPassword("lovinghurt82");
//使用JDBCTemplate
//Spring专门用来封装数据库连接方法的专用类
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String sql = "INSERT INTO SPRINGTEST (NAME) VALUE (?)";
int test = jdbcTemplate.update(sql, "test");
System.out.println("插入的行数:"+test);
}
/* Day1025测试:Spring整合JDBC2
使用Spring自带的Dao父类JdbcDaoSupport来建立数据库之间的连接
知识点:
1.通过继承父类JdbcDaoSupport来使用JdbcTemplate
2.通过Spring容器给JdbcTemplate注入数据源信息DataSource,无需繁琐的手动添加
3.通过getJdbcTemplate()方法获取父类中的Template来执行SQL语句
4.update方法的使用
优势:
1.无需自己创建JdbcTemplate,直接使用父类提供的template即可,降低了耦合性
2.通过容器创建对象,符合Spring创建对象的规范
报错一:NullPointerException空指针异常
是因为没有给JdbcDaoSupport中的JdbcTemplate赋值,你需要给它赋值它才能知道要连接哪里,
此处使用容器创建,具体可以查看:application.xml第6-31行
*/
@Test
public void testInsert(){
ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
StudentDao studentDao = (StudentDao) ac.getBean("studentDao");
//StudentDao studentDao = new StudentDao();
SpringTest springTest = new SpringTest();
springTest.setName("test102501");
int insert = studentDao.insert(springTest);
System.out.println("插入的行数:"+insert);
}
/*
Day1025测试:Spring整合JDBC-增删改
与test02的操作基本相同,只是将insert的方法改成update的方法,并未有太大区别
知识点:
1.update方法的使用
*/
@Test
public void testUpdate(){
ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
StudentDao studentDao = (StudentDao) ac.getBean("studentDao");
//StudentDao studentDao = new StudentDao();
SpringTest springTest = new SpringTest();
springTest.setName("test102502");
springTest.setId(1);
int insert = studentDao.update(springTest);
System.out.println("修改的行数:"+insert);
}
/*
Day1025测试:Spring整合JDBC-增删改
与test02的操作基本相同,只是将insert的方法改成update的方法,并未有太大区别
知识点:
1.Update方法的使用
*/
@Test
public void testDelete(){
ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
StudentDao studentDao = (StudentDao) ac.getBean("studentDao");
//StudentDao studentDao = new StudentDao();
SpringTest springTest = new SpringTest();
springTest.setId(1);
int insert = studentDao.delete(springTest);
System.out.println("删除的行数:"+insert);
}
/*
Day1025测试:Spring整合JDBC-查询1
根据提供的ID查询数据库中相应的数据
知识点:
1.queryForObject方法的使用
SpringTest springtest = this.getJdbcTemplate().queryForObject(sql,
//此处传参(数组)↓ ↓此处处理获取的数据以及返回的数据类型
new Object[]{id}, new RowMapper<SpringTest>() {
@Override
public SpringTest mapRow(ResultSet resultSet, int i) throws SQLException {
SpringTest test = new SpringTest();
test.setId(resultSet.getInt("Id"));
test.setName(resultSet.getString("Name"));
return test;
}
});
报错2:
EmptyResultDataAccessException:Incorrect result size: expected 1, actual 0----不正确的结果大小:预期是1,实际是0
表示没有在数据库中找到相应的数据,应该是查到一个数据,但搜索到的数据与实际不符
*/
@Test
public void testFind(){
ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
StudentDao studentDao = (StudentDao) ac.getBean("studentDao");
SpringTest test = new SpringTest();
try {
test = studentDao.findById(1);
}catch (EmptyResultDataAccessException exception){
exception.printStackTrace();
}
System.out.println(test);
}
/*
Day1025测试:Spring整合JDBC-查询2
知识点:
1.与findById不同的地方在于,此次用template查询运用的方法是query
2.在传参RowMap中重写的方法中也只是返回单个对象,并非对象列表,是因为方法中已经封装好了相应的方法,返回的是以单个数据为元素的列表
*/
@Test
public void testFindAll(){
ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
StudentDao studentDao = (StudentDao) ac.getBean("studentDao");
List<SpringTest> test = new ArrayList<>();
try {
test = studentDao.findAll();
}catch (EmptyResultDataAccessException exception){
exception.printStackTrace();
}
System.out.println(test);
}
/*
Day1025测试:Spring整合JDBC-查询3
知识点:
1.queryForObject的另一个用法,不需要对获得的数据进行操作是,不需要传入参数RowMap
String sql = "SELECT COUNT(*) FROM SPRINGTEST";
// 此处传入需要获取的数据类型↓
return this.getJdbcTemplate().queryForObject(sql,Integer.class);
2.单个数据的获取使用queryForObject,多个数据的获取使用queryForMap
3.Map中键值对的获取可以使用entrySet来封装,活的Set列表,在通过Map.Entry类中的getKey和getValue方法来获取键值对的值
*/
@Test
public void testGetCount(){
ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
StudentDao studentDao = (StudentDao) ac.getBean("studentDao");
int count = studentDao.getCount();
System.out.println(count);
Map<String, Object> maxMin = studentDao.getMaxMin();
Set<Map.Entry<String, Object>> entries = maxMin.entrySet();
for (Map.Entry<String, Object> entry : entries) {
System.out.println(entry.getKey()+"---------"+entry.getValue());
}
}
/*
Day1025测试:针对事务管理器接口PlatformTransactionManager处理事务异常情况的实验,基于注解的事务管理
知识点:
1.事务管理器是PlatformTransactionManager接口对象,主要用于完成事务的提交、回滚,及获取事务的状态信息
2.Spring事务的默认回滚方式是:发生运行时异常和error时回滚,发生编译异常时提交。不过对于编译异常,程序员也可以手工设置回滚方式
3.基于注解的事务需要加上注解@Transactional,注解中要声明事务传播行为常量(propagation)以及回滚方式(rollbackFor),
事务传播常量常用的有以下几种:
(1)Propagation.REQUIRED
当前没有事务的时候,就会创建一个新的事务;如果当前有事务,就直接加入该事务,比较常用的
(2)设置 Propagation.SUPPORTS
支持当前事务,如果当前有事务,就直接加入该事务;当前没有事务的时候,就以非事务方式执行
(3)Propagation.MANDATORY
支持当前事务,如果当前有事务,就直接加入该事务;当前没有事务的时候,就抛出异常
(4)Propagation.REQUIRES_NEW
创建新事务,无论当前是否有事务都会创建新的
4.Spring提供的对事物的管理,就叫做生命是事务管理,在配置文件中配置即可,可以实现对事务控制最大程度的解耦
5.声明式事务管理的核心实现就是给予AOP
6.事务的粒度分为粗粒度与细粒度,细粒度即针对方法中的某几行代码进行开启提交回滚,而粗粒度是对整个方法进行开启提交回滚
*/
@Test
public void testTransactionManager(){
StudentService service = (StudentService) ac.getBean("studentService");
SpringTest test = new SpringTest(12, "test1026");
int insert = service.insert(test);
System.out.println(insert);
}
/*
Day1026测试:基于XML的事务管理
知识点:
1.Spring事务管理的核心在于AOP,在xml中创建AOP时记得要配置切入点(pointcut)以及事务通知(advisor)
2.事务通知中需要配置对应方法的名字以及事务传播常量,增删改中常量一般选择REQUIRED,查询的常量一般选择SUPPORT,且需要配置只读选项(read-only)
3.Pointcut(切入点)指声明的一个或多个连接点的集合。通过切入点指定一组方法。
注意:被标记为 final 的方法是不能作为连接点与切入点的,因为最终的是不能被修改的,不能被增强的。
4.Advice(通知/增强)是指拦截到Joinpoint(连接点)之后所要做的事情就是通知。
通知定义了增强代码切入到目标代码的时间点,是目标方法执行之前执行,还是之后执行等。通知类型不同,切入时间不同。
通知的类型:前置通知,后置通知,异常通知,最终通知,环绕通知。
切入点定义切入的位置,通知定义切入的时间。
*/
@Test
public void testTransactionManager02(){
StudentService service = (StudentService) ac.getBean("studentService");
SpringTest test = new SpringTest(12, "test1026");
int insert = service.insert2(test);
System.out.println(insert);
}
}
上一篇: express应用HTTPS总结
下一篇: 应用配置HTTPS,nginx
推荐阅读
-
为什么整合Spring与Struts2的时候,必须定义Struts2 Bean的Scope
-
Spring与Struts整合之让Spring管理控制器操作示例
-
JAVAEE——宜立方商城09:Activemq整合spring的应用场景、添加商品同步索引库、商品详情页面动态展示与使用缓存
-
spring Boot与Mybatis整合优化详解
-
SpringMVC+Spring+MyBatis 整合与图片上传简单示例
-
如何利用Spring的@Import扩展点与spring进行无缝整合
-
Spring与Struts整合之使用自动装配操作示例
-
redis与spring整合使用的步骤实例教程
-
Spring与Mybatis整合 将SqlSessionFactory的创建交给spring完成
-
【Spring与MyBatis整合】