实战:五
4.16
实现数据字典
后端接口部分
/**
* 为了实现数据字典,这个方法用来查找对应父id的子id
*
* @param id
* @return
*/
@ApiOperation("根据数据id查询子数据列表")
@GetMapping("findChildData/{id}")
public Result findChildData(@PathVariable Long id) {
List<Dict> childData = dictService.findChildData(id);
return Result.ok(childData);
}
//service层部分。用于判断该数据是否还有子节点,是否还需要继续下沿。
/**
* 根据传进的id,查询parent_id为此id的所有数据。
* @param id
* @return
*/
@Override
public List<Dict> findChildData(Long id) {
QueryWrapper<Dict> dictQueryWrapper = new QueryWrapper<>();
dictQueryWrapper.eq("parent_id",id);
List<Dict> dicts = baseMapper.selectList(dictQueryWrapper);
//list集合中每个数据判断是否还有子节点
for (Dict dict : dicts) {
//根据当前字段的id判断他有没有子节点。
// 没有->false;有->true
dict.setHasChildren(isHasChildren(dict.getId()));
}
return dicts;
}
/**
* 用来判断数据是否有子节点。
* @param id
* @return
* /
private boolean isHasChildren(Long id){
QueryWrapper<Dict> dictQueryWrapper = new QueryWrapper<>();
dictQueryWrapper.eq("parent_id",id);
Integer integer = baseMapper.selectCount(dictQueryWrapper);
return integer>0;
}
前端部分
首先定义router
{
path: '/cmn',
component: Layout,
redirect: '/cmn/list',
name: '数据管理',
meta: { title: '数据管理', icon: 'example' },
alwaysShow:true,//如果只有一个子模块也会单独列出。flase时不会。
children: [
{
path: 'list',
name: '数据字典',
component: () => import('@/views/dict/list'),
meta: { title: '数据字典', icon: 'table' }
},
]
},
在api/index
定义接口信息
import request from '@/utils/request'
export default {
//数据列表方法
dictList(id){
return request({
url:`/admin/cmn/dict/findChildData/${id}`,
method:"get",
})
}
}
页面渲染
基于Element-ui完成的页面渲染。
<div>
<el-table
:data="list"
style="width: 100%"
row-key="id"
border
lazy
:load="getChildrens"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
>
<el-table-column label="名称" width="230" align="left">
<template slot-scope="scope">
<span>{{ scope.row.name }}</span>
</template>
</el-table-column>
<el-table-column label="编码" width="220">
<template slot-scope="{ row }">
{{ row.dictCode }}
</template>
</el-table-column>
<el-table-column label="值" width="230" align="left">
<template slot-scope="scope">
<span>{{ scope.row.value }}</span>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center">
<template slot-scope="scope">
<span>{{ scope.row.createTime }}</span>
</template>
</el-table-column>
</el-table>
</div>
methods: {
getDictList: function (id) {
dict.dictList(id).then((response) => {
this.list = response.data;
});
},
getChildrens:function(tree, treeNode, resolve) {
dict.dictList(tree.id).then((response) => {
resolve(response.data);
});
},
},
//生命周期 - 创建完成(可以访问当前this实例)
created() {
this.getDictList(1);
},
EasyExcel
Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。easyexcel重写了poi对07版Excel的解析,能够原本一个3M的excel用POI sax依然需要100M左右内存降低到几M,并且再大的excel不会出现内存溢出,03版依赖POI的sax模式。在上层做了模型转换的封装,让使用者更加简单方便。
EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。
-
引入依赖
<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel --> <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.1.1</version> </dependency>
-
需要一个实体类
@Data //不能存在有参构造方法,不会读取时会报错。 public class UserData { @ExcelProperty(value = "用户编号",index = 0) private int uid; @ExcelProperty(value = "用户名称",index = 1) private String uname; }
-
写操作逻辑
public static void main(String[] args) { //设置文件地址和文件名 String filename="G:\\excel\\01.xlsx"; //构建一个数据的list集合 ArrayList<UserData> userData = new ArrayList<UserData>(); for (int i = 0; i < 10; i++) { UserData userData1 = new UserData(i, "hello" + i); userData.add(userData1); } //需要指定地址,数据类型,表别名,数据。 EasyExcel.write(filename,UserData.class).sheet("用户信息") .doWrite(userData); }
-
读操作逻辑
需要一个监督类
public class ExcelListen extends AnalysisEventListener<UserData> { /** * 一行一行读取内容 */ @Override public void invoke(UserData userData, AnalysisContext analysisContext) { System.out.println(userData); } public void invokeHead(Map<Integer, CellData> headMap, AnalysisContext context) { System.out.println("表头信息:"+headMap); } /** * 读取后执行的方法 * @param analysisContext */ @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { } }
读取的逻辑
public class TestRead { public static void main(String[] args) { //设置读取文件的位置。 String filename = "G:\\excel\\01.xlsx"; //调用方法,参数:文件地址、文件类型、监听器。 EasyExcel.read(filename,UserData.class, new ExcelListen()).sheet().doRead(); } }
上传和下载文件
下载
@Override
public void export(HttpServletResponse response) {
//设置下载的信息
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
String fileName = "dict";
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
//查询数据库
List<Dict> dictList = baseMapper.selectList(null);
ArrayList<DictEeVo> arrayList = new ArrayList();
//将dict的id复制给dicteevo
for (Dict dict : dictList) {
DictEeVo dictEeVo = new DictEeVo();
BeanUtils.copyProperties(dict,dictEeVo);
arrayList.add(dictEeVo);
}
//Excel写
try {
EasyExcel.write(response.getOutputStream(), DictEeVo.class)
.sheet("dict")
.doWrite(arrayList);
} catch (IOException e) {
e.printStackTrace();
}
}
上传
//controller
/**
* 用于向服务器端提交内容
*/
@ApiOperation("上传数据字典")
@PostMapping("importData")
public Result importData(MultipartFile file) {//通过MultipartFile来接收文件
dictService.importData(file);
return Result.ok();
}
//service
/**
* 将上传的excel写入数据库
* @param file
*/
@Override
public void importData(MultipartFile file) {
try {
//使用EasyExcel的read方法一行一行的读
EasyExcel.read(file.getInputStream(),DictEeVo.class,new DictListener(baseMapper)).sheet().doRead();
} catch (IOException e) {
e.printStackTrace();
}
}
//监听器
public class DictListener extends AnalysisEventListener<DictEeVo> {
private DictMapper dictMapper;
public DictListener(DictMapper dictMapper) {
this.dictMapper = dictMapper;
}
@Override
public void invoke(DictEeVo dictEeVo, AnalysisContext analysisContext) {
//将DictEeVo转换为Dict对象
Dict dict = new Dict();
BeanUtils.copyProperties(dictEeVo,dict);
//调用数据库方法
dictMapper.insert(dict);
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
}
}
前端
<div class="el-toolbar">
<div class="el-toolbar-body" style="justify-content: flex-start">
<el-button type="text" @click="exportData"
><i class="fa fa-plus" /> 导出</el-button
>
<el-button type="text" @click="importData"
><i class="fa fa-plus" /> 导入</el-button
>
</div>
<el-dialog title="导入" :visible.sync="dialogImportVisible" width="480px">
<el-form label-position="right" label-width="170px">
<el-form-item label="文件">
<el-upload
:multiple="false"
:on-success="onUploadSuccess"
:action="'http://localhost:8202/admin/cmn/dict/importData'"
class="upload-demo"
>
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">
只能上传exls文件,且不超过500kb
</div>
</el-upload>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogImportVisible = false"> 取消 </el-button>
</div>
</el-dialog>
//上传文件(导入数据)的方法
importData: function () {
this.dialogImportVisible=true;
},
//上传成功的方法
onUploadSuccess:function(){
//关闭弹框
this.dialogImportVisible=false;
//刷新页面
this.getDictList(1);
}
为数据字典添加缓存
Spring Cache 是一个非常优秀的缓存组件。自Spring 3.1起,提供了类似于@Transactional注解事务的注解Cache支持,且提供了Cache抽象,方便切换各种底层Cache(如:redis)
-
导入依赖
<!-- redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- spring2.X集成redis所需common-pool2--> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.6.0</version> </dependency>
-
编写配置类
@Configuration @EnableCaching public class RedisConfig { /** * 自定义key规则 * * @return */ @Bean public KeyGenerator keyGenerator() { return (target, method, params) -> { StringBuilder sb = new StringBuilder(); sb.append(target.getClass().getName()); sb.append(method.getName()); for (Object obj : params) { sb.append(obj.toString()); } return sb.toString(); }; } /** * 设置RedisTemplate规则 * * @param redisConnectionFactory * @return */ @Bean public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); //解决查询缓存转换异常的问题 ObjectMapper om = new ObjectMapper(); // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常 om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); //序列号key value redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; } /** * 设置CacheManager缓存规则 * * @param factory * @return */ @Bean public CacheManager cacheManager(RedisConnectionFactory factory) { RedisSerializer<String> redisSerializer = new StringRedisSerializer(); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); //解决查询缓存转换异常的问题 ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); // 配置序列化(解决乱码的问题),过期时间600秒 RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofSeconds(600)) .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)) .disableCachingNullValues(); RedisCacheManager cacheManager = RedisCacheManager.builder(factory) .cacheDefaults(config) .build(); return cacheManager; } }
-
使用Spring Cache的注解完成缓存
注解名 描述 参数 @Cacheable 根据方法对其返回结果进行缓存,下次请求时,如果缓存存在,则直接读取缓存数据返回;如果缓存不存在,则执行方法,并把返回的结果存入缓存中。一般用在查询方法上。 value:缓存名,必填,它指定了你的缓存存放在哪块命名空间。cacheNames:与 value 差不多,二选一即可。key:可选属性,可以使用 SpEL 标签自定义缓存的key 。 @CachePut 使用该注解标志的方法,每次都会执行,并将结果存入指定的缓存中。其他方法可以直接从响应的缓存中读取缓存数据,而不需要再去查询数据库。一般用在新增方法上。 value:缓存名,必填,它指定了你的缓存存放在哪块命名空间。cacheNames:与 value 差不多,二选一即可。key:可选属性,可以使用 SpEL 标签自定义缓存的key 。 @CacheEvict 使用该注解标志的方法,会清空指定的缓存。一般用在更新或者删除方法上 value:缓存名,必填,它指定了你的缓存存放在哪块命名空间。cacheNames:与 value 差不多,二选一即可。key:可选属性,可以使用 SpEL 标签自定义缓存的key。allEntries:是否清空所有缓存,默认为 false。如果指定为true,则方法调用后将立即清空所有的缓存。 beforeInvocation:是否在方法执行前就清空,默认为 false。如果指定为 true,则在方法执行前就会清空缓存。 -
修改service层方法
@Override @Cacheable(value = "dict",keyGenerator = "keyGenerator")//添加上此注解。 public List<Dict> findChildData(Long id) { QueryWrapper<Dict> dictQueryWrapper = new QueryWrapper<>(); dictQueryWrapper.eq("parent_id", id); List<Dict> dicts = baseMapper.selectList(dictQueryWrapper); //list集合中每个数据判断是否还有子节点 for (Dict dict : dicts) { //根据当前字段的id判断他有没有子节点。 // 没有->false;有->true dict.setHasChildren(isHasChildren(dict.getId())); } return dicts; }
MongDb
NoSQL(NoSQL = Not Only SQL),意即反SQL运动,指的是非关系型的数据库,是一项全新的数据库革命性运动,早期就有人提出,发展至2009年趋势越发高涨。NoSQL的拥护者们提倡运用非关系型的数据存储,相对于目前铺天盖地的关系型数据库运用,这一概念无疑是一种全新的思维的注入。
为什幺使用NoSQL :
- 对数据库高并发读写。
- 对海量数据的高效率存储和访问。
- 对数据库的高可扩展性和高可用性。
弱点:
- 数据库事务一致性需求
- 数据库的写实时性和读实时性需求
- 对复杂的SQL查询,特别是多表关联查询的需求
什么是MongoDB
MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。
在高负载的情况下,添加更多的节点,可以保证服务器性能。
MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。
安装MongDB
-
拉取镜像
docker pull mongo:latest
-
创建并启动容器
docker run -d --restart=always -p 27017:27017 --name mymongo -v /data/db:/data/db -d mongo
p67
-
4.17
查漏补缺:MongoDB
传统的关系型数据库(如MySQL),在数据操作的“三高”需求以及应对Web2.0的网站需求面前,显得力不从心。
解释:“三高”需求:
-
High performance - 对数据库高并发读写的需求。
-
Huge Storage - 对海量数据的高效率存储和访问的需求。
-
High Scalability && High Availability- 对数据库的高可扩展性和高可用性的需求。
而MongoDB可应对“三高”需求。
具体的应用场景如:
1)社交场景,使用 MongoDB 存储存储用户信息,以及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能。
2)游戏场景,使用 MongoDB 存储游戏用户信息,用户的装备、积分等直接以内嵌文档的形式存储,方便查询、高效率存储和访问。
3)物流场景,使用 MongoDB 存储订单信息,订单状态在运送过程中会不断更新,以 MongoDB 内嵌数组的形式来存储,一次查询就能将
订单所有的变更读取出来。
4)物联网场景,使用 MongoDB 存储所有接入的智能设备信息,以及设备汇报的日志信息,并对这些信息进行多维度的分析。
5)视频直播,使用 MongoDB 存储用户信息、点赞互动信息等。
这些应用场景中,数据操作方面的共同特点是:
(1)数据量大
(2)写入操作频繁(读写都很频繁)
(3)价值较低的数据,对事务性要求不高
对于这样的数据,我们更适合使用MongoDB来实现数据的存储。
什么时候选择MongoDB
-
在架构选型上,除了上述的三个特点外,如果你还犹豫是否要选择它?可以考虑以下的一些问题:
-
应用不需要事务及复杂 join 支持
-
新应用,需求会变,数据模型无法确定,想快速迭代开发
-
应用需要2000-3000以上的读写QPS(更高也可以)
-
应用需要TB甚至 PB 级别数据存储
-
应用发展迅速,需要能快速水平扩展
-
应用要求存储的数据不丢失
-
应用需要99.999%高可用
-
应用需要大量的地理位置查询、文本查询
如果上述有1个符合,可以考虑 MongoDB,2个及以上的符合,选择 MongoDB 绝不会后悔。
MongoDB简介
MongoDB是一个开源、高性能、无模式的文档型数据库,当初的设计就是用于简化开发和方便扩展,是NoSQL数据库产品中的一种。是最像关系型数据库(MySQL)的非关系型数据库。
它支持的数据结构非常松散,是一种类似于 JSON 的 格式叫BSON,所以它既可以存储比较复杂的数据类型,又相当的灵活。
MongoDB中的记录是一个文档,它是一个由字段和值对(fifield:value)组成的数据结构。MongoDB文档类似于JSON对象,即一个文档认为就是一个对象。字段的数据类型是字符型,它的值除了使用基本的一些类型外,还可以包括其他文档、普通数组和文档数组。
MongoDB的特点
(1)高性能:
MongoDB提供高性能的数据持久性。特别是,
对嵌入式数据模型的支持减少了数据库系统上的I/O活动。
索引支持更快的查询,并且可以包含来自嵌入式文档和数组的键。(文本索引解决搜索的需求、TTL索引解决历史数据自动过期的需求、地
理位置索引可用于构建各种 O2O 应用)
mmapv1、wiredtiger、mongorocks(rocksdb)、in-memory 等多引擎支持满足各种场景需求。
Gridfs解决文件存储的需求。
(2)高可用性:
MongoDB的复制工具称为副本集(replica set),它可提供自动故障转移和数据冗余。
(3)高扩展性:
MongoDB提供了水平可扩展性作为其核心功能的一部分。
分片将数据分布在一组集群的机器上。(海量数据存储,服务能力水平扩展)
从3.4开始,MongoDB支持基于片键创建数据区域。在一个平衡的集群中,MongoDB将一个区域所覆盖的读写只定向到该区域内的那些
片。
(4)丰富的查询支持:
MongoDB支持丰富的查询语言,支持读和写操作(CRUD),比如数据聚合、文本搜索和地理空间查询等。
(5)其他特点:如无模式(动态模式)、灵活的文档模型
MongoDB安装
#拉取镜像
docker pull mongo:latest
#创建和启动容器
docker run -d --restart=always -p 27017:27017 --name mymongo -v /data/db:/data/db -d mongo
#进入容器
docker exec -it mymongo /bin/bash
#使用MongoDB客户端进行操作
mongo
MongoDB基本命令
#Help查看命令提示
db.help()
#切换/创建数据库
use test#如果数据库不存在,则创建数据库,否则切换到指定数据库
#查询所有数据库
show dbs;
#删除当前使用数据库
db.dropDatabase();
#查看当前使用的数据库
db.getName();
#显示当前db状态
db.stats();
#当前db版本
db.version();
#查看当前db的链接机器地址
db.getMongo〇;
文档
文档是一组键值(key-value)对(即BSON)。MongoDB 的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型,这与关系型数据库有很大的区别,也是 MongoDB 非常突出的特点。
下表列出了 RDBMS 与 MongoDB 对应的术语:
RDBMS | MongoDB |
---|---|
数据库 | 数据库 |
表格 | 集合 |
行 | 文档 |
列 | 字段 |
表联合 | 嵌入文档 |
主键 | 主键 (MongoDB 提供了 key 为 _id ) |
文档的一些操作
#创建一个集合(table)
db.createCollection( "collName");
#得到指定名称的集合(table )
db.getCollection("user");
MongoDB的CRUD操作
-
INSERT
> db.User.save({name:'zhangsan',age:21,sex:true}) > db.User.find() {"_id": Objectld("4f69e680c9106ee2ec95da66"), "name": "zhangsan", "age": 21, "sex": true}
_id组合
Objectld是、id”的默认类型。Objectld使用12字节的存储空间,每个字节二位十六进制数字, 是一个24位的字符串
![img](file:///C:/Users/Boerk/AppData/Local/Temp/msohtmlclip1/01/clip_image002.jpg)
-
Query
# select * from User where name = 'zhangsan' sql > db.User.find({name:"zhangsan"}) #MongoDB # select name, age from User where age = 21 > db.User.find({age:21}, {'name':1, 'age':1}) #在 MongoDB 中使用 sort() 方法对数据进行排序,sort() 方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用于降序排列。 # select * from User order by age > db.User.find().sort({age:1}) #SUCE #在 MongoDB 中使用 limit()方法来读取指定数量的数据,skip()方法来跳过指定数量的数据 # select * from User skip 2 limit 3 > db.User.find().skip(0).limit(3) # select * from User where age in (21, 26, 32) > db.User.find({age:{$in:[21,26,32]}}) # select count(*) from User where age >20 > db.User.find({age:{$gt:20}}).count() # select * from User where age = 21 or age = 28 > db.User.find({$or:[{age:21}, {age:28}]})
-
Update
# update Userset age = 100, sex = 0 where name = 'user1' > db.User.update({name:"zhangsan"}, {$set:{age:100, sex:0}})
Update()有几个参数需要注意。
db.collection.update(criteria, objNew, upsert, mult)
criteria:需要更新的条件表达式
objNew:更新表达式
upsert:如FI标记录不存在,是否插入新文档。
multi:是否更新多个文档。
-
Remove
#移除对应id的行 > db.User.remove(id) #移除所有 > db.User.remove({})
Springboot整合MongoDB
spring-data-mongodb提供了MongoTemplate与MongoRepository两种方式访问mongodb,MongoRepository操作简单,MongoTemplate操作灵活,我们在项目中可以灵活适用这两种方式操作mongodb,MongoRepository的缺点是不够灵活,MongoTemplate正好可以弥补不足。
-
引入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency>
-
配置MongoDB的地址
spring.data.mongodb.uri=mongodb://ip:27017/test
-
创建对应的实体类
@Data @Document("User") public class User { @Id private String id; private String name; private Integer age; private String email; private String createDate; }
-
添加
/** * 这是对MongoDB进行新增的方法 */ @Test public void add(){ User user = new User(); user.setName("zhangsan"); user.setAge(18); user.setEmail("110120119"); User user1 = mongoTemplate.insert(user); System.out.println(user1); }
-
查询
/** * 这是对MongoDB进行查找的方法 */ @Test public void query() { List<User> all = mongoTemplate.findAll(User.class); System.err.println(all); } /** * 这是根据id对MongoDb的精细查询的方法 */ @Test public void queryById(){ User user = mongoTemplate.findById("625c1bbaa2f93370884eafeb", User.class); System.out.println(user); }
//条件查询 /** * 这是根据条件查询的方法 */ @Test public void queryUserList() { //name=zhangsan &age=18 Query query = new Query(Criteria .where("name").is("zhangsan") //name is zhangsan .and("age").is(18) //age is 18 ); mongoTemplate.find(query, User.class); }
//模糊查询 /** * 模糊查询 */ @Test public void queryUserLike(){ //名字中包含zhang String name = "zhang"; //正则表达式的匹配规则 String regex = String.format("%s%s%s", "^.*", name, ".*$"); Pattern pattern = Pattern.compile(regex,Pattern.CASE_INSENSITIVE); //匹配正则 Query query = new Query(Criteria.where("name").regex(pattern)); List<User> users = mongoTemplate.find(query, User.class); System.err.println(users); }
//分页查询 /** * 分页查询 */ @Test public void queryUserLikePage(){ //分页信息 int pageNum=1; int pageSize=3; //名字中包含zhang String name = "zhang"; //正则表达式的匹配规则 String regex = String.format("%s%s%s", "^.*", name, ".*$"); Pattern pattern = Pattern.compile(regex,Pattern.CASE_INSENSITIVE); //匹配正则 Query query = new Query(Criteria.where("name").regex(pattern)); //分页查询 List<User> users = mongoTemplate.find(query.skip((pageNum-1)*pageSize).limit(pageSize), User.class); System.out.println(users); }
-
Upsert
/** * 修改 */ @Test public void update(){ //1.首先查询 User user = mongoTemplate.findById("625c1bbaa2f93370884eafeb", User.class); user.setName("lisi"); //改哪个?查出来! //根据id查找要改的信息 Query query = new Query(Criteria.where("id").is(user.getId())); //怎么改?写出来! Update update = new Update(); update.set("name",user.getName()); UpdateResult upsert = mongoTemplate.upsert(query, update, User.class); long matchedCount = upsert.getMatchedCount(); System.out.println("修改数量:"+matchedCount); }
-
Remove
/** * 删除 */ @Test public void delete(){ Query query = new Query(Criteria.where("id").is("625c1bbaa2f93370884eafeb")); mongoTemplate.remove(query,User.class); }