SpringBoot开发实用篇2---与数据层技术有关的替换和整合
四、数据层解决方案
1.SQL
现有数据层解决方案技术选型:Druid+MyBatis-plus+MySQL
数据源:DruidDataSource
持久化技术:MyBatis-plus/MyBatis
数据库:MySql
内置数据源:
SpringBoot提供了3种内嵌的数据源对象供开发者选择:
HikariCP:默认内置数据源对象;
Tomcat提供DataSource:HikariCP不可用的情况下,且在web环境中,将使用tomcat服务器配置的数据源对象;
Commons DBCP:Hikari不可用,tomcat数据源也不可用,将使用dbcp数据源。
使用方式:先使用默认配置,再使用个性化配置。
通用配置无法设置具体的数据源配置信息,仅提供基本的连接相关配置,如需配置,在下一级配置中设置具体设定。
JdbcTemplate:Spring提供的默认的持久化技术(几乎没人用)
操作数据库的模板技术。
pom.xml:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
@Autowiredprivate JdbcTemplate jdbcTemplate;@Testvoid testJdbcTemplate(){String sql="select * from tbl_book";RowMapper<Book> rm=new RowMapper<Book>() {@Overridepublic Book mapRow(ResultSet rs, int rowNum) throws SQLException {Book temp=new Book();//查出来的放到结果集中,从结果集中得到,在set到对象中temp.setId(rs.getInt("id"));temp.setName(rs.getString("name"));temp.setType(rs.getString("type"));temp.setDescription(rs.getString("description"));return temp;}};List<Book> list = jdbcTemplate.query(sql, rm);System.out.println(list);}@Testvoid testJdbcTemplateSave(){String sql="insert into tbl_book values(null,'springboot','springboot','springboot')";jdbcTemplate.update(sql);}
H2数据库:
SpringBoot提供了3种内嵌数据库供开发者选择,提高开发测试效率:
H2
HSQL
Derby
伴随着内存启动而启动的数据库,比较小巧。
pom.xml中:
<!--演示H2数据库--><dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency>
配置文件中:
开启服务后,在浏览器中就可以访问:
可以和持久层框架Mybatis-plus、JdbcTemplate搭配使用。
2.NoSQL
(1)Redis
市面上常见的NoSQL解决方案:
Redis
MongoDB
ES
上述技术通常在Linux系统中安装部署。
在Windows安装,方便整合(整合都是一样的)。
Redis是一款key-value存储结构的内存级NoSQL数据库:
支持多种数据存储格式
支持持久化
支持集群
Redis的安装与启动(Windows版)
Windows解压安装或一键式安装
服务端启动命令
redis-server.exe redis.windows.conf
客户端启动命令
redis-cli.exe
具体操作:先打开服务器,再用客户端去连接。
SpringBoot整合Redis:
导入redis对应的starter,在创建工程的时候勾选。
配置Redis(采用默认配置)
提供操作Redis接口对象RedisTemplate:
@SpringBootTest
class Springboot16RedisApplicationTests {@Resourceprivate RedisTemplate redisTemplate;@Testvoid set() {ValueOperations ops = redisTemplate.opsForValue();ops.set("age",41);}@Testvoid get(){ValueOperations ops = redisTemplate.opsForValue();Object age = ops.get("age");System.out.println(age);}@Testvoid hset() {HashOperations ops = redisTemplate.opsForHash();ops.put("info","a","aa");}@Testvoid hget(){HashOperations ops = redisTemplate.opsForHash();Object val = ops.get("info", "a");System.out.println(val);}
}
客户端:RedisTemplate以对象作为key和value,内部对数据进行序列化。
StringRedisTemplate以字符串作为key和value,与Redis客户端操作等效。
@SpringBootTest
public class StringRedisTemplateTest {@Autowiredprivate StringRedisTemplate stringRedisTemplate;@Testvoid get(){ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();String name = ops.get("name");System.out.println(name);}
}
客户端使用jedis,加坐标,改配置文件。
lettcus和jedis的区别:
jedis连接Redis服务器是直连模式,当多线程模式下使用jedis会存在线程安全问题,解决方案可以通过配置连接池使每个连接专用,这样整体性能就会大受影响。
lettcus基于Netty框架进行与Redis服务器连接,底层设计中采用StatefulRedisConnection。StatefulRedisConnection自身是线程安全的,可以保障并发访问安全问题,所以一个连接可以被多线程复用。当然lettcus也支持多连接实例一起工作。
(2)MongoDB
需求:既能存储结构化数据,又高性能。数据有着很高的修改需求
MongoDB是一个开源、高性能、无模式的文档型数据库。NoSQL数据库产品的一种,是最像关系型数据库的非关系型数据库。
启动mongoDB服务:
在客户端连接MongoDB服务:
mongo --host=127.0.0.1 --port=27017
或者使用可视化客户端:
基础CRUD操作:
SpringBoot整合MongoDB:
1.导入Mongodb对应的starter:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
2.配置mongodb访问uri:
3.提供操作Mongodb接口对象MongoTemplate
@SpringBootTest
class Springboot17MongdbApplicationTests {@Autowiredprivate MongoTemplate mongoTemplate;@Testvoid contextLoads() {Book book=new Book();book.setId(1);book.setName("springboot");book.setType("springboot");book.setDescription("springboot");mongoTemplate.save(book);}/*** 类型转换的问题 把数据库中不是int的删了*/@Testvoid find(){List<Book> all = mongoTemplate.findAll(Book.class);System.out.println(all);}}
(3)ES Elasticsearch
相关概念:
Elasticsearch是一个分布式全文搜索引擎。(分布式:架构可以做成分布式的)
要想做全文搜索:
1.通过所提供的数据进行分词,将关联数据保存起来。就有了一个一个的id对应一个一个的简要数据。
2.分词查出来先匹配一个一个的id,id再得到数据。(实际上查询的时候,是将输入这个id的数据展示出来)。
这种方式大幅度的提高了查询速度。
传统的索引:根据id查数据。
ES的索引(倒排索引):根据关键字(数据)查id,再根据id查数据。
一条:关键字—>1—>数据 对应的是一个文档,每一条都需要提前建立起来。当使用关键字后,就能找到对应的数据了。
基础操作:
打开ES服务:双击这个批处理文件:
启动后,可以在浏览器直接创建。
创建/查询/删除索引:
PUT:http://localhost:9200/books
GET:http://localhost:9200/books
DELETE:http://localhost:9200/books
目前创建的这个索引是不支持分词的。要支持分词添加IK插件。再重启服务。
创建一个有分词功能的索引:
查看这个索引:
ES文档操作:
添加一条文档,相当于给数据库中添加一条数据,不需要指定表结构。文档结构是无模式的。
使用_doc添加一个文档信息,id是自动生成的。
使用_create添加文档信息,后面需要加id号。
_doc后也可以加id号。
查询文档:查询id为1的文档
查询所有文档:
使用条件查询:
删除文档:
删除一个已经存在的:
删除一个不存在的:
修改一个文档:
查询一下刚才修改的文档,发现只有name,是全覆盖。
如果不想全部修改,只想修改某一条属性信息:使用文档属性进行修改的。就不会覆盖其他的属性。
再次查询一下,只有修改的变了。
ElasticSearch(ES)总结:
创建文档:有三种方式。
POST http://localhost:9200/books/_doc #使用系统生成id
POST http://localhost:9200/books/_create/1 #使用指定id
POST http://localhost:9200/books/_doc/1 #使用指定id,不存在创建,存在更新(版本递增)
查询文档:
GET http://localhost:9200/books/_doc/1 #查询单个文档
GET http://localhost:9200/books/_search #查询全部文档
条件查询:
GET http://localhost:9200/books/_search?q=name:springboot
删除文档:
DELETE http://localhost:9200/books/_doc/1
修改文档(全量修改)
PUT http://localhost:9200/books/_doc/1
修改文档(部分修改):对文档中的某个属性,不是对整个文档进行操作(其余都是对一整个文档进行操作的)。
POST http://localhost:9200/books/_update/1
SpringBoot整合ES客户端:
直接整合高级别的客户端:
先导入starter
<dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>
再写配置文件:配置文件不用写,采用的是硬编码的方式。
在SpringBoot里创建ES客户端:
@Testvoid testCreateIndex() throws IOException {//创建客户端HttpHost host=HttpHost.create("http://localhost:9200");RestClientBuilder builder=RestClient.builder(host);client= new RestHighLevelClient(builder);//使用客户端发送了一个请求,创建了一个名称为books的索引CreateIndexRequest request=new CreateIndexRequest("books");client.indices().create(request, RequestOptions.DEFAULT);//关闭客户端client.close();}
在SpringBoot中创建索引:
@Testvoid testCreateIndexByIk() throws IOException {//创建客户端HttpHost host=HttpHost.create("http://localhost:9200");RestClientBuilder builder=RestClient.builder(host);client= new RestHighLevelClient(builder);//使用客户端发送了一个请求,创建了一个名称为books的索引CreateIndexRequest request=new CreateIndexRequest("books");String json="{\n" +" \"mappings\":{\n" +" \"properties\":{\n" +" \"id\":{\n" +" \"type\":\"keyword\"\n" +" },\n" +" \"name\":{\n" +" \"type\":\"text\",\n" +" \"analyzer\":\"ik_max_word\",\n" +" \"copy_to\":\"all\"\n" +" },\n" +" \"type\":{\n" +" \"type\":\"keyword\"\n" +" },\n" +" \"description\":{\n" +" \"type\":\"text\",\n" +" \"analyzer\":\"ik_max_word\",\n" +" \"copy_to\":\"all\"\n" +" },\n" +" \"all\":{\n" +" \"type\":\"text\",\n" +" \"analyzer\":\"ik_max_word\"\n" +" }\n" +" }\n" +" }\n" +"}";//设置请求中的参数request.source(json, XContentType.JSON);client.indices().create(request, RequestOptions.DEFAULT);//关闭客户端client.close();}
添加单个文档:
//添加文档@Testvoid testCreateDoc() throws IOException {//创建客户端HttpHost host=HttpHost.create("http://localhost:9200");RestClientBuilder builder=RestClient.builder(host);client= new RestHighLevelClient(builder);Book book = bookDao.selectById(1);IndexRequest request=new IndexRequest("books").id(book.getId().toString());String json= JSON.toJSONString(book);request.source(json,XContentType.JSON);client.index(request,RequestOptions.DEFAULT);//关闭客户端client.close();}
添加多个文档:
//添加全部文档@Testvoid testCreateDocAll() throws IOException {//创建客户端HttpHost host=HttpHost.create("http://localhost:9200");RestClientBuilder builder=RestClient.builder(host);client= new RestHighLevelClient(builder);//把所有东西都查出来,造一个批处理请求的容器List<Book> bookList = bookDao.selectList(null);BulkRequest bulk=new BulkRequest();for (Book book : bookList) {IndexRequest request=new IndexRequest("books").id(book.getId().toString());String json= JSON.toJSONString(book);request.source(json,XContentType.JSON);bulk.add(request);}client.bulk(bulk,RequestOptions.DEFAULT);//关闭客户端client.close();}
查询文档:
//按id查询@Testvoid testGet() throws IOException {//创建客户端HttpHost host=HttpHost.create("http://localhost:9200");RestClientBuilder builder=RestClient.builder(host);client= new RestHighLevelClient(builder);GetRequest request=new GetRequest("books","1");GetResponse response = client.get(request, RequestOptions.DEFAULT);String json = response.getSourceAsString();System.out.println(json);//关闭客户端client.close();}//按条件查询@Testvoid testSearch() throws IOException {//创建客户端HttpHost host=HttpHost.create("http://localhost:9200");RestClientBuilder builder=RestClient.builder(host);client= new RestHighLevelClient(builder);//查books索引SearchRequest request=new SearchRequest("books");//设置条件 如果还有条件继续往里排就行SearchSourceBuilder builder1=new SearchSourceBuilder();builder1.query(QueryBuilders.termQuery("all","1"));request.source(builder1);SearchResponse response = client.search(request, RequestOptions.DEFAULT);//查询到的结果如何显示出来SearchHits hits = response.getHits();for (SearchHit hit : hits) {String source = hit.getSourceAsString();
// System.out.println(source);Book book = JSON.parseObject(source, Book.class);System.out.println(book);}//关闭客户端client.close();}
相关文章:

SpringBoot开发实用篇2---与数据层技术有关的替换和整合
四、数据层解决方案 1.SQL 现有数据层解决方案技术选型:DruidMyBatis-plusMySQL 数据源:DruidDataSource 持久化技术:MyBatis-plus/MyBatis 数据库:MySql 内置数据源: SpringBoot提供了3种内嵌的数据源对象供开发者选…...
科普ChatGPT
ChatGPT是什么? ChatGPT是一款基于人工智能技术的聊天机器人,可以进行自然语言的交互。它是由OpenAI公司开发的,其名称中的GPT是“Generative Pre-trained Transformer”的缩写,即基于预训练的转换器。ChatGPT使用预训练的神经网络模型来理…...

Spring MVC的核心类和注解
DispatcherServlet DispatcherServlet作用 DispatcherServlet是Spring MVC的核心类,也是Spring MVC的流程控制中心,也称为Spring MVC的前端控制器,它可以拦截客户端的请求。拦截客户端请求之后,DispatcherServlet会根据具体规则…...

Java 创建一个大文件
有时候,我们在对文件进行测试的时候,可能需要创建一个临时的大文件。 那么问题来了,在 Java 中如何创建大文件呢? 问题和解决 有些人想到的办法就是定义一个随机的字符串,然后重复很多次,然后将这个字符…...
董小姐大意了
阅读本文大概需要 1.17 分钟。 董小姐跟孟羽童的事情,想必大家或多或少都听说了。 事情的经过我就不多做赘述了,实际上并不复杂。 董小姐不是善茬,孟年轻做不来事,不能给格力带来价值,那可以归为双方没缘分,…...

Java高并发核心编程—内置锁原理篇
注:本笔记是阅读《Java高并发核心编程卷2》整理的笔记! 导致并发修改的原因 基本概念 synchronized 关键字 方法声明synchronized synchronized 同步块 消费者生产者问题 Java对象结构与内置锁 四种内置锁 偏向锁原理 偏向锁的撤销 偏向锁的膨胀 全局安全…...

opencv文字识别
OpenCV(开源计算机视觉库)是一个用于实现计算机视觉和机器学习的开源库。它包含了许多预先训练的模型和算法,可以帮助开发者快速实现图像处理、对象检测和识别等功能。在文字识别方面,OpenCV也有一些实用的工具和方法。 要在OpenC…...
bool、python集合
目录 1、使用bool判断某一数据类型是否为空 2、Python集合(数组) 1、列表 2、元组 3、集合 4、字典 1、使用bool判断某一数据类型是否为空 如果有某种内容,则几乎所有值都将评估为 True。 除空字符串外,任何字符串均为 Tr…...

从零开始学架构——可扩展架构模式
可扩展架构模式的基本思想和模式 软件系统与硬件和建筑系统最大的差异在于软件是可扩展的,一个硬件生产出来后就不会再进行改变、一个建筑完工后也不会再改变其整体结构 例如,一颗 CPU 生产出来后装到一台 PC 机上,不会再返回工厂进行加工以…...
Day03 01-MySQL数据完整性详解
文章目录 第七章 数据完整性7.1 完整性约束7.2 实体完整性7.2.1 唯一约束7.2.2 主键约束7.2.3 自增约束 7.3 域完整性7.3.1 非空约束7.3.2 默认值约束7.3.3 检查约束 7.4 引用完整性 第七章 数据完整性 7.1 完整性约束 我们已经知道了如何创建数据库、如何创建表、如何在表中…...

DJ 5-4 以太网 Ethernet
目录 一、以太网的物理拓扑结构 二、以太网物理层标准 1、以太网技术:10Base-T 和 100Base-T 2、以太网技术:1000Base 系列 3、曼彻斯特编码* 4、差分曼彻斯特编码机制* 三、以太网链路层控制技术 四、以太网的帧结构 1、前同步码 2、MAC 地址…...

华为OD机试真题 Java 实现【区块链文件转储系统】【2023Q2 200分】
一、题目描述 区块链底层存储是一个链式文件系统,由顺序的N个文件组成,每个文件的大小不一,依次为F1,F2…Fn。 随着时间的推移,所占存储会越来越大。 云平台考虑将区块链按文件转储到廉价的SATA盘,只有连续的区块链…...
Java 实现 二叉树的 后序遍历
1、定义节点类 class Node {int val;Node left;Node right;Node(int val) {this.val val;} }public class BinaryTree {/*** 后序遍历* param root 节点*/public void postorderTraversal(Node root) {if (root ! null) {postorderTraversal(root.left);postorderTraversal(r…...
rk3588安装qt虚拟键盘
qt是默认安装的,版本号为5.12.8,但是没有虚拟键盘模块,项目中需要,就采用源码编译的方法执行 下载源码 源码地址为Index of /archive/qt/5.12/5.12.1/submodules,下载后放到3588中解压cd到src路径,运行一下命令 …...

HCIP-RIP双向重发布综合实验
拓扑结构: 要求: 1、两个协议间进行多点双向重发布 2、R7的环回没有宣告在OSPF协议中,而是在后期重发布进入的 3、解决环路,所有路径选择最优,且存在备份 4、R2的环回要在RIP中宣告,R3的环回要在OSPF中宣…...
Flask的使用例子
以下是一个简单的使用Flask创建Web应用程序的示例: from flask import Flask, render_template, requestapp Flask(__name__)app.route(/) def home():return Hello, World!app.route(/about) def about():return render_template(about.html)app.route(/submit, …...

【基础6】存储过程的 创建与调用
目录 什么是存储过程 用户自定义存储过程 练习 什么是存储过程 什么是存储过程 类似于C语言中的函数。用来执行管理任务或应用复杂的业务规则存储过程可以带参数,也可以返回结果存储过程可以包含数据操纵等语句、变量、逻辑控制语句等。(单个select语…...

如何快速实现接口自动化测试,常规接口断言封装实践
目录 前言: 一、框架设计思路 1. 封装请求方法 2. 断言封装 3. 接口封装 4. 接口统一管理 二、框架使用 三、总结 前言: 在当今互联网行业中,接口自动化测试已经成为了非常重要的测试手段之一。而在这个过程中,接口自动化…...

java+nodejs+vue+python+php家教信息管理系统
任何网友都可以自由地查看、搜索、发布该家教信息平台的信息。该平台是区别于传统的家教中介的服务平台。学生可以免费查看网站上的家教信息,挑选适合自己的家教;教师可以免费查看网站上的需求信息,挑选适合自己的学生;学生可以发…...

课程分享:鸿蒙HarmonyOS系统及物联网开发实战课程(附课程视频及源码下载)
课程名称: 鸿蒙HarmonyOS系统及物联网开发实战课程 课程介绍: HarmonyOS 是一款面向万物互联时代的、全新的分布式操作系统。在传统的单设备系统能力基础上,HarmonyOS 提出了基于同一套系统能力、适配多种终端形态的分布式理念,…...

XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...

MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...