Spring JDBC与事务管理(一)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: Spring JDBC与事务管理

本节,开始学习Spring JDBC模块与事务管理。说起JDBC我们一定不陌生,JDBC可以让我们使用Java程序去访问数据库。那作为Spring生态体系,肯定对JDBC也有良好的支持。所以这一篇博客,着重讲解Spring JDBC 与事务管理。


一.Spring JDBC


1.Spring JDBC简介


☯ Spring JDBC 是Spring框架用于处理关系型数据库的模块。

☯ Spring JDBC对JDBC的API进行封装,极大地简化了开发的工作量。

☯ jdbcTemplate是Spring JDBC核心类,提供数据CRUD(增删改查)方法。


这时候,你可能会抱有疑惑,为什么有Mybatis了,还需要Spring JDBC呢?


其实这两者面向的对象是不一样的,Mybatis作为一个ORM框架(Object Relational Mapping),它封装的程度较高,适合于中小企业进行软件的敏捷开发。让程序员可以快速地完成与数据库的交互工作。但是,我们学过Mybatis的都知道,这里面就涉及到一系列的例如XML的配置以及各种各样的操作细节,实际上封装的程度还是比较高的。封装的程度高,就意味着我们执行效率较低。但是Spring JDBC只是对原始的JDBC的API简单封装。对于一线的互联网大厂,无论是数据量,还是用户的并发量都是非常高的。这时侯,如果使用Mybatis,可能由于微小的性能上的差距,就会导致整体应用变慢。因此,作为一线大厂,他们很少使用市面上的成熟框架。更多的时候,是使用像Spring JDBC这样的轻量级的封装框架。在这个基础上,结合自己企业的特点进行二次的封装。可以说,Spring JDBC的执行效率比起Mybatis是要高的。也因为有了Spring 底层的IoC容器的存在,也不至于让程序像原生JDBC那样难以管理。Spring JDBC是介于ORM框架和原生JDBC之间的一个折中的选择。


那说到这里,Spring JDBC该如何使用呢?主要有以下的3个步骤。


2.Spring JDBC的使用步骤


☯ Maven工程引入spring-jdbc这个依赖

☯ 在applicationContext.xml中配置DataSource数据源。DataSource数据源是用于指向到底我们要连接哪种数据库的哪台服务器以及它的用户名和密码是什么等。

☯ 在Dao注入jdbcTemplate对象,实现数据CRUD。


3.Spring JDBC的配置过程


下面通过代码案例来讲解如何在Spring JDBC模块下,配置jdbcTemplate对象,同时实现增删改查的操作。这个案例需要用到一个建库脚本,我把它上传到CSDN上了,大家可以免费去下载。https://download.csdn.net/download/weixin_50216991/46916802


如果不想下载,建库脚本如下:


SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for employee
-- ----------------------------
DROP TABLE IF EXISTS `employee`;
CREATE TABLE `employee`  (
  `eno` int(11) NOT NULL,
  `ename` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `salary` float(10, 2) NOT NULL,
  `dname` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `hiredate` date NULL DEFAULT NULL,
  PRIMARY KEY (`eno`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of employee
-- ----------------------------
INSERT INTO `employee` VALUES (3308, '张三', 6000.00, '研发部', '2011-05-08');
INSERT INTO `employee` VALUES (3420, '李四', 8700.00, '研发部', '2006-11-11');
INSERT INTO `employee` VALUES (3610, '王五', 4550.00, '市场部', '2009-10-01');
SET FOREIGN_KEY_CHECKS = 1;


1.打开Idea,创建全新的Maven工程,创建好数据库表。

然后引入依赖,如下


    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.13</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.13</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.27</version>
        </dependency>
    </dependencies>


2.在resources目录下面创建applicationContext.xml文件,填入schema约束。


<?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"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
</beans>


3.在applicationContext.xml进行Spring JDBC的底层数据源的配置。


<?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"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    <!--进行Spring JDBC的底层配置(数据源的配置)-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/demo?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=Asia/Shanghai&amp;allowPublicKeyRetrieval=true"/>
        <property name="username" value="root"/>
        <property name="password" value="zc20020106"/>
    </bean>
</beans>


3.配置jdbcTemplate , 给Spring JDBC绑定相应的数据源。


<?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"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    <!--进行Spring JDBC的底层配置(数据源的配置)-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/demo?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=Asia/Shanghai&amp;allowPublicKeyRetrieval=true"/>
        <property name="username" value="root"/>
        <property name="password" value="zc20020106"/>
    </bean>
    <!--配置jdbcTemplate-->
    <!--这个beanId最好固定叫jdbcTemplate-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--给Spring JDBC绑定相应的数据源-->
        <property name="dataSource" ref="dataSource"/>
    </bean>
</beans>


4.回到工程目录,在java目录下新增com.haiexijun.entity包,然后在里面创建Employee员工实体类。作为员工实体,它自然要和数据表中的字段依依对应。下面编写一下Employee类的代码。在里面重写toString()方法利于调试。


package com.haiexijun.entity;
import java.util.Date;
public class Employee {
    private Integer eno;
    private String ename;
    private Float salary;
    private String dname;
    private Date hiredate;
    public Integer getEno() {
        return eno;
    }
    public void setEno(Integer eno) {
        this.eno = eno;
    }
    public String getEname() {
        return ename;
    }
    public void setEname(String ename) {
        this.ename = ename;
    }
    public Float getSalary() {
        return salary;
    }
    public void setSalary(Float salary) {
        this.salary = salary;
    }
    public String getDname() {
        return dname;
    }
    public void setDname(String dname) {
        this.dname = dname;
    }
    public Date getHiredate() {
        return hiredate;
    }
    public void setHiredate(Date hiredate) {
        this.hiredate = hiredate;
    }
    @Override
    public String toString() {
        return "Employee{ "+"eno="+eno+" , "+"ename="+ename+" , "+"salary="+salary+" , "+"dname="+dname+" , "+"hiredate="+hiredate+" }";
    }
}


5.创建com.haiexijun.dao包,在里面创建EmployeeDao类。作为EmployeeDao,它在进行数据操作时,依赖于jdbcTemplate。因为刚才已经在IoC容器里面进行配置了jdbcTemplate的配置,所以在容器启动以后,自动的会对jdbcTemplate进行初始化,在后期使用时,只需要在这个对象采用配置的方式注入到dao的jdbcTemplate属性中就可以了。


package com.haiexijun.dao;
import com.haiexijun.entity.Employee;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
public class EmployeeDao {
    private JdbcTemplate jdbcTemplate;
    //通过id来查找员工
    public Employee findById(Integer eno){
        //定义sql语句
        String sql="select * from employee where eno = ?";
        //进行指定的查询,将唯一返回的数据转换为对应的对象
        //参数1表示要执行的sql语句
        //参数2传入一个Object数组,里面的参数是要传入的?的参数
        //参数3表示把查询结果转换为的相应对象的类型。BeanPropertyRowMapper表示将Bean的属性与每一行的列进行对应类型匹配,来获取实体类型
        Employee employee= jdbcTemplate.queryForObject(sql,new Object[]{eno},new BeanPropertyRowMapper<Employee>(Employee.class));
        return employee;
    }
    public JdbcTemplate getJdbcTemplate() {
        return jdbcTemplate;
    }
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
}


6.编写好EmployeeDao后,需要在applicationContext.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"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    <!--进行Spring JDBC的底层配置(数据源的配置)-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/demo?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=Asia/Shanghai&amp;allowPublicKeyRetrieval=true"/>
        <property name="username" value="root"/>
        <property name="password" value="zc20020106"/>
    </bean>
    <!--配置jdbcTemplate-->
    <!--这个beanId最好固定叫jdbcTemplate-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--给Spring JDBC绑定相应的数据源-->
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--配置EmployeeDao-->
    <bean id="employeeDao" class="com.haiexijun.dao.EmployeeDao">
        <!--为Dao注入jdbcTemplate对象-->
        <property name="jdbcTemplate" ref="jdbcTemplate"/>
    </bean>
</beans>


到这里,算是配置完了,下面来测试一下:

创建一个入口类SrpingApplication,编写如下的方法:


import com.haiexijun.dao.EmployeeDao;
import com.haiexijun.entity.Employee;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringApplication {
    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        EmployeeDao employeeDao=context.getBean("employeeDao",EmployeeDao.class);
        Employee employee= employeeDao.findById(3308);
        System.out.println(employee);
    }
}


运行结果如下:


a97779d75ccc406793d4ccd916fd21c6.png


到这里,我们就完成了Sping JDBC的一个基本的配置过程。



相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
6月前
|
Java 关系型数据库 MySQL
深入解析 @Transactional——Spring 事务管理的核心
本文深入解析了 Spring Boot 中 `@Transactional` 的工作机制、常见陷阱及最佳实践。作为事务管理的核心注解,`@Transactional` 确保数据库操作的原子性,避免数据不一致问题。文章通过示例讲解了其基本用法、默认回滚规则(仅未捕获的运行时异常触发回滚)、因 `try-catch` 或方法访问修饰符不当导致失效的情况,以及数据库引擎对事务的支持要求。最后总结了使用 `@Transactional` 的五大最佳实践,帮助开发者规避常见问题,提升项目稳定性与可靠性。
888 12
|
Java 关系型数据库 数据库
Spring Boot多数据源及事务管理:概念与实战
【4月更文挑战第29天】在复杂的企业级应用中,经常需要访问和管理多个数据源。Spring Boot通过灵活的配置和强大的框架支持,可以轻松实现多数据源的整合及事务管理。本篇博客将探讨如何在Spring Boot中配置多数据源,并详细介绍事务管理的策略和实践。
1236 3
|
11月前
|
XML Java 数据库连接
Spring高手之路25——深入解析事务管理的切面本质
本篇文章将带你深入解析Spring事务管理的切面本质,通过AOP手动实现 @Transactional 基本功能,并探讨PlatformTransactionManager的设计和事务拦截器TransactionInterceptor的工作原理,结合时序图详细展示事务管理流程,最后引导分析 @Transactional 的代理机制源码,帮助你全面掌握Spring事务管理。
173 2
Spring高手之路25——深入解析事务管理的切面本质
|
Java Spring 容器
Spring IOC、AOP与事务管理底层原理及源码解析
【10月更文挑战第1天】Spring框架以其强大的控制反转(IOC)和面向切面编程(AOP)功能,成为Java企业级开发中的首选框架。本文将深入探讨Spring IOC和AOP的底层原理,并通过源码解析来揭示其实现机制。同时,我们还将探讨Spring事务管理的核心原理,并给出相应的源码示例。
348 9
|
Java 数据库连接 数据库
Spring基础3——AOP,事务管理
AOP简介、入门案例、工作流程、切入点表达式、环绕通知、通知获取参数或返回值或异常、事务管理
Spring基础3——AOP,事务管理
|
XML Java 数据库
Spring5入门到实战------15、事务操作---概念--场景---声明式事务管理---事务参数--注解方式---xml方式
这篇文章是Spring5框架的实战教程,详细介绍了事务的概念、ACID特性、事务操作的场景,并通过实际的银行转账示例,演示了Spring框架中声明式事务管理的实现,包括使用注解和XML配置两种方式,以及如何配置事务参数来控制事务的行为。
Spring5入门到实战------15、事务操作---概念--场景---声明式事务管理---事务参数--注解方式---xml方式
|
Java Spring 开发者
掌握Spring事务管理,打造无缝数据交互——实用技巧大公开!
【8月更文挑战第31天】在企业应用开发中,确保数据一致性和完整性至关重要。Spring框架提供了强大的事务管理机制,包括`@Transactional`注解和编程式事务管理,简化了事务处理。本文深入探讨Spring事务管理的基础知识与高级技巧,涵盖隔离级别、传播行为、超时时间等设置,并介绍如何使用`TransactionTemplate`和`PlatformTransactionManager`进行编程式事务管理。通过合理设计事务范围和选择合适的隔离级别,可以显著提高应用的稳定性和性能。掌握这些技巧,有助于开发者更好地应对复杂业务需求,提升应用质量和可靠性。
164 0
|
Java 数据库连接 API
Spring事务管理嵌套事务详解 : 同一个类中,一个方法调用另外一个有事务的方法
Spring事务管理嵌套事务详解 : 同一个类中,一个方法调用另外一个有事务的方法
1285 1
|
Java 开发者 Spring
深入解析 @Transactional:Spring 事务管理的艺术及实战应对策略
深入解析 @Transactional:Spring 事务管理的艺术及实战应对策略
176 2
|
设计模式 Java 数据库连接
【Spring源码】JDBC数据源访问实现
我们再来看看阅读线索三,这方面我们从设计模式进行入手。阅读线索三:从这个模块可以学到什么我们看下以下代码,PreparedStatement实例的是由PreparedStatementCreator实现的。再来看看PreparedStatementCreator接口,一共有三个子类实现。也就是说PreparedStatement的三种不同实现被封装到三个子类中,而具体需要哪种实现,只需要传入不同。
150 1
【Spring源码】JDBC数据源访问实现