74、SpringBoot 整合 Spring Data JDBC

总结:用起来跟 Spring Data JPA 差不多

什么是 JdbcTemplate?(Template译为模板)
Spring 框架对 JDBC 进行封装,使用 JdbcTemplate 方便实现对数据库操作

★ Spring Data JDBC

既不需要JPA、Hibernate这种ORM框架,但Spring Data还是提供了面向对象的封装。——它相当于是一种轻量化的持久化技术,用起来比Spring JDBC更方便,但又不像Spring Data JPA那么需要大量注解、复杂它相当于是一个折中。

★ Spring Data JDBC的功能

大致包括如下几方面功能:
- DAO接口只需继承CrudRepository或PagingAndSortingRepository,Spring Data JDBC能为DAO组件生成实现类、类似于Spring Data JPA。
- Spring Data JDBC支持方法名关键字查询、类似于Spring Data JPA
- Spring Data JDBC支持用@Query定义查询语句。
- Spring Data JDBC同样支持DAO组件添加自定义的查询方法——————通过添加额外的父接口,并为额外的该接口提供实现类,Spring Data JDBC就能该实现类中的方法“移植”到DAO组件中。
- 一般不支持样本查询;也不支持Specification查询。

★ Spring Data JDBC VS Spring Data JPA

Spring Data JDBC相当于“轻量化”的Spring Data JPA。
Spring Data JDBC的功能不如Spring Data JPA强大(毕竟它底层没有ORM框架的加持)。
Spring Data JDBC也不需要处理复杂的ORM映射、实体对象的生命周期管理等,
因此Spring Data JDBC用起来更简单。 
——Spring Data JDBC有点类似MyBatis

★ Spring Data JDBC映射规则

Spring Data JDBC默认的处理方式是“约定优于配置”的同名映射:- 程序操作User对象,Spring Data JDBC对应于操作user表。
- 对于id数据列,自动被映射到对象的id属性。▲Spring Data JDBC的注解:- @Table:映射自定义的表名。非JPA注解
- @Column:映射自定义的列名,非JPA注解
- @Id:修饰标识属性,非JPA注解
- @PersistenceConstructor:修饰主构造器。当你的映射类中有多个构造器时,你希望Spring Data JDBC用哪个构造器来创建对象,就用该注解来修饰该构造器。

★ Spring Data JDBC操作数据库方法:

A. 全自动:方法名关键字查询。B. 半自动:@Query指定查询语句。C. 全手动:自己定义查询方法,即可用DataSource,也用JdbcTemplate。

★ Spring Data JDBC的编程步骤:

(1)定义映射类,为Java类添加@Table、@Column、@Id和 @PersistenceConstructor(2)让DAO接口继承CrudRepository或PagingAndSortingRepository。(3)在DAO接口中定义方法名关键字查询、@Query查询、完全自定义查询(需要额外的接口和实现类)

代码演示

其实跟 JPA 差不多

User 类

在这里插入图片描述

UserDao接口,

根据方法名关键字查询---------全自动,不用自己写sql的
也有通过注解 @Query 进行查询的 —>自己定义查询语句-----半自动,可以自己写sql语句
在这里插入图片描述

也可以自定义Dao接口,用来自己写sql和封装数据
在这里插入图片描述

自定义接口和实现类,来实现数据的查询,
一个基于 DataSource , 一个基于 jdbcTemplate
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

UserDaoTest 测试

测试类
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

application.properties

在这里插入图片描述

pom.xml

一个是 spring data jdbc 的依赖 , 一个是 mysql 的依赖,
创建项目的时候这个 mysql 的依赖老是不完整,所以要记录下
在这里插入图片描述

完整代码

User

package cn.ljh.app.domain;import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;/*** author JH*/@Data
//此处不能添加JPA注解,因为此项目没有用到 JPA
@Table("user_inf")
public class User
{@Column(value = "user_id")@Idprivate Integer id;private String name;private String password;private int age;/*** @PersistenceConstructor*  修饰主构造器。当你的映射类中有多个构造器时,*  你希望Spring Data JDBC用哪个构造器来创建对象,就用该注解来修饰该构造器*/@PersistenceConstructorpublic User(){}public User(Integer id, String name, String password, int age){this.id = id;this.name = name;this.password = password;this.age = age;}@Overridepublic String toString(){return "User{" +"id=" + id +", name='" + name + '\'' +", password='" + password + '\'' +", age=" + age +'}';}
}

UserDao

package cn.ljh.app.dao;import cn.ljh.app.domain.User;
import org.springframework.data.jdbc.repository.query.Modifying;
import org.springframework.data.jdbc.repository.query.Query;
import org.springframework.data.repository.CrudRepository;import java.util.List;public interface UserDao extends CrudRepository<User,Integer>,CustomUserDao
{// 继承 CrudRepository 接口后,就已经有通用的 CRUD 操作,无需自己来书写这些方法//方法名关键字查询---------全自动//根据名字模糊查询List<User> findByNameLike(String namePattern);//根据年龄大小进行范围查询List<User> findByAgeGreaterThan(int startAge);List<User> findByAgeLessThan(int age);//根据年龄区间进行范围查询List<User> findByAgeBetween(int startAge , int endAge);//@Query 查询 --->自己定义查询语句-----半自动//rowMapperClass 或 rowMapperRef 是用来做自定义映射,查询出来的User对象的数据,映射到Student对象的属性上面去都可以,因为是自定义的。//根据密码模糊查询@Query("select * from user_inf where password like :passwordPattern")List<User> findBySql(String passwordPattern);//根据年龄范围修改名字@Query("update user_inf set name = :name where age between :startAge and :endAge")@Modifying //更改数据库数据需要用到这个注解int updateNameByAge(String name , int startAge , int endAge);}

CustomUserDao

package cn.ljh.app.dao;import cn.ljh.app.domain.User;import java.util.List;/*** author JH*/
//自己定义的接口,用来实现全手动的查询
public interface CustomUserDao
{//通过名字进行模糊查询,使用 dataSourceList<User> customQueryUsingConnection(String namePattern);//通过名字进行模糊查询,使用 jdbcTemplateList<User> customQueryUsingTemplate(String namePattern);
}

CustomUserDaoImpl

package cn.ljh.app.dao.impl;import cn.ljh.app.dao.CustomUserDao;
import cn.ljh.app.domain.User;
import lombok.SneakyThrows;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;import javax.sql.DataSource;
import java.sql.Array;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;/*** author JH*/
public class CustomUserDaoImpl implements CustomUserDao
{private DataSource dataSource;private JdbcTemplate jdbcTemplate;//通过有参构造器进行依赖注入public CustomUserDaoImpl(DataSource dataSource, JdbcTemplate jdbcTemplate){this.dataSource = dataSource;this.jdbcTemplate = jdbcTemplate;}@SneakyThrows@Overridepublic List<User> customQueryUsingConnection(String namePattern){//创建数据库连接Connection connection = this.dataSource.getConnection();//创建 PreparedStatement 预处理语句PreparedStatement pstmt = connection.prepareStatement("select * from user_inf where name like ?");pstmt.setString(1, namePattern);//执行查询ResultSet rs = pstmt.executeQuery();List<User> userList = new ArrayList<>();//遍历结果集,封装对象while (rs.next()){userList.add(new User(rs.getInt("user_id"),rs.getString("name"),rs.getString("password"),rs.getInt("age")));}return userList;}@Overridepublic List<User> customQueryUsingTemplate(String namePattern){//直接执行查询List<User> userList = this.jdbcTemplate.query("select user_id as id,name ,password,age from user_inf where name like ?",//把查询的结果封装起来new BeanPropertyRowMapper<>(User.class),namePattern);return userList;}
}

UserDaoTest

package cn.ljh.app;import cn.ljh.app.dao.UserDao;
import cn.ljh.app.domain.User;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.jdbc.repository.query.Modifying;
import org.springframework.data.jdbc.repository.query.Query;
import org.springframework.test.annotation.Rollback;
import org.springframework.transaction.annotation.Transactional;import java.util.List;
import java.util.Optional;/*** author JH*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class UserDaoTest
{@Autowiredprivate UserDao userDao;// 继承 CrudRepository 接口后,就已经有通用的 CRUD 操作,无需自己来书写这些方法==============//添加user对象@ParameterizedTest@CsvSource({"aa,xxx,2", "bb,xxx,3"})public void testSave(String name, String password, int age){//没有id,save就是添加User user = userDao.save(new User(null, name, password, age));System.err.println(user);}//根据id修改对象@ParameterizedTest@CsvSource({"13,aaa,xxxx,22"})public void testUpdate(Integer id, String name, String password, int age){//有id,save就是修改User user = userDao.save(new User(id, name, password, age));System.err.println(user);}//根据id删除用户对象@ParameterizedTest@ValueSource(ints = {14})public void testDelete(Integer id){userDao.deleteById(id);}//根据id查询对象@ParameterizedTest@ValueSource(ints = {1})public void testFindById(Integer id){Optional<User> user = userDao.findById(id);}//方法名关键字查询---------全自动=====================================================//根据名字模糊查询@ParameterizedTest@ValueSource(strings = {"孙%", "%精"})public void testFindByNameLike(String namePattern){List<User> users = userDao.findByNameLike(namePattern);users.forEach(System.err::println);}//根据年龄大小进行范围查询@ParameterizedTest@ValueSource(ints = {500, 10})public void testFindByAgeGreaterThan(int startAge){List<User> users = userDao.findByAgeGreaterThan(startAge);users.forEach(System.err::println);}//根据年龄大小进行范围查询@ParameterizedTest@ValueSource(ints = {20})public void testFindByAgeLessThan(int age){List<User> users = userDao.findByAgeLessThan(age);users.forEach(System.err::println);}//根据年龄区间进行范围查询@ParameterizedTest@CsvSource({"15,20", "500,1000"})public void testFindByAgeBetween(int startAge, int endAge){List<User> users = userDao.findByAgeBetween(startAge, endAge);users.forEach(System.err::println);}//@Query 查询 --->自己定义查询语句-----半自动=====================================================================//rowMapperClass 或 rowMapperRef 是用来做自定义映射,查询出来的User对象的数据,映射到Student对象的属性上面去都可以,因为是自定义的。//根据密码模糊查询@ParameterizedTest@ValueSource(strings = {"niu%", "%3"})public void testFindBySql(String passwordPattern){List<User> users = userDao.findBySql(passwordPattern);users.forEach(System.err::println);}//根据年龄范围修改名字@ParameterizedTest@CsvSource({"牛魔王aa,800,1000"})@Transactional@Rollback(false)public void testUpdateNameByAge(String name, int startAge, int endAge){int i = userDao.updateNameByAge(name, startAge, endAge);}//自己定义的接口,用来实现全手动的查询===================================================================================//通过名字进行模糊查询,使用 dataSource@ParameterizedTest@ValueSource(strings = {"孙%"})public void testCustomQueryUsingConnection(String namePattern){List<User> users = userDao.customQueryUsingConnection(namePattern);users.forEach(System.err::println);}//通过名字进行模糊查询,使用 jdbcTemplate@ParameterizedTest@ValueSource(strings = {"孙%"})public void testCustomQueryUsingTemplate(String namePattern){List<User> users = userDao.customQueryUsingTemplate(namePattern);users.forEach(System.err::println);}
}

application.properties

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.5</version></parent><groupId>cn.ljh</groupId><artifactId>Spring_Data_JDBC</artifactId><version>1.0.0</version><name>Spring_Data_JDBC</name><properties><java.version>11</java.version></properties><dependencies><!-- 导入 spring data jdbc --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jdbc</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>

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

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

相关文章

离线部署 python 3.x 版本

文章目录 离线部署 python 3.x 版本1. 下载版本2. 上传到服务器3. 解压并安装4. 新建软连信息5. 注意事项 离线部署 python 3.x 版本 1. 下载版本 python 各版本下载地址 本次使用版本 Python-3.7.0a2.tgz # linux 可使用 wget 下载之后上传到所需服务器 wget https://www.py…

gma 2 成书计划

随着 gma 2 整体构建完成。下一步计划针对库内所有功能完成一个用户指南&#xff08;非网站&#xff09;。 封皮 主要章节 章节完成度相关链接第 1 章 GMA 概述已完成第 2 章 地理空间数据操作已完成第 3 章 坐标参考系统已完成第 4 章 地理空间制图已完成第 5 章 数学运算模…

3288S Android11 适配红外遥控功能(超详细)

目录 一、rk3288平台红外遥控介绍二、原理图分析三、配置设备树并使能红外遥控功能四、打开红外打印功能&#xff0c;查看红外遥控的用户码和键值五、将查看到的红外遥控用户码和键值添加到设备树和.kl文件六、Android红外遥控.kl文件映射知识和使用添加新的.kl文件七、补充&am…

Unity中关于多线程的一些事

一.线程中不允许调用unity组件api 解决方法&#xff1a;可以使用bool值变化并且在update中监测bool值变化来调用关于unity组件的API. 二.打印并且将信息输出到list列表中 多线程可能同时输出多条信息。输出字符串可以放入Queue队列中。队列可以被多线程插入。 三.启用socke…

Python 网络爬取的时候使用那种框架

尽管现代的网站多采取前后端分离的方式进行开发了&#xff0c;但是对直接 API 的调用我们通常会有 token 的限制和可以调用频率的限制。 因此&#xff0c;在一些特定的网站上&#xff0c;我们可能还是需要使用网络爬虫的方式获得已经返回的 JSON 数据结构&#xff0c;甚至是处理…

【计算机毕业设计】基于SpringBoot+Vue记帐理财系统的设计与实现

博主主页&#xff1a;一季春秋博主简介&#xff1a;专注Java技术领域和毕业设计项目实战、Java、微信小程序、安卓等技术开发&#xff0c;远程调试部署、代码讲解、文档指导、ppt制作等技术指导。主要内容&#xff1a;毕业设计(Java项目、小程序、安卓等)、简历模板、学习资料、…

C语言 coding style

头文件 The #define Guard #define的保护文件的唯一性&#xff0c;防止被多重包含 格式 : <PROJECT>_< FILE>_H_ PROJECT : XS FILE : MV_CTR 头文件的包含顺序 C System FilesOther LibrariesUser LibraryConditional include 作用域 局部变量 -变量定义时需要…

go语言unsafe.Pointer与uintptr

以下内容来源go语言圣经 1、unsafe.Pointer&#xff0c;相当于c语言中的void *类型的指针&#xff0c;如果需要运算需要转成uintptr类型的指针 2. uintptr uintptr是一个无符号的整型&#xff0c;它可以保存一个指针地址。 它可以进行指针运算。 uintptr无法持有对象, GC不把…

Kubernetes的容器批量调度引擎 Volcano

一个用于高性能工作负载场景下基于Kubernetes的容器批量调度引擎 Volcano是在Kubernetes上运行高性能工作负载的容器批量计算引擎。 它提供了Kubernetes目前缺少的一套机制&#xff0c;这些机制通常是许多高性能 工作负载所必需的&#xff0c;包括&#xff1a; - 机器学习/深度…

三.vue2路由知识全总结

Vue Devtools&#xff1a;插件安装&#xff0c;展示模块中的数据 vue-router 应用场景&#xff1a;Vue Router 是 Vue.js 的官方路由。它与 Vue.js 核心深度集成&#xff0c;让用 Vue.js 构建单页应用变得轻而易举。 嵌套的路由/视图表模块化的、基于组件的路由配置路由参数、…

一拖三快充线(USB-C转三充)的解决方案--LDR6020P

DR6020P 是带有 3 组 6 路 DRP USB-C 及 PD 通信协议处理模块和 USB2.0 Device 功能的 16 位 RISC MCU&#xff0c;内置 8K16 位 MTP 程序存储器&#xff08;可烧录 1000 次&#xff09;&#xff0c;512 字节的数据存储器&#xff08;SRAM&#xff09;。内置 LDO 5V 输出&#…

通讯网关软件011——利用CommGate X2ODBC实现DDE数据转入ODBC

本文介绍利用CommGate X2ODBC实将DDE数据源中的数据转入到ODBC数据源。CommGate X2ODBC是宁波科安网信开发的网关软件&#xff0c;软件可以登录到网信智汇(http://wangxinzhihui.com)下载。 【案例】如下图所示&#xff0c;将DDE数据源&#xff08;如Excel&#xff09;的数据写…

postgresql-触发器

postgresql-触发器 触发器概述创建触发器管理触发器删除触发器事件触发器创建事件触发器修改触发器删除事件触发器 触发器概述 PostgreSQL 触发器&#xff08;trigger&#xff09;是一种特殊的函数&#xff0c;当某个数据变更事件&#xff08;INSERT、UPDATE、 DELETE 或者 TR…

【3dmax】怎么将点删除而面保留

在编辑多边形模式下&#xff0c;选择点模式&#xff0c;选择要删除的点&#xff0c;在下拉面板中找到【移除】

Mysql——压缩包方式安装教程

一.Mysql压缩包下载方式 zip版&#xff08;5.7及8.0&#xff09;的下载需到官方网站下载&#xff0c;不同版本对应能安装在不同的操作系统下&#xff0c;本次介绍的是mysql-8.0.30-winx64在win10下的安装方式。 下载网址&#xff1a;MySQL :: Download MySQL Community Server …

描述符——配置描述符

描述符定义 描述符实现 /*** brief USB configuration descriptor.*/ typedef struct __attribute__ ((packed)) {uint8_t bLength ; /**< Size of this descriptor in bytes. */uint8_t bDescriptorType ; /**< CONFIGURATION Descriptor Type. */ui…

基于同名面片的TLS测站点云配准

1、原理介绍 2、代码介绍 基于C++编写的程序代码如下,其依赖eigen矩阵运算库,在创建工程时包含库目录中使用了相对路径,因此其下载下来直接可以运行,不用单独在设置环境,非常方便。

云原生微服务治理:服务发现、负载均衡与熔断策略

文章目录 什么是云原生微服务治理&#xff1f;服务发现客户端发现服务器端发现 负载均衡Ribbon - 基于客户端的负载均衡Nginx - 基于服务器的负载均衡 熔断策略Hystrix - 熔断器模式 结论 &#x1f389;欢迎来到云计算技术应用专栏~云原生微服务治理&#xff1a;服务发现、负载…

Spring Cloud Gateway快速入门(二)——断言工厂

文章目录 前言1. 什么是Gateway断言工厂2. 为什么要使用断言2.1. 调试和开发&#xff1a;2.2. 防御性编程&#xff1a;2.3. 文档和可读性&#xff1a;2.4. 测试&#xff1a; 3. 常用的Gateway断言工厂3.1 Path断言工厂3.2 Method断言工厂3.3 Header断言工厂3.4 时间断言工厂 4.…

北邮22级信通院数电:Verilog-FPGA(1)实验一“跑通第一个例程” 过程中遇到的常见问题与解决方案汇总(持续更新中)

北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章&#xff0c;请访问专栏&#xff1a; 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客 目录 问题一&#xff1a;Verilog代码没有跑通 报…