第三章springboot数据访问

ops/2024/11/16 23:45:19/

本章将对springboot的数据库访问进行讲解。

3.1 springboot 数据访问概述

SpringData是spring提供的一个用于简化数据库访问,支持云服务的开源框架。能让我们快速简单地访问数据库地数据。springboot采用整合springdata的方式统一处理数据访问层,通过添加大量的自动配置,引入各种数据访问的模板,以及统一的Repository接口,从而达到简化数据访问层的操作。

springdata提供啦多种类型数据库支持,springboot对其支持的数据库进行啦整合管理,提供对应的依赖启动器,如下表:

mybatis是操作数据库的框架,springboot没有给它的场景依赖,不过mybatis自己适配啦springboot,提供:mybatis-spring-boot-starter依赖启动器,实现数据访问操作。

3.2springboot整合mybatis

mybatis是优秀的持久层框架,支持定制化sql,存储过程以及高级映射,避免啦很多麻烦。mybatis可以用简单的xml或者注解配置和映射原生信息,将接口和java的pojos(普通java对象),映射成数据库的记录。

3.2.1 基础环境搭建

springboot与数据访问框架(mybatis)的整合非常简单,引入对应的依赖启动器,并且进行数据库相关参数设置就可以啦。下面我们来实操看:
1.数据准备

我们先新建springbootdata数据库,数据库里创建t_article和t_coomment,并且插入测试数据:

create DATABASE springbootdata;
USE springbootdata;
#创建t_article并插入相关数据
DROP TABLE IF EXISTS t_article;
#构建表t_article
CREATE TABLE t_article(
id int(20) NOT NULL AUTO_INCREMENT cOMMENT '文章id',
title varchar(200) DEFAULT NULL COMMENT '文章标题',
content longtext COMMENT '文章内容',
PRIMARY KEY(id)
)ENGINE=InnODB AUTO_INCREMENT=2 DEFAULT CHARSET=UTF8;INSERT INTO t_article VALUES('1','Spring Boot基础入门','从入门到精通讲解.');
INSERT INTO t_article VALUES('2','Spring Cloud基础入门','从入门到精通讲解..');#构建表t_comment
CREATE TABLE t_comment(
id int(20) NOT NULL AUTO_INCREMENT COMMENT '评论i',
content longtext COMMENT '评论内容',
author varchar(200) DEFAULT NULL COMMENT '评论作者',
a_id int(20) DEFAULT NULL COMMENT '关联的文章id',
PRIMARY KEY(id)
)ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
INSERT INTO t_comment VALUES ('1','很全、很详细','狂奔的蜗牛','1');
INSERT INTO t_comment VALUES ('2','赞一个','tom','1');
INSERT INTO t_comment VALUES ('3','很详细','tom2','1');
INSERT INTO t_comment VALUES ('4','赞','张山','1');
INSERT INTO t_comment VALUES ('5','很不错','张扬','2');

2创建项目引入对应的启动器

创建springboot项目时,选中依赖启动器:mysql和mybatis,springweb。

编写数据库的实体类:

package com.waiguoyu.chapter02.domain;public class Comment {private String content;public Integer id;public Integer aId;private String author;@Overridepublic String toString() {return "Comment{" +"content='" + content + '\'' +", id=" + id +", aId=" + aId +", author='" + author + '\'' +'}';}public String getContent() {return content;}public void setContent(String content) {this.content = content;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public Integer getaId() {return aId;}public void setaId(Integer aId) {this.aId = aId;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}
}
package com.waiguoyu.chapter02.domain;import java.util.List;public class Article {private Integer id;private String title;private String content;private List<Comment> commentsList;@Overridepublic String toString() {return "Article{" +"id=" + id +", title='" + title + '\'' +", content='" + content + '\'' +", commentsList=" + commentsList +'}';}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}public List<Comment> getCommentsList() {return commentsList;}public void setCommentsList(List<Comment> commentsList) {this.commentsList = commentsList;}
}

这两个类中的属性分别对应数据库表中的字段。

3.编写配置文件

在全局配置文件中编写对应的mysql数据库连接配置:

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springbootdata?useUnicode=true&characterEncoding=utf8
//数据库账号密码吗
spring.datasource.username=root
spring.datasource.password=root

这里的账号密码是 自己电脑数据库的账号密码。

数据库源选择配置:这里使用阿里巴巴的Druid数据源。引入启动依赖:

<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.8</version></dependency>

这个数据源启动器已经初始化啦一些运行参数,如果需要修改运行参数,要在配置文件中需改:

#添加并配置第三方数据源
spring.datasource,type = com.alibaba.druid.pool.DruidDataSource
spring.datasource.initialSize=20
spring.datasource.minIdle=10
spring.datasource.maxActive=100

上面实例啦修改数据源的:类型,初始化连接数,最小空闲数,最大连接数属性。如果需要修改其他的可以参照这样修改。

添加上述配置之后,springboot无法识别,需要编写自定义配置类,将这些属性注入到Druid数据源属性中。

注入方式完成啦第二章的目标就可以会啦:

import com.alibaba.druid.pool.DruidDataSource;
import com.waiguoyu.chapter02.mapper.CommentMapper;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import javax.sql.DataSource;@Configuration//标识该类为配置类,相当于创建啦xml配置文件
public class DataSourceConfig {@Bean//向xml文件里面注入一个实例对象@ConfigurationProperties(prefix = "spring.datasource")//将全局配置文件中以spring.datasouce开头的注入到 该方法的 返回的 对象的属性中public DataSource getDataSource() {return new DruidDataSource();}}

上边不配置这些操作也可以进行,只是为啦模拟实际开发而已。

3.2.2 使用注解的方式整合mybatis

上面是环境搭建,在这里才是整合。

第一步:创建Mapper接口文件:

创建mapper包,然后创建对数据库表进行数据操作的接口:CommentMapper,

import com.waiguoyu.chapter02.domain.Comment;
import org.apache.ibatis.annotations.*;@Mapper//标识该类是mybatis接口文件,并且保证springboot能够扫描到它
public interface CommentMapper {//接口内部通过注解和sql语句完成对表的增删改查@Select("SELECT * FROM t_comment WHERE id= #{id}")public Comment findById(Integer id);@Insert("INSERT INTO t_comment(content,author,a_id)" + "values (#{content},#{author},#{aId})")public int insertComment(Comment comment);@Update("UPDATE t_comment set content = #{content} WHERE id = #{id}")public int updateComment(Comment comment);@Delete("DELETE FROM t_comment WHERE id=#{id}")public int deleteComment(Integer id);}

注意:如果接口或者业务过多,需要重复添加大量的@Mapper注解,我们可以在sprin gboot启动类上添加:@MapperScan(“xxx”)注解,这样就不需要逐个添加@Mapper注解啦。xxx表示需要指定的具体包名。例如:

第二步:编写单元测试进行接口测试

在测试类引入Cm+ommentMapper接口,测试如下:

package com.waiguoyu.chapter02;import com.waiguoyu.chapter02.domain.Comment;
import com.waiguoyu.chapter02.mapper.CommentMapper;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)
@SpringBootTest
class Chapter02ApplicationTests {@Testvoid contextLoads() {}@Autowiredprivate CommentMapper commentMapper;@Testpublic void slectCommenttest(){Comment comment = commentMapper.findById(1);System.out.println(comment);}
}

到这里就映入成功啦。

测试结果有一个数据没有映射成功,因为编写的实体类那个属性使用驼峰命名法,将数据表中的a_id设计成啦aId属性,所有无法正常映射。解决这个问题:

在springboot全局配置文件添加驼峰命名匹配映射配置就可以啦:

#开启驼峰命名匹配映射
mybatis.configuration.mapUnderscoreToCamelCase=true

3.2.3 使用配置文件的方式整合Mybatis

通过案例来演示如何使用配置文件xml的方式整和mybatis

1.创建Mapper接口文件,用于操作数据库表:t_article

import com.waiguoyu.chapter02.domain.Article;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface ArticleMapper {//查询数据public ArticleMapper selectArticle(Integer id);//更新数据操作public int updataArticle(Article article);
}

这里声明啦查询和更新操作两个方法。

2.创建xml文件,创建一个统一映射文件ArticleMapper.xml:

这里是mybatis映射文件中的具体写法,详细请看mybaits官方文档。

3.配置xml映射文件路径:

上面的xml文件springboot无法扫描到,需要在全局配置文件里面添加这个映射文件路径的配置,同时还要添加实体类别名映射路径:

如果xml文件里面映射文件中实体类的数据映射配置,使用的是全路径名称,就不需要配置别名路径。

4.编写测试类进行测试:

实际开发中会混合使用这两种整合mybatis的方式。

3.3 springboot整合jpa

jpa:java持久化api,持久化规范,它提供:对象/关系映射 的 工具,管理java中的关系型数据库。

目的:简化持久化开发工作,整合orm(对象/关系映射)技术。

3.3.1 springData jap介绍

它是spring在Orm框架和jpa规范的基础上封装的一套jpa应用框架,让开发者用较少的代码完成数据的操作。我们先熟悉spring data jpa 的基本使用进行简单介绍

1.编写orm实体类

使用实体类前先编写实体类和数据表进行映射,并配置好映射关系,应为spring data jpa针对orm关系的数据进行的操作。

2.编写Repository接口

根据不同的 表数据操作 编写对应的Repository接口,并且根据需求编写对应的数据操作方法。

package com.waiguoyu.chapter02.mapper;import com.waiguoyu.chapter02.domain.Discuss;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Transactional;import java.util.List;public interface DiscussRepository extends JpaRepository<Discuss, Integer> {//基本的查询方法,不用注解,方法名是jpa支持的 方法名关键字 查询方法,方法的作用:查询author非空的Discuss数据public List<Discuss> findByAuthorNotNull();//该方法通过@Query注入sql语句,用于通过分页查询,查询discuss数据@Query("SELECT c from t_comment c where c.aId=?1")public List<Discuss> getDiscussPaged(Integer aid, Pageable pageable);//与上面的方法同,nativeQuery = true 用来定义:编写原生的sql语句,@Query(value = "SELECT * from t_comment where c.aId=?1",nativeQuery = true)public List<Discuss> getDiscussPaged2(Integer aid, Pageable pageable);@Transactional//支持事务管理,也就是要么都成功,如果更新数据不成功就退回全部操作,防止数据的丢失@Modifying//支持数据变更//通过注解注入sql语句,更新和删除需要配合使用上面两个注解。@Query("update t_comment c set c.author = ?1 where c.id=?2")public int updateDiscuss(String author,Integer id);@Transactional@Modifying@Query("delete t_comment c where c.id=?1")public int deleteDiscuss(Integer id);}

下面对编写这种Repository接口进行具体的讲解:

1.编写这类接口时,必须继承 XXRepository<T,ID>接口,T:表示要操作的实体类,ID表示实体类的主键的类型。上面的案例继承啦:JpaRepository接口。

下面讲解JpaRepository继承结构中的涉及到的接口:

1.repository接口没有方法,是spring Data JPA提供的用于自定义repository接口的顶级父接口。

2.CrudRepository接口:继承啦repository接口,包含一些基本的CRUD方法(比如)

3.PagingAndSortingRepository 接口继承CrudRepository接口,并且提供啦分页和排序两个方法。

4.QueryByExampleExecutor接口:能够进行条件封装查询,能通过Example实例执行复杂的条件查询。

5.JpaRepository接口:同时继承PagingAndSortingRepository 接口和QueryByExampleExecutor接口,并且还拥有一些数据操作方法,自定义Repository接口文件时一般会直接继承JpaRepository接口。

简而言之就是:JpaRepository接口接口有:一些基本的CRUD方法,分页和排序两个方法。能够进行条件封装查询,能通过Example实例执行复杂的条件查询。

使用springdatajpa进行数据操作时,可以有多种实现方式,下面进行说明:

下图就是对应的springData Jpa中支持的方法名关键字对应的sql语句:

在自定义的Repository接口方法中,数据变更的操作方法上必须使用那两个注解(代码案例讲解那),不然会报错,如果在调用Repository接口的方法的service类上已经添加啦事务处理的注解

就不用在Repository接口上添加啦。

jpa还支持使用Example实例进行复杂的条件查询,spring Data Jpa的基本使用进行了解,详细可以去官方文档进行学习。

3.3.2 使用springboot整合jpa

了解完jpa之后,我们具体来整合jpa

1.在pom文件添加其依赖:

 <!--springdatajpa的依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency>

2.编写ORM实体类:

package com.waiguoyu.chapter02.domain;import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import org.springframework.data.annotation.Id;//定义springboot data jpa 实体类,将该类与数据库表进行映射@Entity(name="t_comment")//标注一个 与数据库做映射的 实体类,用name属性指定映射的数据库表
public class Discuss {@Id//可以用在类属性或者get方法上,用于绑定数据库表的主键@GeneratedValue(strategy = GenerationType.AUTO)//与@id一起使用,确定主键的生成策略,比如TABLE;用一个特定的数据库表格来保存主键// IDENTITY:主键自增,SEQUENCE:不支持主键自增的主键的生成策略,AUTO:由jpa自主选择前三个策略中的一个private Integer id;private String content;private String author;@Column(name = "a_id")//标注属性,当类属性和数据库表的对应字段名字不一样,就是用它来绑定private Integer AId;@Overridepublic String toString() {return "Discuss{" +"id=" + id +", content='" + content + '\'' +", author='" + author + '\'' +", AId=" + AId +'}';}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}public Integer getAId() {return AId;}public void setAId(Integer AId) {this.AId = AId;}
}

3.编写respositry接口,类同上边得案例。

4.编写单元测试:

5.整体得测试:

3.4springboot整合redis

非关系型数据库的整合。

3.4.1redis介绍

redis介绍另看文章,接下来就i安装redis。

redis只需要解压缩好文件,运行redis-server.exe就启动可以啦。

再去下载redis desktop manager客户端连接用户端就可以啦。打开客户端根据下面的操作进行即可。

3.4.2 使用springboot整合redis

1.添加springbootdataredis依赖:

  <!--redis的依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>

2.编写对应的实体类:

package com.waiguoyu.chapert03.domain;import org.springframework.data.annotation.Id;
import org.springframework.data.redis.core.RedisHash;
import org.springframework.data.redis.core.index.Indexed;import java.util.List;@RedisHash("persons")//指定操作实体类在redis数据库中的存储空间,该类的数据操作都存储在redis数据库中名为persons的存储空间下
public class Person {@Id //标识实体类主键。也可以在数据存储时指定idprivate String id;@Indexed //标识对应属性在redis数据库中生成二级索引。索引名称就是属性名private String firstname;@Indexedprivate String lastname;private Address address;private List<Family> familyList;@Overridepublic String toString() {return "Person{" +"id='" + id + '\'' +", firstname='" + firstname + '\'' +", lastname='" + lastname + '\'' +", address=" + address +", familyList=" + familyList +'}';}public Person() {}public Person(String id, String firstname, String lastname, Address address, List<Family> familyList) {this.id = id;this.firstname = firstname;this.lastname = lastname;this.address = address;this.familyList = familyList;}public String getId() {return id;}public void setId(String id) {this.id = id;}public List<Family> getFamilyList() {return familyList;}public void setFamilyList(List<Family> familyList) {this.familyList = familyList;}public Address getAddress() {return address;}public void setAddress(Address address) {this.address = address;}public String getLastname() {return lastname;}public void setLastname(String lastname) {this.lastname = lastname;}public String getFirstname() {return firstname;}public void setFirstname(String firstname) {this.firstname = firstname;}
}
import org.springframework.data.redis.core.index.Indexed;public class Family {@Indexedprivate String type;@Indexedprivate String username;
省略get,set,构造函数,以及tostring
public class Address {@Indexedprivate String city;@Indexedprivate String country;

3.编写Repository接口:

springboot给常用数据库提供啦一些自动化配置,

这些操作与上一节的一样。可以使用方法名关键字进行数据操作。

package com.waiguoyu.chapert03.repository;import com.waiguoyu.chapert03.domain.Person;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.CrudRepository;import java.util.List;
//继承的CrudRepository接口定义啦很多查询方法,jpaRepository是springboot的jpa特有的,如果想使用这个接口操作redis数据库,可以同时导入redis和
//jpa依赖。
public interface PersonRepository extends CrudRepository<Person, Long> {List<Person> findByLastName(String lastName);Page<Person> findPersonByLastName(String lastName, Pageable page);List<Person> findByFirstNameAAndLastname(String firstName, String lastName);List<Person> findByAddress_City(String city);List<Person> findByFamilyList_Username(String username);}

4.连接redis数据库:
在配置文件配置信息:

#服务器连接密码默认为空
spring.data.redis.password=
#redis服务器地址
spring.data.redis.host=localhost
#连接的端口号
spring.data.redis.port=6379

也可以单独添加相关配置,跟之前的一样。

4.编写单元测试进行测试:

@Autowiredprivate PersonRepository personRepository;@Testpublic void savePerson() {Person person = new Person("张","有才");Person person1 = new Person("张","有才123");Address address=new Address("北京","chinen");person.setAddress(address);//创建并添加家庭成员List<Family> families=new ArrayList<>();Family fan=new Family("父亲","母亲");families.add(fan);person.setFamilyList(families);
//        向redis数据库添加数据Person save=personRepository.save(person);Person save2=personRepository.save(person1);System.out.println(save);System.out.println(save2);}

bug:我这里打的代码连接不上redis数据库。

目前就是redis整合springboot以及进行数据库操作的方式啦。想了解更多redis知识请看官方文档。

3.5 本章小结


http://www.ppmy.cn/ops/134271.html

相关文章

【蓝桥等考C++真题】蓝桥杯等级考试C++组第13级L13真题原题(含答案)-统计数字

CL13 统计数字(50 分) 一场歌唱比赛有不超过 26 位选手参加&#xff0c;选手的代号依次用大写字母 A、B、C……表示。在节目现场观众要给这些选手投票&#xff0c;每人投一票&#xff0c;选出最喜欢的选手。已知观众的投票记录&#xff0c;请将所有选手的得票数从高到低进行排…

python并发与并行概念,以及multiprocessing模块应用举例

在Python中,并发和并行是两个相关但含义不同的概念: ● 并发(Concurrent)指的是在一段时间内,多个任务交替执行的能力,这些任务可能不是同时执行,但给人的感觉是同时在处理多项任务。它可以发生在单核或多核处理器上,通过任务调度来实现“同时”处理的效果。 ● 并行(…

4.1 Android NDK 简介

原生开发套件&#xff08;NDK&#xff09;是一套工具&#xff0c;使您能够在 Android 应用中使用 C/C 代码&#xff0c;并提供众多平台库&#xff0c;您可以使用这些平台库管理原生 activity 和访问实体设备组件&#xff0c;例如传感器和触控输入。如果您需要实现以下一个或多个…

基于集成Whisper 与 Pepper-GPT改进人机交互体验并实现顺畅通信

摘要 随着技术以令人眼花缭乱的速度发展&#xff0c;使人机交互更加顺畅比以往任何时候都更加重要。为了应对这一挑战&#xff0c;一个新领域应运而生&#xff1a;人机交互&#xff08;HRI&#xff09;。有效的人机交互被认为是实现技术效益的关键。 用户体验&#xff08;UX&…

封装el-menu

案例图 数据格式 commonMenu.vue <template><div class"commonMenuStyle"><el-sub-menu v-if"hasChildren" :index"item.MenuId"><template #title><el-icon><location /></el-icon><!-- isColl…

第八节 如何结合AAA实现用户远程登录-路由基础

关于调试设备的登录方式&#xff0c;一共有三种&#xff1a; 第一个&#xff1a;console&#xff1a;需要工程师在现场&#xff0c;进行登录&#xff0c;设备开局的时候使用 第二个&#xff1a;telnet ssh&#xff1a;基于网络互通的前提下进行登录的&#xff0c;远程登录 第三…

你可以通过以下步骤找到并打开 **Visual Studio 开发者命令提示符**:

你可以通过以下步骤找到并打开 Visual Studio 开发者命令提示符&#xff1a; 1. 通过开始菜单查找 打开 开始菜单&#xff08;点击屏幕左下角的 Windows 图标&#xff09;。在搜索框中输入 Developer Command Prompt。你应该看到以下几种选项&#xff08;具体取决于你的 Visu…

【OpenGL】OpenGL简介

文章目录 OpenGL概述OpenGL的本质OpenGL相关库核心库窗口管理glutfreeglutglfw 函数加载glewGLAD OpenGL概述 OpenGL(Open Graphics Library) 严格来说&#xff0c;本身并不是一个API&#xff0c;它是一个由Khronos组织制定并维护的规范(Specification)。OpenGL规范严格规定了…