5.开发DAO组件 -- Spring Data JPA

news2024/9/24 17:18:29

开发DAO组件

作用:用来访问数据库
持久化技术:Spring Data, JPA, Mybaits,jOOQ 等
Spring Boot为常见持久化技术提供了支持。

现在使用 Spring Data JPA

Spring Data JPA

使用Spring Data JPA来访问数据库,需要再项目添加两个依赖:

1、Spring Boot Data JPA依赖,它会自动添加数据源的实现(用 springboot 提供的能自动配置和整合的Spring Boot Data JPA)

        <!--  添加 Spring Boot Data JPAStarter 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

2、MySQL数据库驱动依赖

        <!--  mysql数据库驱动依赖  -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

只要添加Spring Boot Data JPA的starter组件依赖,Spring Boot就会为你搞定整合spring data jpa的一切基础配置

创建配置文件,指定连接数据库的信息

创建一个配置文件 application.properties,就放在resources包下

# 数据库 URL
spring.datasource.url=jdbc:mysql://localhost:3306/数据库名?serverTimezone=UTC
spring.datasource.username=用户名
spring.datasource.password=密码
# 指定显示sql语句
spring.jpa.show-sql=true
# 指定根据实体自动建表
spring.jpa.generate-ddl=true

因为配置文件有配置这个功能:
指定根据实体自动建表 spring.jpa.generate-ddl=true

所以我们可以通过给Book类添加JPA注解,变成实体类。

问题:Java类和实体类有什么区别?

Java类: 是通用的,可以用于实现各种功能和逻辑
实体类: 是具有特定目的的类,用于表示领域模型中的具体实体,与数据持久化和数据库操作相关。

1、持久化能力: 实体类是指具有持久化能力的类,可以通过ORM(对象关系映射)技术将其映射到数据库表中,实现对象和数据库之间的数据交互。而普通类则通常不具备持久化的能力
2、注解: 实体类通常需要使用特定的注解(如JPA的@Entity注解)来进行标记,以便在持久化过程中进行映射和管理。而普通类不需要添加这些注解。
3、数据库映射: 实体类与数据库表之间存在一一对应或一对多的关系,实体类的属性通常与数据库表的字段相对应。而普通类则不需要与数据库表进行映射。
4、CRUD操作: 实体类通常可以通过ORM框架提供的API进行数据库的增删改查操作(CRUD操作)。而普通类不具备这些数据库操作的能力。
5、规范要求: 实体类在JPA等框架中有一些规范要求,如需要无参构造函数、需要主键等。而普通类没有这些规范要求。
6、实例化和使用: ava类可以被直接实例化和使用,用于封装数据和实现业务逻辑。而实体类一般需要通过ORM框架或者其他方式来创建和管理,以便与数据库进行交互。

如何把Java类变成实体类:

实体类通常需要使用特定的注解(如JPA的@Entity注解)来进行标记和配置,以便在持久化过程中进行映射和管理。而Java类没有这些特定的持久化注解

package cn.ljh.boot.domain;

import javax.persistence.*;

//通过添加JPA注解,把这个Java类变成实体类
@Entity  //表明这个类是一个实体类
@Table(name = "book_inf") //把这个实体类映射到数据库的 book_inf 表
public class Book {

    @Id //主键id
    @GeneratedValue(strategy = GenerationType.IDENTITY) //指定主键生成策略
    @Column(name = "book_id") //指定这个字段映射到数据库表的具体列名
    private Integer id;
    @Column(name = "book_name")
    private String name;
    @Column(name = "price")
    private double price;
    @Column(name = "author")
    private String author;


后面我把price价格的修饰改成 bigdecimal 修饰类型

IDEA连接mysql

把Java类改成实体类后,运行项目,发现数据库自动生成 bool_inf 这张表了,对应的列也都生成了。
在这里插入图片描述

准备工作完成后,现在开发DAO组件

是基于 Spring Data 开发DAO组件,用spring data ,既可以访问sql数据库,也可以访问nosql数据库。

 让DAO接口继承CrudRepository接口
 Spring Data会为继承了CrudRepository接口的DAO接口自动为它动态生成实现类,并将该实现类的实例部署在Spring容器中。
 此外,Spring Data还可动态为BookDao增加很多查询方法。
 Spring Data不仅可以自动生成大量的CRUD方法,也能允许用户定义自定义的查询(sql、HQL),
 甚至允许用户使用最底层API(EntityManager、DataSource、Connection……)

开发Dao组件,只需要创建一个BookDao 接口,然后去继承CrudRepository接口就可以了。
在service就可以注入这个BookDao 对象来用了,这时候的bookDao因为继承了CrudRepository接口,所以本身已经集成了很多sql操作

public interface BookDao extends CrudRepository<Book,Integer> {
}

在这里插入图片描述
通过代码可以看出,注入BookDao组件依赖后,这个bookDao就集成了很多sql操作。
比如简单的 save 保存,findAll 查询所有,deleteById根据id删除数据等。

下面的代码就是正式的业务逻辑,使用的就是基于spring boot data jpa 来实现数据库的数据持久化操作


//添加这个@Service注解,springboot就可以自动扫描这个Service组件的实现类,然后把这个类部署成容器中的bean。
@Service
@Transactional //事务控制
public class BookServiceImpl implements BookService {

    //注入DAO组件,用有参构造器来注入
    private BookDao bookDao;
    public BookServiceImpl(BookDao bookDao){
        this.bookDao = bookDao;
    }
    //这个bookDao 因为继承了CrudRepository接口,所以本身已经集成了很多sql操作。
    
    //添加书籍的方法
    @Override
    public Integer addBook(Book book) {
        Book b = bookDao.save(book);
        return b.getId();
    }

    //查看所有书籍的方法
    @Override
    public List<Book> getAllBooks() {
        //要强制转换
        List<Book> listBooks = (List<Book>) bookDao.findAll();
        return  listBooks;
    }

    //删除书籍的方法
    @Override
    public void deleteBookById(Integer id) {
        bookDao.deleteById(id);
    }
}

对应的前端页面也贴出来。有过一些功能修改,直接贴出来记录

bookForm.html添加书籍页面

<!DOCTYPE html>
<!-- HTML引入Thymeleaf ,导入命名空间 , 把thymeleaf的域名加进来就可以使用了-->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>添加图书页面</title>
    <!--  导入 webjar 包中的 bootstrap 样式库  -->
    <link rel="stylesheet" th:href="@{/webjars/bootstrap/4.6.0/css/bootstrap.css}">

</head>
<body>

<!--  class="container" :相当于类名,就是这个div模块的名字-->
<!--  class="alert alert-primary" : 警报框  -->
<div class="container">
    <div id="addBookFailTips" th:if="${tip} != null">
        <div th:text="${tip}" class="alert alert-primary" style="text-align: center">书籍添加失败显示的提示信息</div>
    </div>

    <h2>添加图书</h2>
<!--  TODO  -->
    <!--  submit提交表单的时候,就会走这个addBook方法  -->
    <form method="post" th:action="@{/addBook}">
        <div class="form-group row">
            <label for="name" class="col-sm-3 col-form-label">图书名:</label>
            <div class="col-sm-9">
                <input type="text" id="name" name="name" class="form-control" placeholder="输入图书名">
            </div>
        </div>
        <div class="form-group row">
            <label for="author" class="col-sm-3 col-form-label">作者:</label>
            <div class="col-sm-9">
                <input type="text" id="author" name="author" class="form-control" placeholder="输入作者">
            </div>
        </div>
        <div class="form-group row">
            <label for="price" class="col-sm-3 col-form-label">价格:</label>
            <div class="col-sm-9">
                <input type="text" id="price" name="price" class="form-control" placeholder="输入价格">
            </div>
        </div>
        <div class="form-group row">
            <div class="col-sm-6 text-right">
                <button id="add" type="submit" class="btn btn-primary">添加</button>
            </div>
            <div class="col-sm-1 ">
                <button type="reset" class="btn btn-danger">重置</button>
            </div>
            <div class="col-sm-3 ">
                <a th:href="@{/listBooks}">
                    <button type="button" class="btn btn-secondary" style="background-color: yellowgreen">查看书籍列表
                    </button>
                </a>
            </div>
        </div>
    </form>
</div>
<!--TODO 提示输入信息不能为空-->
<script>
    // <!-- 如果书籍添加失败,那么在提示 2 秒后设置 div 为 none 进行隐藏 -->
    // setTimeout(function() {
    //     document.getElementById("addBookFailTips").style.display = "none";
    // }, 2000); // 2秒后隐藏
</script>
</body>
</html>

书籍列表页面 listBooks.html

<!DOCTYPE html>
<!-- HTML引入Thymeleaf ,导入命名空间 , 把thymeleaf的域名加进来就可以使用了-->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>书籍列表页面</title>
    <!--  导入 webjar 包中的 bootstrap 样式库  -->
    <link rel="stylesheet" th:href="@{/webjars/bootstrap/4.6.0/css/bootstrap.css}">

</head>
<body>
<!--  class="container" :相当于类名,就是这个div模块的名字-->
<!--  class="alert alert-primary" : 警报框  -->
<div class="container">
    <table class="table table-hover">
        <tr>
            <th>书名</th>
            <th>价格</th>
            <th>作者</th>
            <th>删除</th>
        </tr>
        <!--  循环迭代  ${books}就是后端传来的集合数据, book就是循环后的变量  -->
        <tr th:each="book: ${books}">
            <td th:text="${book.name}">书名</td>
            <td th:text="${book.price}">价格</td>
            <td th:text="${book.author}">作者</td>
            <td><a th:href="@{/deleteBook/} + ${book.id}">删除</a></td>
        </tr>
    </table>
</div>
<div class="container">
        <a th:href="@{/bookForm}"><button type="button" style="background-color: beige">返回添加书籍</button></a>
</div>
</body>
</html>

实现页面:

bookForm页面
在这里插入图片描述
listBooks页面
在这里插入图片描述

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

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

相关文章

探究Vue源码:mustache模板引擎(8) 了解nestTokens 手写梳理模板字符串井号循环嵌套结构tokens

上文 探究Vue源码:mustache模板引擎(7) 手写模板字符串转换tokens数组过程中 我们操作出了一个较为简单的 tokens数组 并简单处理了 井号反斜杠的特殊符号语法 那么 我们现在需要将零散的tokens嵌套起来 主要就体现在 我们 井号 到 反斜杠 中间的内容 显然是属于循环语句中的子…

Postman如何做接口测试1:如何导入 swagger 接口文档

在使用 postman 做接口测试过程中&#xff0c;测试工程师会往界面中填入非常多的参数&#xff0c;包括 url 地址&#xff0c;请求方法&#xff0c;消息头和消息体等一系列数据&#xff0c;在请求参数比较多的情况下非常花时间。 我们可以使用 postman 的文档导入功能&#xff…

Chapter 11: Tuples | Python for Everybody 讲义笔记_En

文章目录 Python for Everybody课程简介TuplesTuples are immutableComparing tuplesTuple assignmentDictionaries and tuplesMultiple assignment with dictionariesThe most common wordsUsing tuples as keys in dictionariesSequences: strings, lists, and tuples - Oh M…

因果推断(二)倾向匹配得分(PSM)

因果推断&#xff08;二&#xff09;倾向匹配得分&#xff08;PSM&#xff09; 前文介绍了如何通过合成控制法构造相似的对照组&#xff0c;除此之外&#xff0c;也可以根据倾向匹配得分&#xff08;PSM&#xff09;进行构造&#xff0c;即为每一个试验组样本在对照组中找对与…

dialog => :before-close的属性应用

在element-ui里面关闭弹窗的时候before-close会触发。 也就是点击X的时候回触发before-close这个属性, 代码实例: <el-dialogtitle"新增用户":visible.sync"dialogVisible"width"50%":before-close"handleClose"> handleClose…

【动态规划part15】| 392.判断子序列、115.不同的子序列

&#x1f388;LeetCode392.判断子序列 链接&#xff1a;392.判断子序列 给定字符串 s 和 t &#xff0c;判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些&#xff08;也可以不删除&#xff09;字符而不改变剩余字符相对位置形成的新字符串。&#xff08;…

Linux端口与netstat使用

端口是设备与外界交流的通道&#xff0c;有物理端口和虚拟端口。 Linux有六万多端口&#xff0c;可以分为下面几类&#xff1a; 1.公认端口&#xff08;1~1023&#xff09;&#xff1a;用于系统内置与知名程序的预留使用 2.注册端口&#xff08;1024~49151&#xff09;&…

使用webdriver-manager解决浏览器与驱动不匹配所带来自动化无法执行的问题

1、前言 在我们使用 Selenium 进行 UI 自动化测试时&#xff0c;常常会因为浏览器驱动与浏览器版本不匹配&#xff0c;而导致自动化测试无法执行&#xff0c;需要手动去下载对应的驱动版本&#xff0c;并替换原有的驱动&#xff0c;可能还会遇到跨操作系统进行测试的时候&…

【autoresizing案例 Objective-C语言】

一、autoresizing案例 1.在介绍autoresizing之前,告诉大家,这个只是介绍,以后不要用这个东西,都用autolayout 还有一个非常重要的就是,使用autoresizing,就不能用autolayout,反之亦然 2.我们来看一个案例,看一个什么案例呢,看这么一个案例, 大家先看我这个的要求:…

如何安装、部署、启动Jenkins

一、测试环境 Linux系统 Centos 7 二、安装步骤&#xff1a; 1、安装jdk 我安装的是jdk8&#xff0c;此处就不多说了&#xff0c;自己百度哈&#xff0c;很简单 2、安装jenkins 首先依次执行如下三个命令&#xff1a; 2.1、导入镜像&#xff1a; [rootcentos7 ~]# sudo …

《吐血整理》进阶系列教程-拿捏Fiddler抓包教程(18)-Fiddler如何接口测试,妈妈再也不担心我不会接口测试了

1.简介 Fiddler最大的优势在于抓包&#xff0c;我们大部分使用的功能也在抓包的功能上&#xff0c;fiddler做接口测试也是非常方便的。 领导或者开发给你安排接口测试的工作任务&#xff0c;但是没有给你接口文档&#xff08;由于开发周期没有时间出接口文档&#xff09;&…

小程序商品如何上传视频

小程序商品展示的方式在不断创新&#xff0c;除了传统的图片展示&#xff0c;视频成为了吸引用户注意力的重要方式之一。今天就讲解一下&#xff0c;商家怎么上传商品视频。 1. 商家需要准备好商品视频。商家可以自己拍摄商品的使用演示视频、产品介绍视频等&#xff0c;也可以…

Linux部署jar包,隐藏命令行参数

Linux部署jar包&#xff0c;隐藏命令行参数 一、背景需求二、查阅资料三、实现隐藏库3.1、测试test.c3.2、设置隐藏库3.3、验证 四、应用jar启动命令五、直接应用结果 最新项目安全检测&#xff0c;发现配置文件中数据库密码&#xff0c;redis密码仍处理明文状态 于是整理了一篇…

做软件测试,掌握哪些技术才能算作“测试大佬”?

一、过硬的基础能力 其实所有的测试大佬都是从底层基础开始的&#xff0c;随着时间&#xff0c;经验的积累慢慢变成大佬。要想稳扎稳打在测试行业深耕&#xff0c;成为测试大牛&#xff0c;首当其冲的肯定就是拥有过硬的基础&#xff0c;所有的基础都是根基&#xff0c;后期所…

【应用层】HTTPS协议详细介绍

文章目录 前言一、什么是"加密"二、常见的加密方式三、数据摘要&#xff08;数据指纹&#xff09;四、证书总结 前言 HTTPS也是一个应用层协议&#xff0c;是在HTTP协议的基础上引入了一个加密层&#xff0c;由于HTTP协议内容都是按照文本的方式明文传输的&#xff…

【外卖系统】修改菜品

需求分析 在菜品管理列表页面点击修改按钮&#xff0c;跳转到修改页面&#xff0c;在修改页面回显菜品相关信息并进行修改&#xff0c;在最后点击确定按钮完成修改操作 代码设计 页面发送ajax请求&#xff0c;请求服务端获取分类数据&#xff0c;用于菜品分类下拉框中数据显…

【Unity学习笔记】对象池

文章目录 设计思路总体设计从生命周期考虑 一些代码 对象池这个东西老生常谈了&#xff0c;使用它的好处在于&#xff1a;当我们需要重复创建或者销毁一些物体&#xff0c;例如限制子弹数量上限为10发&#xff0c;当射出第11发就需要使第10发消失&#xff0c;第11出现。销毁10号…

vue中人员导出功能实现

大纲&#xff1a; 1、导出定义的export.js文件 代码展示 import axios from axios //导出一 export const exportExcel (url, params, name, type post) > {// url url路径 params 查询参数 name 文件名 type 请求方式axios[type](url, params, {responseType: blob,}).t…

微信小程序多码融合

1、多码融合实现 如果需要实现扫码关注、跳转页面、扫码充电以及第三方融合扫码充电的需求&#xff0c;通过“扫普通链接二维码打开小程序” 的功能采用hlht协议的方式进行融合&#xff0c;使用代码生成新的二维码&#xff0c;二维码内容格式如下&#xff1a; hlht://9900000…

性能测试基础知识(三)性能指标

性能测试基础知识&#xff08;三&#xff09;性能指标 前言一、时间特性1、响应时间2、并发数3、吞吐量&#xff08;TPS&#xff09; 二、资源特性1、CPU利用率2、内存利用率3、I/O利用率4、网络带宽使用率5、网络传输速率&#xff08;MB/s&#xff09; 三、实例场景 前言 性能…