前言:MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。支持的数据结构非常松散,是类似 json 的 bjson 格式,因此可以存储比较复杂的数据类型。其语法对面向对象语言比较友好,及其适用于java编程。
适用场景:
1,大量且无强关系型数据。--比如日志,缓存等
2,高频读写操作又对事务强制性要求较低。--比如实验性数据,测试数据等
3,轻查询重显示数据。比如可介于redis和mysql之间的做视图应用
环境:
springboot版本:2.2.5.RELEASE
mongodb版本:4.4.0 安装传送门
一、 配置
spring Boot 对mongodb进行了封装,配置很简单。
pom文件中引入jar:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
bootstrap.yml(application.properties)中引入配置
spring:
data:
mongodb:
uri: mongodb://name:pwd@localhost:27017/dataname
//多个 IP 集群可以采用以下配置:
//spring.data.mongodb.uri=mongodb://user:pwd@ip1:port1,ip2:port2/database
二、spring boot中应用
2.1 数据实体(po)--比如日志统计类
@Document(collection = "tk_log")
public class TkLogMg {
@Id
private String id;
private String logType;
private String logName;
private JSONObject tjJson;
private Date beginTime;
private Date endTime;
@Transient
private String diffTime;
//getter、setter省略
}
常用注释说明:
@Document | 标注在实体类上,标明由mongodb来维护该表。 |
@Id | 主键,不可重复,自带索引,需要自己生成并维护不重复的约束。 |
@Indexed | 索引,加索引后以该字段为条件检索将大大提高速度。 |
@Field | 定义存储字段名。可以不加,不加的话默认以参数名为列名。 |
@Transient | 被该注解标注的,将不会被录入到数据库中。只作为普通的javaBean属性。 |
@DBRef | 设置对象的关联。类似于关系型数据库的外键 |
2.2 创建dao层--MongoRepository包含了丰富的数据操作
public interface TkLogMgDao extends MongoRepository<TkLogMg, String>{
Page<TkLogMg> findByLogType(String logType,Pageable pageable);
List<TkLogMg> findByBeginTimeLessThan(Date beginTime);
}
MongoRepository有以下常用方法:
count()统计总数
count(Example< S > example)条件统计总数
delete(T entities)通过对象信息删除某条数据
deleteById(ID id)通过id删除某条数据
deleteALL(Iterable<? extends T> entities)批量删除某条数据
deleteAll() 清空表中所有的数据
existsById(ID id) 判断数据是否存在
exists(Example< T > example) 判断某特定数据是否存在
findAll() 获取表中所有的数据
findAll(Sort sort) 获取表中所有的数据,按照某特定字段排序
findAll(Pageable pageAble) 获取表中所有的数据,分页查询
findAll(Example< T > example) 条件查询
findAll(Iterable ids) 条件查询
findAll(Example< T > example,Pageable pageable) 条件分页查询
findAll(Example< T > example,Sort sort) 条件查询排序
findOneById(ID id) 通过id查询一条数据
findOne(Example example) 通过条件查询一条数据
也支持mongodb源生语句---不建议使用,可读性差,如果数据的curd达到一定的复杂度,客观上已经不建议使用此技术。
GreaterThan(大于)
findByAgeGreaterThan(int age)
{"age" : {"$gt" : age}}
LessThan(小于)
findByAgeLessThan(int age)
{"age" : {"$lt" : age}}
Between(在...之间)
findByAgeBetween(int from, int to)
{"age" : {"$gt" : from, "$lt" : to}}
IsNotNull, NotNull(是否非空)
findByFirstnameNotNull()
{"age" : {"$ne" : null}}
IsNull, Null(是否为空)
findByFirstnameNull()
{"age" : null}
Like(模糊查询)
findByFirstnameLike(String name)
{"age" : age} ( age as regex)
(No keyword) findByFirstname(String name)
{"age" : name}
Not(不包含)
findByFirstnameNot(String name)
{"age" : {"$ne" : name}}
Near(查询地理位置相近的)
findByLocationNear(Point point)
{"location" : {"$near" : [x,y]}}
Within(在地理位置范围内的)
findByLocationWithin(Circle circle)
{"location" : {"$within" : {"$center" : [ [x, y], distance]}}}
Within(在地理位置范围内的)
findByLocationWithin(Box box)
{"location" : {"$within" : {"$box" : [ [x1, y1], x2, y2]}}}
附上更多方法:
2.3 service中使用--主要注意除了对MongoRepository的操作外,某些场景亦可使用MongoTemplate。
@Service
public class TkLogMgService {
//1,无事务约束
//2,save包含插入和修改,无id为插入,有id为覆盖修改
public void save(TkLogMg mg) {
tkLogMgDao.save(mg);
}
//查询单个
public TkLogMg getById(String id) {
Optional<TkLogMg> optional = tkLogMgDao.findById(id);
if (optional.isPresent()) {
return optional.get();
} else {
return null;
}
}
//使用MongoRepository分页查询
public Page<TkLogMg> page(Integer currPage, Integer pageSize, TkLogMg queryMg) {
Sort sort = Sort.by(Sort.Direction.DESC, "num");
PageRequest pageRequest = PageRequest.of(currPage - 1, pageSize, sort);
TkLogMg mrMg = new TkLogMg();
BeanUtils.copyProperties(queryMg, mrMg);
ExampleMatcher matcher = ExampleMatcher.matching().withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) // 改变默认字符串匹配方式:模糊查询
.withIgnoreCase(true) // 改变默认大小写忽略方式:忽略大小写
.withMatcher("lot", ExampleMatcher.GenericPropertyMatchers.contains()) // 采用“包含匹配”的方式查询
.withMatcher("num", ExampleMatcher.GenericPropertyMatchers.contains());
Example<TkLogMg> example = Example.of(mrMg, matcher);
Page<TkLogMg> all = matchRecomMgDao.findAll(example, pageRequest);
return all;
}
//使用mongoTemplate查询列表
public List<TkLogMg> loadLoseRecom(Date begin, String lot) {
Query query = new Query();
query.addCriteria(Criteria.where("bgTime").lt(begin).and("lot").is(lot));
return mongoTemplate.find(query, TkLogMg.class);
}
@Autowired
private TkLogMgDao tkLogMgDao;
@Autowired
private MongoTemplate mongoTemplate;
}
注意:mongodb整体上对查询的支持并不好,此处只距离说明MongoRepository和mongoTemplate的使用,更多的应用,单独写一篇。
三、数据输出处理
3.1 在action层的操作跟正常的数据操作无疑,这里不过多赘述。
3.2 主要说下关于分页操作的情况。
action中:
@Autowired
private TkLogMgService tkLogMgService;
@GetMapping("/showPage.html")
public String recordPage(Integer curPage, String ln, String sid, ModelMap model) {
curPage = curPage == null ? 1 : curPage;
int pageSize = 15;
TkLogMg queryMg = new TkLogMg();
Page<TkLogMg > recordMgPage = tkLogMgService .page(curPage, pageSize, queryMg);
PageQuery<TkLogMg> recordPage = new PageQuery<TkLogMg>(recordMgPage.getNumber(), "",
recordMgPage.getTotalElements(), pageSize);
model.addAttribute("recordPage", recordPage);
return "/front/log/showPage";
}
主要是对page对象的转化,由org.springframework.data.domain.Page转为org.beetl.sql.core.engine.PageQuery(此类为beetle中的分页类,亦可自定义分页类),目的是为了使前台分页得到统一。
自定义分页类如下:
import java.io.Serializable;
import java.util.List;
public class PageBo<T> implements Serializable{
private static final long serialVersionUID = -3948389268046368059L;
protected List<T> list; //分页结果List
protected int pageNumber; //页数
protected int totalPage; //总页数
protected int pageSize=15;
protected long totalRow;
public PageBo(){
}
public PageBo(List<T> list,Integer pageNumber,int totalPage,long totalRow){
this.list=list;
this.pageNumber=pageNumber;
this.totalPage=totalPage;
this.totalRow=totalRow;
}
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
public int getPageNumber() {
return pageNumber;
}
public void setPageNumber(int pageNumber) {
this.pageNumber = pageNumber;
}
public int getTotalPage() {
return totalPage;
}
public long getTotalRow() {
return totalRow;
}
public int getPageSize() {
return pageSize;
}
}
3.3 页面中的使用和常规使用一样即可。
本文暂时没有评论,来添加一个吧(●'◡'●)