73、SpringBoot 直接整合 JDBC

news2024/11/26 16:36:48

★ Spring Boot可直接整合JDBC来操作数据库

——很少这么干,这么干就意味着使用最原始的方式来操作数据库。

对于对于极小的项目,直接整合JDBC无需添加JPA、Hibernate等ORM框架。

★ JdbcTemplate

为项目添加spring-boot-starter-jdbc.jar依赖(注意没有data)。
 ——这个Starter几乎是所有数据库访问技术都需要依赖的,因为它是最基础的JDBC依赖

Spring Boot会在容器中自动配置一个JdbcTemplate,并可将该它注入其他的项目组件——

该项目组件就可调用它的方法来操作数据库了。

RowMapper负责将一行记录映射成对象。

▲ JdbcTemplate方法的总结:

JdbcTemplate还是比较好用的,大部分CRUD操作只要一个方法即可搞定。

对这些方法进行归纳,不难发现它们的设计很统一:
- update()用于执行DML语句(insert、update、delete)、query[ForXxx]()用于执行SELECT语句,
  execute()用于执行DDL语句(create、alter、drop)。
- queryForObject:只能返回单行结果集。
- queryForOList:可返回多行结果集。
- query:可返回多行、多列结果集。
- 如果传入了RowMapper参数,才能返回多列结果集;否则只能返回单列结果集。
- 方法需要传入Object... args参数,则意味着使用PreparedStatement执行SELECT语句,此时就需要为占位符传入参数
  否则使用普通Statement执行SELECT语句。

- 如果查询方法只指定requiredType参数,则意味着查询结果集只能返回单列数据;
  如果查询方法指定了rowMapper参数,查询结果可以返回多列数据,
  而rowMapper则负责将每行数据转为目标对象。

▲ BeanPropertyRowMapper

BeanPropertyRowMapper是Spring提供的RowMapper实现类

BeanPropertyRowMapper有一个特点:它要求查询结果集的列名与被映射对象的属性名一一对应

可通过SELECT语句对查询的数据列进行了重命名,从而让结果集的列名与被映射对象的属性名保持对应。


【请记住:】如果使用JDBC来实现DAO组件,必须由开发者自己提供实现类。

代码演示

创建项目
在这里插入图片描述

User 对象

在这里插入图片描述

userDao

在这里插入图片描述

UserDaoImpl

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

解释这个rowMapper
在这里插入图片描述

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

添加这个依赖,springboot就会帮我们创建一个datasource的数据源的连接,并且会在容器中部署一个叫做 JdbcTemplate,所以userDao组件才有得依赖注入这个jdbcTemplate对象
在这里插入图片描述

测试结果:

根据id查找 User 对象
在这里插入图片描述

添加对象
在这里插入图片描述

根据id删除对象
在这里插入图片描述

根据id修改对象
在这里插入图片描述

根据名字进行模糊查询
在这里插入图片描述

根据年龄进行查询
在这里插入图片描述

完整代码

UserDaoImpl

package cn.ljh.app.dao.impl;

import cn.ljh.app.dao.UserDao;
import cn.ljh.app.domain.User;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;


//@Repository 注解里面有贴 @Component 注解,就是专门用于标注 Dao 组件的
//就是 test 那里要用Autowired注入这个UserDao,那么就需要在这里添加这个@Repository注解
//就是为了让容器中有这个 userDao 组件
@Repository
public class UserDaoImpl implements UserDao
{
    //此处就需要使用 jdbcTemplate 来访问数据库了
    private JdbcTemplate jdbcTemplate;

    //通过参数构造器进行依赖注入
    public UserDaoImpl(JdbcTemplate jdbcTemplate)
    {
        this.jdbcTemplate = jdbcTemplate;
    }

    final RowMapper<User> rowMapper = new RowMapper<User>()
    {
        //该方法就负责将一行的结果集映射成指定的对象
        @Override
        public User mapRow(ResultSet resultSet, int i) throws SQLException
        {
            return new User(
                    resultSet.getInt("user_id"),
                    resultSet.getString("name"),
                    resultSet.getString("password"),
                    resultSet.getInt("age"));
        }
    };

    //根据id查询对象
    @Override
    public User findById(Integer id)
    {
        //rowMapper 负责将一行结果集转成对象
        User user = jdbcTemplate.queryForObject("select * from user_inf where user_id = ?", rowMapper, id);
        return user;
    }

    //添加对象
    @Override
    public int save(User user)
    {
        int update = jdbcTemplate.update("insert into user_inf values(null,?,?,?)",
                user.getName(), user.getPassword(), user.getAge());
        return update;
    }

    //根据id删除对象
    @Override
    public int removeById(Integer id)
    {
        int update = jdbcTemplate.update("delete from user_inf where user_id = ?", id);
        return update;
    }

    //修改
    @Override
    public int update(User user)
    {
        int update = jdbcTemplate.update("update user_inf set name = ? ,password = ? , age = ? where user_id = ?",
                user.getName(), user.getPassword(), user.getAge(), user.getId());
        return update;
    }

    //根据名称模糊查询
    @Override
    public List<User> findByNamePattern(String namePattern)
    {
        List<User> query = jdbcTemplate.query("select * from user_inf where name like ? ", rowMapper, namePattern);
        return query;
    }

    //根据年龄查询
    @Override
    public List<User> findByAgeGt(int startage)
    {
        //因为 User 对象里面的id,在数据库表里面的列名 是 user_id ,如果使用 user_id as id 查询,给个别名,
        //那么查出来的数据的列名id,就和User对象的属性id 对应上了,就是id和id名字对应上了,
        //之前查出来的数据显示的是user_id ,现在给个别名变成id,就不需要再使用这个 rowMapper 来封装了
        List<User> query = jdbcTemplate.query("select user_id as id , name , password ,age from user_inf where age > ?",
                //把结果集映射成 User 类型
                new BeanPropertyRowMapper(User.class),
                startage);
        return query;
    }
}

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 java.util.List;

/**
 * author JH
 */
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class UserDaoTest
{
    @Autowired
    private UserDao userDao;
    
    //根据id查找 User 对象
    @ParameterizedTest
    @ValueSource(ints = {2, 3, 5})
    public void testFindById(Integer id)
    {
        User user = userDao.findById(id);
        System.err.println(user);
    }
    
    //添加对象
    @ParameterizedTest
    @CsvSource({"ljh,123,25", "jh,12,26"})
    public void testSave(String name, String password, int age)
    {
        User user = new User(null, name, password, age);
        int save = userDao.save(user);
    }

    //删除
    @ParameterizedTest
    @ValueSource(ints = {11, 12})
    public void testRemove(Integer id)
    {
        int i = userDao.removeById(id);
    }
    
    //修改
    @ParameterizedTest
    @CsvSource({"1,孙悟空ZZZ,54321,505"})
    public void testUpdate(Integer id,String name, String password, int age)
    {
        int update = userDao.update(new User(id, name, password, age));
    }

    //根据名字进行模糊查询
    @ParameterizedTest
    @ValueSource(strings = {"孙%","%精"})
    public void testFindByNamePattern(String namePattern)
    {
        List<User> users = userDao.findByNamePattern(namePattern);
        users.forEach(System.err::println);
    }

    //根据年龄进行查询
    @ParameterizedTest
    @ValueSource(ints = {10,500})
    public void testFindByAgeGt(int startage)
    {
        List<User> users = userDao.findByAgeGt(startage);
        users.forEach(System.err::println);
    }
}

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>jdbc</artifactId>
    <version>1.0.0</version>
    <name>jdbc</name>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <!--  添加这个依赖,springboot就会帮我们创建一个datasource的数据源的连接,
           并且会在容器中部署一个叫做 JdbcTemplate,
            所以userDao组件才能依赖注入这个jdbcTemplate对象-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-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.coloradmin.cn/o/1020038.html

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

相关文章

R语言绘图-3-Circular-barplot图

0. 参考&#xff1a; https://r-graph-gallery.com/web-circular-barplot-with-R-and-ggplot2.html 1. 说明&#xff1a; 利用 ggplot 绘制 环状的条形图 (circular barplot)&#xff0c;并且每个条带按照数值大小进行排列。 2 绘图代码: 注意&#xff1a;绘图代码中的字体…

redis 哨兵(sentinel)机制

1. 前言 sentinel&#xff08;哨兵&#xff09;是Redis 的高可用性解决方案之一。通过哨兵可以创建一个当主服务器出现故障时自动将从服务器升级为主服务器的分布式系统&#xff0c;解决了主从复制出现故障时需要人为干预的问题。 redis 的主从复制的作用有数据预热、负载均衡…

UML基础与应用之对象图

什么是对象图&#xff1f; 对象图表示一组对象及它们之间的关系&#xff0c;是某一时刻系统详细信息的快照&#xff0c;描述系统交互的静态图形&#xff0c;它由协作的对象组成&#xff0c;但不包含在对象之间传递的任何消息。因为对象是类的实例化&#xff0c;所以说某一时刻…

步步为营,如何将GOlang引用库的安全漏洞修干净

文章目录 引场景构建第一步、直接引用的第三方库升级修复策略1.确认是否为直接引用的第三方库2.找到需要升级的版本是否为release版本 第二步、间接引用的第三方库升级修复策略那么问题来了&#xff0c;我们这么间接引用库的对应的直接引用库是哪个呢&#xff1f; &#xff08;…

uni-app实现web-view图片长按下载

<template><view><web-view :webview-styles"webviewStyles" :src"webUrl"></web-view></view> </template> uniapp的web-view中图片无法长按保存&#xff0c;IOS下是正常的&#xff0c;但是Android下长按无反应 解…

在测试过程中引入可观测性平台提升业务质量

作者 观测云 产品技术专家 成都办公室 - 刘跃兰 前言 随着微服务技术的发展&#xff0c;微服务概念已深入人心&#xff0c;越来越多的企业开始使用微服务架构来开发业务应用。业务应用系统的整体架构变得更加复杂&#xff0c;并存在各种各样的不确定性因素&#xff0c;从而对…

nginx+keepalived集群搭建

1. nginx部署 单机部署可参考&#xff1a;https://blog.csdn.net/ym5209999/article/details/119897237 2. keepalived安装 [rootnginx1 ~]# yum -y install keepalived3. keepalived配置 3.1 安装完成后&#xff0c;默认配置文件位于&#xff1a;/etc/keepalived&#xff…

奶奶都看的懂的《栈》(C语言实现,超详细解析 !!!)

目录 一、前言 二、栈 &#x1f34e;栈的概念 &#x1f350;栈的结构​编辑 &#x1f349;栈的实现 &#x1f34a;栈 各个接口的实现 ⭕ 定义一个 栈 结构体 ⭕栈 的初始化 ⭕ 栈 的尾插 ⭕ 栈 的尾删 ⭕ 栈 内数据个数 ⭕ 获取 栈 顶元素 ⭕ 判断 栈 是否为空 ⭕…

Linux-网卡和网络配置

链接一篇大佬的博客&#xff1a;Linux之手把手教会修改网卡名称 文章目录 修改网卡名称步骤1&#xff1a;修改“/etc/default/grub”步骤2&#xff1a;修改“/etc/sysconfig/network-scripts”下的文件步骤3&#xff1a;修改“ifcfg-eth0”配置步骤4&#xff1a;判断操作系统的…

AIGC入门 - LLM 信息概览

本文将介绍以下 LLM OPTLLaMaAlpacaVicunaMosschatGLMBaichuanOpenbuddy 一、OPT 1、背景 OPT全称Open Pre-trained Transformer Language Models&#xff0c;即“开放的预训练Transformer语言模型”&#xff0c;是 Meta AI 团队在2022年5月发布了开源大模型OPT-175B&#…

Ninja: Towards Transparent Tracing and Debugging on ARM【TEE的应用】

目录 摘要引言贡献 背景TrustZone和受信任的固件PMU和ETM 相关工作x86上的透明恶意软件分析ARM上的动态分析工具基于仿真的系统硬件虚拟化裸机系统 Trustzone相关的系统 系统架构具体实现和评估可以看论文&#xff0c;这里不赘述了讨论总结 作者&#xff1a;Zhenyu Ning and Fe…

ffmpeg编译 Error: operand type mismatch for `shr‘

错误如下&#xff1a; D:\msys2\tmp\ccUxvBjQ.s: Assembler messages: D:\msys2\tmp\ccUxvBjQ.s:345: Error: operand type mismatch for shr D:\msys2\tmp\ccUxvBjQ.s:410: Error: operand type mismatch for shr D:\msys2\tmp\ccUxvBjQ.s:470: Error: operand type mismatch…

BCrypt 密码数据加解密运用

前言&#xff1a; 当涉及到存储用户密码时&#xff0c;确保密码的安全非常重要。以往&#xff0c;我们通常都是采用 MD5 这种不可逆算法来进行密码数据的加密后存储&#xff0c;虽然MD5算法是一种常见的哈希函数&#xff0c;但是它已经不再被认为是安全的选项。 常规MD5加密&a…

趣解设计模式之《小王的学习秘籍》

〇、小故事 小王是学校的学霸&#xff0c;凭借着自己的天赋以及对于学习的刻苦&#xff0c;每次考试都能排到年级第一名。但是&#xff0c;他所在的班级总成绩却不高&#xff0c;在所有班级中&#xff0c;属于中游水平。老师希望通过小王的贡献&#xff0c;能否帮助整个班级同…

证券账户可以绑定几张银行卡,可以更换绑定吗

个人账户实现股票量化程序化自动交易&#xff0c;券商有接口&#xff0c;门槛已降低_股票程序交易接口的博客-CSDN博客像上面的例子&#xff0c;如果按照市面上常见的可转债万3或万2不免5&#xff0c;人工操作费率限制&#xff0c;这种情况就不要想&#xff0c;根本没机会&…

返回最大元素的索引 忽略数组中所有的NaN值 numpy.nanargmax()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 返回最大元素的索引 忽略数组中所有的NaN值 numpy.nanargmax() [太阳]选择题 请问代码中第一次执行语句的输出正确的是&#xff1f; import numpy as np a np.array([0,np.nan,2]) print(&…

H264视频压缩格式

H264简介 H.264从1999年开始&#xff0c;到2003年形成草案&#xff0c;最后在2007年定稿有待核实。在ITU的标准里称为H.264, 在MPEG的标准里是MPEG-4的一个组成部分-MPEG-4 Part 10&#xff0c;又叫Advanced Video Codec&#xff0c;因此常常称为MPEG-4AVC或直接叫AVC。 压缩算…

服务器搭建(TCP套接字)-fork版(服务端)

基础版的服务端虽然基本实现了服务器的基本功能&#xff0c;但是如果客户端的并发量比较大的话&#xff0c;服务端的压力和性能就会大打折扣,为了提升服务端的并发性能&#xff0c;可以通过fork子进程的方式&#xff0c;为每一个连接成功的客户端fork一个子进程&#xff0c;这样…

Ansible自动化:简化你的运维任务

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

OpenStack创建云主机并连接CRT

文章目录 OpenStackT版创建云主机并连接CRT命令行操作&#xff08;1&#xff09;创建镜像&#xff08;2&#xff09;创建实例&#xff08;3&#xff09;创建网络创建内网创建外网 &#xff08;4&#xff09;创建安全组&#xff08;5&#xff09;创建路由&#xff08;6&#xff…