jdbc访问数据库1

视频:单行数据查询与自定义RowMapper接口

18.访问数据库

Spring Boot 框架为 SQL 数据库提供了广泛的支持,既有用 JdbcTemplate 直接访问 JDBC,同时支持“object relational mapping”技术(如 HibernateMyBatis)。Spring Data 独立的项目提供对多种关系型和非关系型数据库的 访问支持。比如 MySQL, Oracle , MongoDB , Redis, R2DBC,Apache Solr,Elasticsearch…

Spring Boot 也支持嵌入式数据库比如 H2, HSQL, and Derby。这些数据库只需要提供 jar 包就能在内存中维护 数据。我们这章访问关系型数据库。

DataSource

通常项目中使用 MySQL,Oracle,PostgreSQL 等大型关系数据库。Java 中的 jdbc 技术支持了多种关系型数据库 的访问。在代码中访问数据库,我们需要知道数据库程序所在的 ip,端口,访问数据库的用户名和密码以及数据 库的类型信息。以上信息用来初始化数据源,数据源也就是 DataSource。数据源表示数据的来源,从某个 ip 上的 数据库能够获取数据。javax.sql.DataSource 接口表示数据源,提供了标准的方法获取与数据库绑定的连接对象 (Connection)。 javax.sql.Connection 是连接对象,在 Connection 上能够从程序代码发送查询命令,更新数据的语句给数据库; 同时从 Connection 获取命令的执行结果。

image-20250329212159829

DataSource 在 application 配置文件中以 spring.datasource.*作为配置项。类似下面的代码:

spring.datasource.url=jdbc:mysql://localhost/mydb

spring.datasource.username=dbuser

spring.datasource.password=dbpass

DataSourceProperties.java 是数据源的配置类,更多配置参考这个类的属性。

@ConfigurationProperties(prefix = “spring.datasource”)

public class DataSourceProperties implements BeanClassLoaderAware,

InitializingBean {

}

  • Spring Boot 能够从 spring.datasource.url 推断所使用的数据驱动类,如果需要特殊指定请设置 spring.datasource.driver-class-name 为驱动类的全限定名称。Spring Boot 支持多种数据库连接池,优先使用 HikariCP,其次是 Tomcat pooling,再次是 Commons DBCP2, 如果以上都没有,最后会使用 Oracle UCP 连接池。当项目中 starter 依赖了 spring-boot-starter-jdbc 或者 spring-boot-starter-data-jpa 默认添加 HikariCP 连接池依赖,也就是默认使用 HikariCP 连接池。

JdbcTemplate

使用 JdbcTemplate 我们提供自定义 SQL, Spring 执行这些 SQL 得到记录结果集。JdbcTemplate 和 NamedParameterJdbcTemplate 类是自动配置的,您可以@Autowire 注入到自己的 Bean 中。开箱即用。 JdbcTemplate 执行完整的 SQL 语句,我们将 SQL 语句拼接好,交给 JdbcTemplate 执行,JdbcTemplate 底层 就是使用 JDBC 执行 SQL 语句。是 JDBC 的封装类而已。

NamedParameterJdbcTemplate 可以在 SQL 语句部分使用“:命名参数”作为占位符, 对参数命名,可读性更 好。NamedParameterJdbcTemplate 包装了 JdbcTemplate 对象,“:命名参数”解析后,交给 JdbcTemplate 执行 SQL

语句。

JdbcTemplateAutoConfiguration 自动配置了 JdbcTemplate 对象,交给 JdbcTemplateConfiguration 创建了 JdbcTemplate 对象。并对 JdbcTemplate 做了简单的初始设置(QueryTimeout,maxRows 等)。

访问数据库先准备数据库的 script。SpringBoot 能够自动执行 DDL,DML 脚本。两个脚本文件名称默认是 schema.sql 和 data.sql。脚本文件在类路径中自动加载。

always:总是执行数据库初始化脚本

never:禁用数据库初始化

创建数据库

image-20250329213348201

image-20250329214906946

image-20250329215143166

image-20250329215203698

image-20250329215228835

image-20250329215806682

/*
 Navicat Premium Data Transfer

 Source Server         : 本地数据库
 Source Server Type    : MySQL
 Source Server Version : 80026 (8.0.26)
 Source Host           : localhost:3306
 Source Schema         : school

 Target Server Type    : MySQL
 Target Server Version : 80026 (8.0.26)
 File Encoding         : 65001

 Date: 29/03/2025 21:58:40
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`  (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `stuid` char(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `major` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `stuid_unique`(`stuid` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES (1, '烟雨1', '1001', '计算机应用技术');
INSERT INTO `student` VALUES (2, '烟雨2', '1002', '软件技术');

SET FOREIGN_KEY_CHECKS = 1;

创建项目

image-20250329213708576

  • 安装 lombok 插件

image-20250329213751512

image-20250329214403563

image-20250329214422224

image-20250329214612148

schema.sql

DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`  (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `stuid` char(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `major` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `stuid_unique`(`stuid` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

data.sql

INSERT INTO `student` VALUES (1, '烟雨1', '1001', '计算机应用技术');
INSERT INTO `student` VALUES (2, '烟雨2', '1002', '软件技术');

配置数据源

image-20250329221115422

  • application.properties
#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#spring.datasource.url=jdbc:mysql://localhost:3306/blog?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false
#spring.datasource.username=root
#spring.datasource.password=123456
#配置数据源
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/school?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=yanyu666
#执行数据库脚本   建表和插入数据
#执行数据库脚本   建表和插入数据
#spring.sql.init.mode=always   脚本执行成功后,修改为  never  避免每次运行项目都会##执行脚本覆盖数据
spring.sql.init.mode=always

image-20250329223241067

image-20250329223310796

lombok

@Data

功能:组合了 @Getter@Setter@ToString@EqualsAndHashCode@NoArgsConstructor

@NoArgsConstructor@AllArgsConstructor@RequiredArgsConstructor

功能:自动生成构造函数。

  • @NoArgsConstructor:生成无参构造函数。

  • @AllArgsConstructor:生成包含所有字段的构造函数。

  • @RequiredArgsConstructor:生成包含所有 final 字段和 @NonNull 字段的构造函数。

  • @Getter@Setter

    功能:自动生成类的 getter 和 setter 方法。

    • @Getter:为类的字段生成 getter 方法。
    • @Setter:为类的字段生成 setter 方法

lombok 生效

  • 安装Lombok插件

  • 设置开启

  • 依赖添加Lombok

JdbcTemplate 访问 MySQL

项目中依赖了 spring-jdbc 6.0.3,JdbcTemplate 对象会自动创建好。把 JdbcTemplate 对象注入给你的 Bean, 再调用 JdbcTemplate 的方法执行查询,更新,删除的 SQL。

JdbcTemplate 上手快,功能非常强大。提供了丰富、实用的方法,归纳起来主要有以下几种类型的方法:

(1)execute 方法:可以用于执行任何 SQL 语句,常用来执行 DDL 语句。

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

3)query 和 queryForXXX 方法:用于执行查询相关的语句。

4)call 方法:用于执行数据库存储过程和函数相关的语句

查询

image-20250329225615342

#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#spring.datasource.url=jdbc:mysql://localhost:3306/blog?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false
#spring.datasource.username=root
#spring.datasource.password=123456
#配置数据源
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/school?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=yanyu666
#执行数据库脚本   建表和插入数据
#spring.sql.init.mode=always   脚本执行成功后,修改为  never  避免每次运行项目都会执行脚本覆盖数据
spring.sql.init.mode=never
package com.yanyu.jdbc1.model;

import lombok.Data;

/**
 * @Author yanyu666_508200729@qq.com
 * @Date 2025/3/29 22:45
 * @description:
 */
@Data
/*功能:组合了 @Getter、@Setter、@ToString、@EqualsAndHashCode 和 @NoArgsConstructor。
* */
public class UserPO {

    private Integer id;
    private String name;
    private String password;
    private String major;

}

package com.yanyu.jdbc1;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;

@SpringBootTest
class Jdbc1ApplicationTests {

	@Test
	void contextLoads() {
	}
	//注入JdbcTemplate
	@Autowired
	JdbcTemplate jdbcTemplate;
	@Test
	void test1(){
		String sql = "select count(*) as count from student";
		Long l = jdbcTemplate.queryForObject(sql, Long.class);
		System.out.println("学生总数:" + l);// 2

	}

}

查询单行数据

image-20250329230347085

image-20250329230810595

image-20250329225615342

#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#spring.datasource.url=jdbc:mysql://localhost:3306/blog?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false
#spring.datasource.username=root
#spring.datasource.password=123456
#配置数据源
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/school?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=yanyu666
#执行数据库脚本   建表和插入数据
#spring.sql.init.mode=always   脚本执行成功后,修改为  never  避免每次运行项目都会执行脚本覆盖数据
spring.sql.init.mode=never
package com.yanyu.jdbc1.model;

import lombok.Data;

/**
 * @Author yanyu666_508200729@qq.com
 * @Date 2025/3/29 22:45
 * @description:
 */
@Data
/*功能:组合了 @Getter、@Setter、@ToString、@EqualsAndHashCode 和 @NoArgsConstructor。
* */
public class UserPO {

    private Integer id;
    private String name;
    private String password;
    private String major;

}

image-20250329231037200

表名写错

//	字段 与  UserPO  进行对应的映射
//注入JdbcTemplate
	@Autowired
	JdbcTemplate jdbcTemplate;	
@Test
	void test2(){
		String sql = "select * from student where id = ?";

		UserPO userPO = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(UserPO.class), 2);
		System.out.println(userPO);


	}

有时 @Data lombok 不好使,不好使的情况下,自己写 bean规范

image-20250329233220726

自定义RowMapper

在你的代码中,-> 用于定义一个 RowMapper,这是一个函数式接口,用于将 ResultSet 的一行数据映射为一个 Java 对象。

image-20250330001956049

//注入JdbcTemplate
	@Autowired
	JdbcTemplate jdbcTemplate;
void test4(){
		String sql = "select * from student where id =1";
		/*
		* public interface RowMapper<T> {
    @Nullable
    T mapRow(ResultSet rs, int rowNum) throws SQLException;
}
* RowMapper  接口只有一个  方法,所以可以使用  lambda
		* */

		UserPO userPO = jdbcTemplate.queryForObject(sql,(rs,rows)->{
			var id = rs.getInt("id");
			var name = rs.getString("name");
			var stuid = rs.getString("stuid");
			var major = rs.getString("major");
			return new UserPO(id,name,stuid,major);
		});
		System.out.println(userPO);
	}

解释

  • (rs, rownum) ->:这是一个 lambda 表达式,表示 RowMapper 接口的实现。
    • rsResultSet 对象,表示查询结果。
    • rownum 是当前行的行号(从 1 开始),在这个例子中没有使用。
  • new ArticlePO(...):这是 lambda 表达式的主体,表示如何将 ResultSet 中的一行数据映射为一个 ArticlePO 对象。

image-20250330011809220

查询多行记录

视频:多行数据查询

//注入JdbcTemplate
	@Autowired
	JdbcTemplate jdbcTemplate;
//	多行记录
	@Test
	void test6(){
		String sql = "select * from student order by id";
		List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
//		使用  forech  和  lambda
		maps.forEach(el->{
			el.forEach((Field,value)->{
				System.out.println("字段名字" + Field + ",列值" + value);
			});
		});
	}

mg-eZuSdlon-1744258371805)]

查询多行记录

//注入JdbcTemplate
	@Autowired
	JdbcTemplate jdbcTemplate;
//	多行记录
	@Test
	void test6(){
		String sql = "select * from student order by id";
		List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
//		使用  forech  和  lambda
		maps.forEach(el->{
			el.forEach((Field,value)->{
				System.out.println("字段名字" + Field + ",列值" + value);
			});
		});
	}

image-20250330011923115

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@yanyu666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值