文章目录
- 🌞 Sun Frame:SpringBoot 的轻量级开发框架(个人开源项目推荐)
- 🌟 亮点功能
- 📦 spring cloud模块概览
- 常用工具
- 🔗 更多信息
- 1.创建ES的索引和映射
- 1.创建索引
- 2.创建映射
- 2.sun-club-infra 编写同步到ES的Service
- 1.EsSubjectFields.java Es的字段映射常量类
- 2.SubjectInfoEs.java Java中的映射实体类
- 3.SubjectEsService.java
- 4.SubjectEsServiceImpl.java
- 3.添加题目时调用接口,同步到ES
- 1.sun-club-common引入雪花Id工具类IdWorkerUtil.java
- 2.sun-club-domain 修改SubjectInfoDomainServiceImpl.java的添加题目逻辑
🌞 Sun Frame:SpringBoot 的轻量级开发框架(个人开源项目推荐)
轻松高效的现代化开发体验
Sun Frame 是我个人开源的一款基于 SpringBoot 的轻量级框架,专为中小型企业设计。它提供了一种快速、简单且易于扩展的开发方式。
我们的开发文档记录了整个项目从0到1的任何细节,实属不易,请给我们一个Star!🌟
您的支持是我们持续改进的动力。
您的支持是我们持续改进的动力。
🌟 亮点功能
- 组件化开发:灵活选择,简化流程。
- 高性能:通过异步日志和 Redis 缓存提升性能。
- 易扩展:支持多种数据库和消息队列。
📦 spring cloud模块概览
- Nacos 服务:高效的服务注册与发现。
- Feign 远程调用:简化服务间通信。
- 强大网关:路由与限流。
常用工具
- 日志管理:异步处理与链路追踪。
- Redis 集成:支持分布式锁与缓存。
- Swagger 文档:便捷的 API 入口。
- 测试支持:SpringBoot-Test 集成。
- EasyCode:自定义EasyCode模板引擎,一键生成CRUD。
🔗 更多信息
- 开源地址:Gitee Sun Frame
- 详细文档:语雀文档
1.创建ES的索引和映射
1.创建索引
2.创建映射
2.sun-club-infra 编写同步到ES的Service
1.EsSubjectFields.java Es的字段映射常量类
package com.sunxiansheng.subject.infra.basic.entity;
/**
* Description: 与ES关联的字段的常量类
* @Author sun
* @Create 2024/6/19 14:55
* @Version 1.0
*/
public class EsSubjectFields {
public static final String DOC_ID = "doc_id";
public static final String SUBJECT_ID = "subject_id";
public static final String SUBJECT_NAME = "subject_name";
public static final String SUBJECT_ANSWER = "subject_answer";
public static final String SUBJECT_TYPE = "subject_type";
public static final String CREATE_USER = "create_user";
public static final String CREATE_TIME = "create_time";
// 请求字段数组
public static final String[] FIELD_QUERY = {
SUBJECT_ID, SUBJECT_NAME, SUBJECT_ANSWER, SUBJECT_TYPE, DOC_ID, CREATE_USER, CREATE_TIME
};
}
2.SubjectInfoEs.java Java中的映射实体类
package com.sunxiansheng.subject.infra.basic.entity;
import com.sunxiansheng.subject.common.eneity.PageInfo;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* Description: ES题目实体类
* @Author sun
* @Create 2024/6/19 14:47
* @Version 1.0
*/
@Data
public class SubjectInfoEs extends PageInfo implements Serializable {
private Long subjectId;
private Long docId;
private String subjectName;
private String subjectAnswer;
private String createUser;
private Long createTime;
private Integer subjectType;
private String keyWord;
private BigDecimal score;
}
3.SubjectEsService.java
package com.sunxiansheng.subject.infra.basic.service;
import com.sunxiansheng.subject.common.eneity.PageResult;
import com.sunxiansheng.subject.infra.basic.entity.SubjectInfoEs;
/**
* Description:题目ES接口
* @Author sun
* @Create 2024/6/19 15:06
* @Version 1.0
*/
public interface SubjectEsService {
/**
* 插入一条记录
* @param subjectInfoEs
* @return
*/
boolean insert(SubjectInfoEs subjectInfoEs);
/**
* ES分页查询
* @param subjectInfoEs
* @return
*/
PageResult<SubjectInfoEs> querySubjectList(SubjectInfoEs subjectInfoEs);
}
4.SubjectEsServiceImpl.java
package com.sunxiansheng.subject.infra.basic.service.impl;
import com.sunxiansheng.subject.common.eneity.PageResult;
import com.sunxiansheng.subject.infra.basic.entity.EsSubjectFields;
import com.sunxiansheng.subject.infra.basic.entity.SubjectInfoEs;
import com.sunxiansheng.subject.infra.basic.es.EsIndexInfo;
import com.sunxiansheng.subject.infra.basic.es.EsRestClient;
import com.sunxiansheng.subject.infra.basic.es.EsSourceData;
import com.sunxiansheng.subject.infra.basic.service.SubjectEsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
/**
* Description:
* @Author sun
* @Create 2024/6/19 15:10
* @Version 1.0
*/
@Service
@Slf4j
public class SubjectEsServiceImpl implements SubjectEsService {
@Override
public boolean insert(SubjectInfoEs subjectInfoEs) {
// 创建一个es源数据对象,内部包含文档id和数据,使用这个对象将数据插入到es
EsSourceData esSourceData = new EsSourceData();
// 将要插入的信息转换为map,要对应于es的字段名
Map<String, Object> data = convert2EsSourceData(subjectInfoEs);
// 将信息放到es数据源对象
esSourceData.setDocId(subjectInfoEs.getDocId().toString());
esSourceData.setData(data);
// 插入,根据集群名、索引名、源数据插入
return EsRestClient.insertDoc(getEsIndexInfo(), esSourceData);
}
/**
* 将SubjectInfoEs转换为Map<String, Object>
* @param subjectInfoEs
* @return
*/
private Map<String, Object> convert2EsSourceData(SubjectInfoEs subjectInfoEs) {
Long subjectId = subjectInfoEs.getSubjectId();
Long docId = subjectInfoEs.getDocId();
String subjectName = subjectInfoEs.getSubjectName();
String subjectAnswer = subjectInfoEs.getSubjectAnswer();
String createUser = subjectInfoEs.getCreateUser();
Long createTime = subjectInfoEs.getCreateTime();
// 创建一个map,将数据放入map,注意这里的key要和es的字段名一致
Map<String, Object> esSourceData = new HashMap<>();
esSourceData.put(EsSubjectFields.SUBJECT_ID, subjectId);
esSourceData.put(EsSubjectFields.DOC_ID, docId);
esSourceData.put(EsSubjectFields.SUBJECT_NAME, subjectName);
esSourceData.put(EsSubjectFields.SUBJECT_ANSWER, subjectAnswer);
esSourceData.put(EsSubjectFields.CREATE_USER, createUser);
esSourceData.put(EsSubjectFields.CREATE_TIME, createTime);
return esSourceData;
}
/**
* 获取集群名和索引名
* @return
*/
private EsIndexInfo getEsIndexInfo() {
EsIndexInfo esIndexInfo = new EsIndexInfo();
// 设置索引
esIndexInfo.setIndexName("subject_index");
// 设置集群名
esIndexInfo.setClusterName("98bd89b5ccaf");
return esIndexInfo;
}
@Override
public PageResult<SubjectInfoEs> querySubjectList(SubjectInfoEs subjectInfoEs) {
return null;
}
}
3.添加题目时调用接口,同步到ES
1.sun-club-common引入雪花Id工具类IdWorkerUtil.java
package com.sunxiansheng.subject.common.util;
public class IdWorkerUtil {
private long workerId;
private long datacenterId;
private long sequence;
private long twepoch = 1585644268888L;
private long workerIdBits = 5L;
private long datacenterIdBits = 5L;
private long sequenceBits = 12L;
private long maxWorkerId = -1L ^ (-1L << workerIdBits);
private long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
private long workerIdShift = sequenceBits;
private long datacenterIdShift = sequenceBits + workerIdBits;
private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
private long sequenceMask = -1L ^ (-1L << sequenceBits);
private long lastTimestamp = -1L;
public long getWorkerId() {
return workerId;
}
public long getDatacenterId() {
return datacenterId;
}
public long getTimestamp() {
return System.currentTimeMillis();
}
public IdWorkerUtil(long workerId, long datacenterId, long sequence) {
if (workerId > maxWorkerId || workerId < 0) {
throw new IllegalArgumentException(
String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
}
if (datacenterId > maxDatacenterId || datacenterId < 0) {
throw new IllegalArgumentException(
String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
}
this.workerId = workerId;
this.datacenterId = datacenterId;
this.sequence = sequence;
}
public synchronized long nextId() {
long timestamp = timeGen();
if (timestamp < lastTimestamp) {
System.err.printf(
"clock is moving backwards. Rejecting requests until %d.", lastTimestamp);
throw new RuntimeException(
String.format("Clock moved backwards. Refusing to generate id for %d milliseconds",
lastTimestamp - timestamp));
}
if (lastTimestamp == timestamp) {
sequence = (sequence + 1) & sequenceMask;
if (sequence == 0) {
timestamp = tilNextMillis(lastTimestamp);
}
} else {
sequence = 0;
}
lastTimestamp = timestamp;
return ((timestamp - twepoch) << timestampLeftShift) |
(datacenterId << datacenterIdShift) |
(workerId << workerIdShift) | sequence;
}
private long tilNextMillis(long lastTimestamp) {
long timestamp = timeGen();
while (timestamp <= lastTimestamp) {
timestamp = timeGen();
}
return timestamp;
}
//获取当前时间戳
private long timeGen() {
return System.currentTimeMillis();
}
}