SSM学习——Spring JDBC

Spring JDBC

概念

Spring的JDBC模块负责数据库资源管理和错误处理,简化了开发人员对数据库的操作。

Spring JDBC通过配置数据源JDBC模板来配置。

针对数据库操作,Spring框架提供了JdbcTemplate类,它是Spring框架数据抽象层的基础,是Spring JDBC的核心类。

SpringTemplate

JdbcAccessor提供了访问数据库使用的公共属性,例如Data Source,DataSource主要功能是获取数据库连接,还可以引入对数据库连接的缓冲池和分布式事务的支持;JdbcOperations定义了可以使用的操作集合,例如增删改查(CURD)。

Spring JDBC模块由4个包组成:
Spring JDBC package

下面我们真正来用一下。

Spring JDBC实践

数据库创建

首先我们在MySQL中创建一个数据库,由于我是Mac环境,所以我直接在终端中执行SQL语句来完成。

如果你没有修改过密码,执行以下命令

mysql -uroot

如果修改过密码请执行以下命令,根据提示输入密码,输入的时候看不见

mysql -u root -p

如果你是Windows可以通过sqlyog连接。

以下部分通用:

执行SQL语句创建数据库

CREATE DATABASE db_javaee;

我们接下来为这个数据库创建一个单独的用户来管理它,用户名为db_javaee,密码是dbjavaeepassword

CREATE USER 'db_javaee'@'localhost' IDENTIFIED BY 'dbjavaeepassword';

这里有必要说明下,如果数据库与你开发环境在同一台机器上,这里可写'localhost',如果是远程的数据库要改为'%',即(以下同理)

CREATE USER 'db_javaee'@'%' IDENTIFIED BY 'dbjavaeepassword';

给这个用户授予权限,如果是远程别忘了改成'%'

GRANT ALL ON db_javaee.* TO 'db_javaee'@'localhost';

刷新权限

flush privileges;

这里有个问题得注意下,如果你的MySQL版本是5.7到这里就没啥问题了。如果是MySQL8.0以及更高,则加密算法由原来的sha256_password改成了caching_sha2_password,导致连接新版本数据库报错。

新版本用户需要追加

ALERT USER 'db_javaee'@'localhost' IDENTIFIED WITH mysql_native_password by 'dbjavaeepassword';

如果你root用户登陆不上也有可能是因为这个原因,这时候你就要像Mac用户一样到终端里连接,并将此处的db_javaee改为root才能在旧版sqlyog里或者navcat里连接。

项目创建

我们还是创建一个Maven项目,名称为top.cairbin.test3,然后在pom.xml里添加依赖包

<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.1.5.RELEASE</version>
</dependency>
<dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.1.5.RELEASE</version>
</dependency>
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version>
</dependency>
<dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.1.5.RELEASE</version><scope>test</scope>
</dependency>

注意这里的mysql-connector-java请用较新的,我之前用5.1.47会报错。

同样创建与src平级的resources目录并use as source folder,在里面创建app.xml(跟我们之前的AppCtx.xml一样,名称不固定随你便,不过在main中的必须与这里的文件名一致),并写入如下内容

<?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 http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!-- 指定需要扫描的包,使注解生效 --><context:component-scanbase-package="top.cairbin.test3" /><!-- 配置dataSource --><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/db_javaee" /><!--连接数据库的用户名 --><property name="username" value="db_javaee" /><!--连接数据库的密码 --><property name="password" value="dbjavaeepassword" /></bean><!-- 配置JDBC模板 --><bean id="jdbcTemplate"class="org.springframework.jdbc.core.JdbcTemplate"><!-- 默认必须使用数据源 --><property name="dataSource" ref="dataSource" /></bean>
</beans>

如果你数据库用户名和密码设置与我不一样,记得修改这里的value属性。

App.java中测试

package top.cairbin.test3;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;public class App 
{public static void main( String[] args ){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app.xml");// 获取JdbcTemplate实例JdbcTemplate jdTemplate = (JdbcTemplate) applicationContext.getBean("jdbcTemplate");// 使用execute()方法执行SQL语句,创建用户账户管理表accountjdTemplate.execute("create table account(" + "id int primary key auto_increment," +"username varchar(50)," + "balance double)");System.out.println("账户表account创建成功!");}
}

点击运行按钮后就可以看到表创建成功了

编写测试

我们创建一个Account测试类

package top.cairbin.test3;public class Account {private int id;       // 账户idprivate String username; // 用户名private double balance;  // 账户余额public Integer getId() {return id;}public void setId(Integer 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;}public String toString() {return "Account [id=" + id + ", "+ "username=" + username + ", balance=" + balance + "]";}
}

再建立一个IAccountDao接口

package top.cairbin.test3;import java.util.List;public interface IAccountDao {// 添加public int addAccount(Account account);// 更新public int updateAccount(Account account);// 删除public int deleteAccount(int id);	// 通过id查询public Account findAccountById(int id);// 查询所有账户public List<Account> findAllAccount();
}

然后定义AccountDao类实现这个接口

package top.cairbin.test3;
import java.util.List;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;@Repository("accountDao")
public class AccountDao implements IAccountDao {// 声明JdbcTemplate属性并添加注解@Autowired
private JdbcTemplate jdbcTemplate;// 添加账户public int addAccount(Account account) {// 定义SQLString sql = "insert into account(username,balance) value(?,?)";// 定义数组来存放SQL语句中的参数Object[] obj = new Object[] { account.getUsername(), account.getBalance() };// 执行添加操作,返回的是受SQL语句影响的记录条数int num = this.jdbcTemplate.update(sql, obj);return num;}// 更新账户public int updateAccount(Account account) {// 定义SQLString sql = "update account set username=?,balance=? where id = ?";// 定义数组来存放SQL语句中的参数Object[] params = new Object[] { account.getUsername(), account.getBalance(), account.getId() };// 执行添加操作,返回的是受SQL语句影响的记录条数int num = this.jdbcTemplate.update(sql, params);return num;}// 删除账户public int deleteAccount(int id) {// 定义SQLString sql = "delete from account where id = ? ";// 执行添加操作,返回的是受SQL语句影响的记录条数int num = this.jdbcTemplate.update(sql, id);return num;}// 通过id查询账户数据信息public Account findAccountById(int id) {//定义SQL语句String sql = "select * from account where id = ?";// 创建一个新的BeanPropertyRowMapper对象RowMapper<Account> rowMapper = new BeanPropertyRowMapper<Account>(Account.class);// 将id绑定到SQL语句中,并通过RowMapper返回一个Object类型的单行记录return this.jdbcTemplate.queryForObject(sql, rowMapper, id);}// 查询所有账户信息public List<Account> findAllAccount() {// 定义SQL语句String sql = "select * from account";// 创建一个新的BeanPropertyRowMapper对象RowMapper<Account> rowMapper = new BeanPropertyRowMapper<Account>(Account.class);// 执行静态的SQL查询,并通过RowMapper返回结果return this.jdbcTemplate.query(sql, rowMapper);}}

创建测试类SpringJdbcTest,编写测试单元

package top.cairbin.test3;import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;public class SpringJdbcTest {@Testpublic void mainTest() {// 加载配置文件ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app.xml");// 获取JdbcTemplate实例JdbcTemplate jdTemplate = (JdbcTemplate) applicationContext.getBean("jdbcTemplate");// 使用execute()方法执行SQL语句,创建用户账户管理表accountjdTemplate.execute("create table account(" + "id int primary key auto_increment," +"username varchar(50)," + "balance double)");System.out.println("账户表account创建成功!");}@Testpublic void addAccountTest() {// 加载配置文件ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app.xml");// 获取AccountDao实例IAccountDao accountDao = (IAccountDao) applicationContext.getBean("accountDao");// 创建Account对象,并向Account对象中添加数据Account account = new Account();account.setUsername("tom");account.setBalance(1000.00);// 执行addAccount()方法,并获取返回结果int num = accountDao.addAccount(account);if (num > 0) {System.out.println("成功插入了" + num + "条数据!");} else {System.out.println("插入操作执行失败!");}}@Testpublic void updateAccountTest() {// 加载配置文件ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");// 获取AccountDao实例IAccountDao accountDao = (IAccountDao) applicationContext.getBean("accountDao");// 创建Account对象,并向Account对象中添加数据Account account = new Account();account.setId(1);account.setUsername("tom");account.setBalance(2000.00);// 执行updateAccount()方法,并获取返回结果int num = accountDao.updateAccount(account);if (num > 0) {System.out.println("成功修改了" + num + "条数据!");} else {System.out.println("修改操作执行失败!");}}@Testpublic void deleteAccountTest() {// 加载配置文件ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app.xml");// 获取AccountDao实例IAccountDao accountDao = (IAccountDao) applicationContext.getBean("accountDao");// 执行deleteAccount()方法,并获取返回结果int num = accountDao.deleteAccount(1);if (num > 0) {System.out.println("成功删除了" + num + "条数据!");} else {System.out.println("删除操作执行失败!");}}
}

Eclipsesrc/main/java使用@Test注解需要进行配置:右键项目-> properties -> Java Build Path -> Libraries -> Add Library -> JUint

添加完成后导入包import java.util.List;就能用了。

点击运行,我这里已经测试了多次了,结果可能跟你的不一样

从图中左侧可以看到两个方法成功了,两个方法失败了。失败的方法图标又个红色的叉号。

我们再创建一个JdbcTemplateTest类,测试下查询方法

package top.cairbin.test3;import java.util.List;import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;public class JdbcTemplateTest {@Testpublic void findAccountByIdTest() {// 加载配置文件ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app.xml");// 获取AccountDao实例IAccountDao accountDao = (IAccountDao) applicationContext.getBean("accountDao");// 执行findAccountById()方法Account account = accountDao.findAccountById(1);System.out.println(account);}@Testpublic void findAllAccountTest() {// 加载配置文件ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app.xml");// 获取AccountDao实例IAccountDao accountDao = (IAccountDao) applicationContext.getBean("accountDao");// 执行findAllAccount()方法,获取Account对象的集合List<Account> account = accountDao.findAllAccount();// 循环输出集合中的对象for (Account act : account) {System.out.println(act);}}
}

关于SpringTest

在Spring中使用Junit测试,每一个测试方法都会初始化Spring容器,导致容器被初始化多次,需要通过ctx.getBean()获取测试Bean。

SpringTest可以解决上面的问题,通过在类之上添加注解即可

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext.xml")

这里的Junit版本为4.12,需要修改pom.xml
此处不对该功能过多解释。

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

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

相关文章

的C++奇迹之旅:值和引用的本质效率与性能比较

文章目录 请添加图片描述 [TOC](文章目录) &#x1f4dd;引用# &#x1f320;引用概念**引用**不是新定义一个变量&#xff0c;而是给**已存在变量取了一个别名**&#xff0c;编译器不会为引用变量开辟内存空间&#xff0c;它和它引用的变量共用同一块内存空间。>定义&#…

ArcGIS 10.8中文版详细安装教程(附安装包)

ArcGIS 10.8中文版详细安装教程&#xff08;附安装包&#xff09; 关键词&#xff1a;ArcGIS 10.8中文版安装 1.概述 ArcGIS Desktop 10.8中文版是由ESRI公司开发的一款专业的地理信息系统&#xff0c;一套完整的桌面GIS软件套件&#xff0c;它包含ArcMap、ArcCatalog、ArcG…

C++——模板初阶

泛型编程 C语言中交换两个变量数据的内容一般是这样实现的 #include<iostream>using namespace std;void swap(int* x, int* y) {int tmp *x;*x *y;*y tmp; } int main() {int x 5;int y 7;swap(&x,&y);cout << "x" << x << …

最优算法100例之30-表示数值的字符串

专栏主页&#xff1a;计算机专业基础知识总结&#xff08;适用于期末复习考研刷题求职面试&#xff09;系列文章https://blog.csdn.net/seeker1994/category_12585732.html 题目描述 请实现一个函数用来判断字符串是否表示数值&#xff08;包括整数和小数&#xff09;。例如&a…

基于ArrayList实现简单洗牌

前言 在之前的那篇文章中&#xff0c;我们已经认识了顺序表—>http://t.csdnimg.cn/2I3fE 基于此&#xff0c;便好理解ArrayList和后面的洗牌游戏了。 什么是ArrayList? ArrayList底层是一段连续的空间&#xff0c;并且可以动态扩容&#xff0c;是一个动态类型的顺序表&…

Java方法的参数传递机制与递归总结

文章目录 1、方法的参数传递机制1.1、形参和实参1.2、 参数传递机制&#xff1a;值传递1.3、 举例1.4 练习 2、 递归(recursion)方法 1、方法的参数传递机制 1.1、形参和实参 若方法含有参数&#xff1a; 形参&#xff08;formal parameter&#xff09;&#xff1a;在定义方…

QT背景介绍

&#x1f40c;博主主页&#xff1a;&#x1f40c;​倔强的大蜗牛&#x1f40c;​ &#x1f4da;专栏分类&#xff1a;QT❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、QT背景 1.1什么是QT 1.2QT的发展历史 1.3什么是框架、库 1.4QT支持的平台 1.5QT的优点 1.6QT的…

BIM转Power BI数据集

在本博客中&#xff0c;我们将了解如何使用从 SSAS 表格、Power BI Desktop 或 Power BI 服务数据集中提取的 Model.bim 文件在本地或 PBI 服务上生成新数据集。 1、设置&#xff08;SSAS 表格和 PBI 服务通用&#xff09; 我建议你创建一个专门用于此任务的新 Python 环境&a…

old photo老照片图像复原数据集

来源 本来想拿DA-CLIP 训练一下old photo&#xff0c;训练代码没成功&#xff0c;毕设没时间就不研究了 github搜old photo复原论文原作者好像没开源训练数据集&#xff0c;所以用了这个SynOld 训练集500对测试集200对 但是readme写的很差&#xff0c;其他什么也没交代 展示…

Centos-Linux安装部署MySQL-8.0

linux搭建mysql 1.使用系统的root账户 2.切换到 /usr/local 目录下 3.下载mysql wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.31-linux-glibc2.12-x86_64.tar.xz也可以直接在官方下载最新版本 官方下载 选择linux 4.解压mysql tar xvJf mysql-8.0.21-l…

C易错注意之const修饰指针,含char类型计算,位段及相关经典易错例题

目录 前言 一&#xff1a;const修饰指针 1.const修饰变量 2.const 修饰指针 1.const int*p&m; 2. int* const p&m; 3. int const *p&m; 4. int const *const p&m; 5.总结 总之一句话为&#xff1a;左定值有定向 二&#xff1a;关于计算中char类型…

C语言:动态内存管理(二)

目录 前言 1.3 realloc​编辑 3、常见动态内存管理错误 3.1 对空指针的解引用操作 3.2 对动态开辟的空间进行越界访问 3.3 对非动态开辟内存使用free释放 3.4 使用free释放一块动态内存开辟的一部分 3.5 对同一块空间的多次释放 3.6 动态内存开辟之后忘记释放 总结 前…

杨氏矩阵(C语言)

文章目录 问题技术名词解释思路关键代码运行代码 问题 有一个数字矩阵&#xff0c;矩阵的每行从左到右是递增的&#xff0c;矩阵从上到下是递增的&#xff0c;请编写程序在这样的矩阵中查找某个数字是否存在。 要求&#xff1a;时间复杂度小于O(N); 技术名词解释 杨氏矩阵&…

自动化测试框架Robot Framework入门

什么是RF RF是一个基于 Python 的、可扩展的关键字驱动的自动化 验收测试框架、验收测试驱动开发 &#xff08;ATDD&#xff09;、 行为驱动开发 &#xff08;BDD&#xff09; 和机器人流程自动化 &#xff08;RPA&#xff09;。它 可用于分布式、异构环境&#xff0c;其中自动…

Spring Security——04,认证_校验

认证_校验 一、认证过滤器二、配置过滤器三、测试过滤器3.1 登录接口3.2 非登录接口3.3 结果 一键三连有没有捏~~ 一、认证过滤器 创建一个filter包&#xff0c;创建一个过滤器 代码如下&#xff1a; Component public class JwtAuthenticationTokenFilter extends OncePerR…

在集群中使用deepspeed如果端口被占用可以使用deepspeed参数更改

在集群中使用deepspeed如果端口被占用可以使用deepspeed参数更改 这一次G老师不好使了 在集群中使用deepspeed默认的端口号29500被占用&#xff0c;显示更改居然不起作用 G老师给的方法也不好使 #!/bin/bash MASTER_ADDRlocalhost MASTER_PORT29501 # 选择一个未被占用的端…

mysql 运算符 语句 字符集 校队集

mysql 运算符 使用select语句可以输出运算的结果 mysql标识符不区分大小写 算数运算符 1./除法 得到的结果是一个小数 %是整数,省略小数 2、除以0不会报错,得到的结果是 null 3.数宇和字符串做加法运算,并不会拼接 比较运算符 1.mysql里面的=是比较运算符,而不是赋值运算…

lora pingpang系统 4

1 深入了解LoRa技术原理 1.1 LoRa扩频通信原理 1.1.1 模拟无线通信&#xff1a; 模拟无线通信是一种使用模拟信号传输数据的通信方式。这种通信方式已经被数字无线通信所取代&#xff0c;因为数字通信具有更高的效率和可靠性。 天线&#xff1a;从空中接收到的无线电波转换成…

数据结构——图的概念,图的存储结构,图的遍历(dfs,bfs)

目录 1.图的定义和术语 2.案例引入 1.六度空间理论 3.图的类型定义 4.图的存储结构 1.邻接矩阵 1.无向图的邻接矩阵表示法 2.有向图的邻接矩阵表示法 3.网&#xff08;有权图&#xff09;的邻接矩阵表示法 代码示例&#xff1a; 2.采用邻接矩阵表示法创建无向图…

MySQL 表的增删改查

文章目录 一、什么是CRUD&#xff1f;二、新增&#xff08;Create&#xff09;1、单行数据 全列插入2、多行数据 指定列插入3、插入特殊类型 三、查询&#xff08;Retrieve&#xff09;1、全列查询2、指定列查询3、表达式查询4、指定别名5、去重6、排序7、条件查询基本查询&a…