Spring 数据库编程

Spring JDBC

传统的JDBC在操作数据库时,需要先打开数据库连接,执行SQL语句,然后封装结果,最后关闭数据库连接等资源。频繁的数据库操作会产生大量的重复代码,造成代码冗余,Spring的JDBC模块负责数据库资源管理和错误处理,大大简化了开发人员对数据库的操作,使开发人员可以从频繁的数据库操作中解脱出来,从而将更多的精力投入编写业务逻辑中。

JdbcTemplate

针对数据库操作,Spring框架提供了JdbcTemplate类,JdbcTemplate是一个模板类,Spring JDBC中的更高层次的抽象类均在JdbcTemplate模板类的基础上创建。

JdbcTemplate类提供了操作数据库的基本方法,包括添加、删除、查询和更新。在操作数据库时,JdbcTemplate类简化了传统JDBC中的复杂步骤,这可以让开发人员将更多精力投入到业务逻辑中。

JdbcTemplate类继承自抽象类JdbcAccessor,同时实现了JdbcTemplate接口。抽象类JdbcAccessor提供了一些访问数据库时使用的公共属性,具体如下:

  • DataSource:DataSource主要功能是获取数据库连接。在具体的数据操作中,它还提供对数据库连接的缓冲池和分布式事务的支持。
  • SQLExceptionTranslator:SQLExceptionTranslator是一个接口,它负责对SQLException异常进行转译工作。
Spring JDBC的配置

Spring JDBC中的4个包说明:

包名说明
core(核心包)包含了JDBC的核心功能,包括JdbcTemplate类、SimpleJdbcInsert类、SimpleJdbcCall类以及NamedParameterJdbcTemplate类。
dataSource(数据源包)包含访问数据源的实用工具类,它有多种数据源的实现,可以在Java EE容器外部测试JDBC代码。
object(对象包)以面向对象的方式访问数据库,它可以执行查询、修改和更新操作并将返回结果作为业务对象,并且在数据表的列和业务对象的属性之间映射查询结果。
support(支持包)包含了core和object包的支持类,如提供异常转换功能的SQLException类。

Spring对数据库的操作都封装在了core、dataSource、object和support这4个包中,想要使用Spring JDBC,就需要对这些包进行配置。在Spring中,JDBC的配置是在配置文件applicationContext.xml中完成的。

配置数据源:包括数据库驱动​​、连接数据库url​​、连接数据库用户名​​、连接数据库密码​​。

<bean id="dataSource" class=
"org.springframework.jdbc.datasource.DriverManagerDataSource"><!-- 数据库驱动 --><property name="driverClassName" value="com.mysql.jdbc.Driver"/><!-- 连接数据库url --><property name="url" value="jdbc:mysql://localhost:3306/spring"/><property name="username" value="root"/><!-- 连接数据库用户名 --><property name="password" value="root"/><!-- 连接数据库密码 -->
</bean>

配置JDBC模板:必须使用默认数据源。

<bean id="JdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><!-- 默认必须使用数据源 --><property name="dataSource" ref="dataSource"/>
</bean>

配置注入类

<bean id="xxx" class="Xxx"><property name="JdbcTemplate" ref="JdbcTemplate"/>
</bean>

dataSource配置的4个属性:

属性名含义
driverClassName所使用的驱动名称,对应驱动JAR包中的Driver类
url数据源地址
username访问数据库的用户名
password访问数据库的密码
dataSource属性值的设定要求

在dataSource的4个属性中,需要根据数据库类型或者系统配置设置相应的属性值。例如,如果数据库类型不同,需要更改驱动名称;如果数据库不在本地,则需要将地址中的localhost替换成相应的主机IP;默认情况下,数据库端口号可以省略,但如果修改过MySQL数据库的端口号,则需要加上修改后的端口号。此外,连接数据库的用户名和密码需要与数据库创建时设置的用户名和密码保持一致。

接下来,我们通过JDBCTemplate的实现数据库的增删改查操作

首先实现数据库的配置如下

 <!-- 数据源 --><bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url"value="jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=utf-8&amp;serverTimezone=Asia/Shanghai"/><property name="username" value="root"/><property name="password" value="root"/></bean><!-- 配置jdbc模板 JdbcTemplate --><bean id="JdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"/></bean><!-- 配置注入类 --><bean id="user" class="com.lq.entities.User"><property name="JdbcTemplate" ref="JdbcTemplate"/></bean>

创建项目,目录如下:

在pom文件里添加maven依赖,我们特意引入了spring-jdbc和mysql-connector-java依赖,为了实现jdbc操作。

        <dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>6.1.16</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>6.1.16</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>6.1.16</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.1.16</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-expression</artifactId><version>6.1.16</version></dependency><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.1</version><scope>test</scope></dependency><!--        jdbc包依赖--><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.3.7</version></dependency><!--    事务管理依赖--><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>5.3.7</version></dependency><!--   数据库驱动依赖--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.25</version></dependency>

创建实体类Account

package com.lq.entities;/*** @Author: Luqing Teacher* @CreateTime: 2025-02-27* @Description: Account* @Version: 1.0*/public class Account {private int id;private String username;private Double balance;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public Double getBalance() {return balance;}public void setBalance(Double balance) {this.balance = balance;}@Overridepublic String toString() {return "Account{" +"id=" + id +", username='" + username + '\'' +", balance=" + balance +'}';}
}

创建接口AccountDao​

package com.lq.dao;import com.lq.entities.Account;import java.util.List;/*** @Author: lzq* @CreateTime: 2025-02-27* @Description: AccountDao* @Version: 1.0*/public interface AccountDao {public int addAccount(Account account);public int updateAccount(Account account);public int deleteAccount(int id);public Account findAccountById(int id);public List<Account> findAllAccount();
}

增删改查的接口实现:

package com.lq.dao.impl;import com.lq.dao.AccountDao;
import com.lq.entities.Account;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;import java.util.List;/*** @Author: Luqing Teacher* @CreateTime: 2025-02-27* @Description: 实现类* @Version: 1.0*/public class AccountDaoImpl implements AccountDao {private JdbcTemplate jdbcTemplate;public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}@Overridepublic int addAccount(Account acc) {String sql =  "INSERT INTO account (username, balance) VALUES (?, ?)";Object[] obj = new Object[]{acc.getUsername(),acc.getBalance()};int result = this.jdbcTemplate.update(sql, obj);return result;}@Overridepublic int updateAccount(Account account) {String sql = "update account set username=?,balance=? where id=?";Object[] obj = new Object[]{account.getUsername(),account.getBalance(),account.getId()};int result = jdbcTemplate.update(sql, obj);return result;}@Overridepublic int deleteAccount(int id) {String sql = "delete from account where id=?";int result = jdbcTemplate.update(sql, id);return result;}@Overridepublic Account findAccountById(int id) {String sql = "select * from account where id=?";//创建一个新的BeanPropertyRowMapper对象RowMapper<Account> rowMapper = new BeanPropertyRowMapper<>(Account.class);//将id绑定到sql中,并且将查询结果封装到Account对象中Account account = this.jdbcTemplate.queryForObject(sql, rowMapper, id);return account;}@Overridepublic List<Account> findAllAccount() {String sql = "select * from account";RowMapper<Account> rowMapper = new BeanPropertyRowMapper<>(Account.class);List<Account> accounts = this.jdbcTemplate.query(sql, rowMapper);return accounts;}
}

本案例的Spring配置文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 数据源 --><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/springjdbc?useUnicode=true&amp;characterEncoding=utf-8&amp;serverTimezone=Asia/Shanghai"/><property name="username" value="root"/><property name="password" value="root"/></bean><!-- 配置jdbc模板 JdbcTemplate --><bean id="JdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"/></bean><bean id="accountDao" class="com.lq.dao.impl.AccountDaoImpl"><property name="jdbcTemplate" ref="JdbcTemplate"/></bean></beans>

接下来进行测试

package com.lq.test;import com.lq.dao.AccountDao;
import com.lq.entities.Account;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;import java.lang.annotation.Target;
import java.util.List;/*** @Author: Luqing Teacher* @CreateTime: 2025-02-27* @Description: jdbcTest* @Version: 1.0*/public class JdbcTest {@Testpublic void test1(){ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");JdbcTemplate jdbcTemplate = (JdbcTemplate) app.getBean("JdbcTemplate");jdbcTemplate.execute("" +"create table account("+ "id int primary key auto_increment,"+"username varchar(50),"+"balance double)");System.out.println("创建成功");}@Testpublic void test2(){ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");AccountDao accountDao = (AccountDao) app.getBean("accountDao");Account account =  new Account();account.setUsername("肖炎");account.setBalance(1000.0);int res = accountDao.addAccount(account);if(res>0){System.out.println("成功添加了"+res+"条数据");}else{System.out.println("添加失败");}}@Testpublic void test3(){ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");AccountDao accountDao = (AccountDao) app.getBean("accountDao");Account account =  new Account();account.setId(1);account.setUsername("小医仙");account.setBalance(1500.0);int res = accountDao.updateAccount(account);if(res>0){System.out.println("成功修改了"+res+"条数据");}else{System.out.println("修改失败");}}@Testpublic void test4(){ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");AccountDao accountDao = (AccountDao) app.getBean("accountDao");int res = accountDao.deleteAccount(1);if(res>0){System.out.println("成功删除了"+res+"条数据");}else{System.out.println("删除失败");}}@Testpublic void test5(){ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");AccountDao accountDao = (AccountDao) app.getBean("accountDao");Account account = accountDao.findAccountById(2);System.out.println(account);System.out.println("------------------------");List<Account> allAccount = accountDao.findAllAccount();for (Account account1 : allAccount) {System.out.println(account1);}}
}
JdbcTemplate类中常用的查询方法
方法说明
List query(Stringsql,RowMapper rowMapper)执行String类型参数提供的SQL语句,并通过参数rowMapper返回一个List类型的结果。
List query(Stringsql, PreparedStatementSetter pss, RowMapper rowMapper)根据String类型参数提供的SQL语句创建PreparedStatement对象,通过参数rowMapper将结果返回到List中。
List query(Stringsql, Object[]args, RowMapper rowMapper)使用Object[]的值来设置SQL语句中的参数值,rowMapper是个回调方法,直接返回List类型的数据。
queryForObject(Stringsql, RowMapper rowMapper, Object…args)将args参数绑定到SQL语句中,并通过参数rowMapper返回一个Object类型的单行记录。
queryForList(Stringsql,Object[]args, class<T>elementType)该方法可以返回多行数据的结果,但必须返回列表,args参数是sql语句中的参数,elementType参数返回的是List数据类型。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/79534.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

492Q 型气缸盖双端面铣削组合铣床总体设计

一、引言 492Q 型气缸盖是发动机的重要组成部分&#xff0c;其双端面的加工精度对发动机的性能和可靠性有着重要影响。设计一款适用于 492Q 型气缸盖双端面铣削的组合铣床&#xff0c;能够提高加工效率和质量&#xff0c;满足发动机生产的需求。 二、总体设计要求 加工精度&…

颚式破碎机的设计

一、引言 颚式破碎机作为矿山、建材等行业的重要破碎设备&#xff0c;其性能优劣直接影响物料破碎效率与质量。随着工业生产规模的扩大和对破碎效率要求的提高&#xff0c;设计一款高效、稳定、节能的颚式破碎机具有重要意义。 二、设计需求分析 处理能力&#xff1a;根据目…

第三阶段面试题

Nginx nginx常用模块以及其功能 proxy模块&#xff0c;进行代理功能 ssl模块&#xff0c;进行HTTPS协议的使用 gzip模块&#xff0c;进行传输数据的压缩 upstream模块&#xff0c;进行反向代理时使用 static模块&#xff0c;静态资源进行访问的模块 cache模块&#xff0…

鸿蒙NEXT开发键盘工具类(ArkTs)

export declare type KeyboardCallBack (show: boolean, height: number) > void; import { AppUtil } from ./AppUtil; import { LogUtil } from ./LogUtil; import { ArrayUtil } from ./ArrayUtil;/*** 键盘工具类* author 鸿蒙布道师* since 2025/04/18*/ export class…

基于 LabVIEW 的电液伺服阀测试台开发

开发了一种基于 LabVIEW 图形编程语言的自动测试系统&#xff0c;能够完成电液伺服阀的空载流量特性、压力增益特性、内泄漏特性等静态特性的自动测试。针对测试过程中干扰信号频段与正常信号频段接近&#xff0c;普通数字滤波器滤波效果不佳的问题&#xff0c;采用迭代滤波分解…

【uniapp】vue2 使用 Vuex 状态管理

创建store文件夹&#xff1a;store/index.js // index.js import Vue from vue import Vuex from vuex import address from ./modules/address.jsVue.use(Vuex)const store new Vuex.Store({modules: {address} })export default store 创建modules文件夹&#xff1a;modul…

c# 简单实现将Message的内容保存到txt中,超过100个则清理旧文件

using System; using System.IO; using System.Threading;public static class LogManager {private static readonly object _fileLock new object(); // 线程安全锁private const int MaxFiles 100; // 最大文件数限制private const string LogDire…

阿里云镜像加速仅支持阿里云产品了

最近在拉取docker镜像时一直报超时的错误&#xff1a; docker pull hello-world Using default tag: latest Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exce…

从零实现Git安装、使用

一、git安装 Git官方下载 1.下载exe程序 2.双击安装&#xff0c;一直点击next&#xff0c;默认安装 安装完成后&#xff0c;在任意文件夹右键&#xff0c;出现下图所示&#xff0c;即为安装成功。 3.【Git Bash Here】调出命令窗口&#xff0c;设置用户名和 email 地址。 gi…

生产环境中如何使用Caffeine+Redis实现二级缓存(详细分析了遇到的各种情况)

生产环境中如何使用CaffeineRedis实现二级缓存&#xff08;详细分析了各种情况&#xff09; 本篇主要讲解的是实现CaffeineRedis实现一个现成的使用流程。下一篇讲解什么是Caffeine以及caffeine的使用 00背景&#xff1a; 使用Caffeine和Redis的二级缓存方案源自于分布式系统…

RT-Thread开发文档合集

瑞萨VisionBoard开发实践指南 RT-Thread 文档中心 RT-Thread-【RA8D1-Vision Board】 RA8D1 Vision Board上的USB实践RT-Thread问答社区 - RT-Thread 【开发板】环境篇&#xff1a;05烧录工具介绍_哔哩哔哩_bilibili 【RA8D1-Vision Board】基于OpenMV 实现图像分类_哔哩哔哩_…

甘果桌面tv版下载-甘果桌面安卓电视版使用教程

甘果桌面 TV 版是一款备受关注的应用&#xff0c;它可以让安卓电视的界面更加个性化、操作更加便捷。接下来&#xff0c;我们就详细了解一下甘果桌面 TV 版的下载方法以及安卓电视版的使用教程。 甘果桌面 TV 版下载 打开你的安卓电视&#xff0c;找到并进入电视自带的应用商店…

RAII资源管理理解

基础介绍 RAII (Resource Acquisition Is Initialization) 是一种 C 编程范式&#xff0c;这不是一个语法特性&#xff0c;而是一种处理方式。RAII的思想&#xff1a; 资源获取与对象初始化同时发生资源释放与对象销毁同时发生通过对象的生命周期来管理资源&#xff0c;确保资…

解锁元生代:ComfyUI工作流与云原生后端的深度融合

目录 蓝耘元生代&#xff1a;智算新势力崛起​ ComfyUI 工作流创建详解​ ComfyUI 初印象​ 蓝耘平台上搭建 ComfyUI 工作流​ 构建基础工作流实操​ 代码示例与原理剖析​ 云原生后端技术全景 云原生后端概念解析​ 核心技术深度解读​ 蓝耘元生代中两者的紧密联系​…

实战篇|多总线网关搭建与量产验证(5000 字深度指南)

引言 1. 环境准备与硬件选型 1.1 项目需求分析 1.2 SoC 与开发板选型 1.3 物理接口与 PCB 设计 1.4 电源与供电保护 2. 软件架构与协议栈移植 2.1 分层架构详解 2.2 协议栈移植步骤 2.3 高可用驱动设计 2.4 映射逻辑与 API 定义 3. 开发流程与实践 3.1 敏捷迭代与里程碑 3.2 核…

Kafka安全认证技术:SASL/SCRAM-ACL方案详解

#作者 &#xff1a;张桐瑞 文章目录 1Kafka安全认证技术介绍2基础设置3 配置SASL/SCRAM认证3.1编写server.properties配置3.2编写kafka.conf密码文件3.3编写user.properties配置文件3.4编写kafka-run-class.sh脚本文件3.5Zk中增加kafka用户3.6启动kafka进程 1Kafka安全认证技术…

TCP/IP和UDP协议的发展历程

TCP/IP和UDP协议的发展历程 引言 互联网的发展史是人类技术创新的辉煌篇章&#xff0c;而在这一发展过程中&#xff0c;通信协议发挥了奠基性的作用。TCP/IP&#xff08;传输控制协议/互联网协议&#xff09;和UDP&#xff08;用户数据报协议&#xff09;作为互联网通信的基础…

PhotoShop学习10

1.画板功能的使用 使用画板功能可以轻松针对不同的设备和屏幕尺寸设计网页和 APP。画板是一种容器&#xff0c;类似于特殊图层组。画板中的图层在图层面板中&#xff0c;按画板进行分组。 使用画板&#xff0c;一个文档中可以有多个设计版面&#xff0c;这样可以在画板之间轻…

X-AnyLabeling开源程序借助 Segment Anything 和其他出色模型的 AI 支持轻松进行数据标记。

一、软件介绍 文末提供源码和程序下载学习 使用 X-AnyLabeling开源程序可以 导入、管理和保存数据。用户可以通过多种方式导入图像和视频文件&#xff0c;包括快捷方式或菜单选项。此外&#xff0c;它还涵盖数据删除、图像切换以及标签和图像数据的保存&#xff0c;以确保高效…

【深度解析】PlatformIO多环境配置实践:ESP32/ESP32-S3/ESP32-C3适配指南

一、前言&#xff1a;为什么需要多环境配置&#xff1f; 在物联网开发中&#xff0c;我们经常需要适配不同型号的硬件平台&#xff08;如ESP32系列&#xff09;,并且github上多数关于ESP32的都适配了多种开发板。传统开发方式需要为每个平台维护独立项目&#xff0c;而Platfor…