欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > 校园选课助手【5】-解决Elasticsearch和MySQL同步

校园选课助手【5】-解决Elasticsearch和MySQL同步

2025/5/11 18:08:26 来源:https://blog.csdn.net/qq_43954910/article/details/140879352  浏览:    关键词:校园选课助手【5】-解决Elasticsearch和MySQL同步

未优化前:课程检索库中的数据经过一次同步后固定不变,用户搜索到对应的课程后点击跳转到课程详情页面,进行选课

存在的问题:

  1. 用户使用不友好,搜索就是为了进行选课,应该返回对应课程的余量,如果没有余量了,进行友好提示,如果有余量,跳转到详情页面进行选课。
  2. 数据不一致,可能修改了课程信息,而检索库中的数据依旧没有更新。

解决方案:
引入消息队列,当CourseController将数据写入mysql后,需要自己再往MQ发条消息,说"数据更新了",EsController收到消息去更新索引库。

1.声明队列和交换机

@Configuration
public class MqConfig {//交换机名称public static final String EXCHANGE_NAME = "course.topic";//新增和修改队列public static final String INSERT_QUEUE_NAME = "course.insert.queue";//删除队列public static final String DELETE_QUEUE_NAME = "course.delete.queue";//RoutingKeypublic static final String INSERT_KEY = "course.insert";public static final String DELETE_KEY = "course.delete";@Beanpublic TopicExchange topicExchange(){return new TopicExchange(EXCHANGE_NAME,true,false);}@Beanpublic Queue insertQueue(){return new Queue(INSERT_QUEUE_NAME,true);}@Beanpublic Queue deleteQueue(){return new Queue(DELETE_QUEUE_NAME,true);}/*** 绑定队列和交换机关系*/@Beanpublic Binding insertQueueBinding(){return BindingBuilder.bind(insertQueue()).to(topicExchange()).with(INSERT_KEY);}@Beanpublic Binding deleteQueueBinding(){return BindingBuilder.bind(deleteQueue()).to(topicExchange()).with(DELETE_KEY);}

2.发送消息

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.security.InvalidParameterException;@RestController
@RequestMapping("Course")
public class courseController {@Autowiredprivate ICourseService courseService;@Autowiredprivate RabbitTemplate rabbitTemplate;@PostMappingpublic void saveCourse(@RequestBody Course course){courseService.save(course);rabbitTemplate.convertAndSend("course.topic","course.insert", course.getId());}@PutMapping()public void updateById(@RequestBody course course){if (course.getId() == null) {throw new InvalidParameterException("id不能为空");}courseService.updateById(course);// 发送MQ消息rabbitTemplate.convertAndSend("course.topic","course.insert", course.getId());}@DeleteMapping("/{id}")public void deleteById(@PathVariable("id") Long id) {courseService.removeById(id);// 发送MQ消息rabbitTemplate.convertAndSend("course.topic", "course.delete", id);}   
}

3.监听消息队列并进行处理


import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;import javax.annotation.Resource;@Component
public class CourseListener {@ResourceICourselService courseService;/*** 监听课程新增或者修改的业务* id接受一个Long,因为发送过来的是一个Long id*/@RabbitListener(queues = "course.insert.queue“)public void listenCourseInsertAndUpdate(Long id){CourseService.insertDocById(id);}/*** 监听课程删除业务*/@RabbitListener(queues = "course.delete.queue“)public void listenCourseDelete(Long id){CourseService.deleteDocById(id);}
}

4.实现上述service功能

新增或修改课程逻辑

  • 1)根据id查询课程数据Item
  • 2)将Item封装为ItemDoc
  • 3)将ItemDoc序列化为JSON
  • 4)创建IndexRequest,指定索引库名和id
  • 5)准备请求参数,也就是JSON文档
  • 6)发送请求

删除课程逻辑

  • 1)准备Request对象,因为是删除,这次是DeleteRequest对象。要指定索引库名和id
  • 3)发送请求。因为是删除,所以是client.delete()方法
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.io.IOException;@Service
public class CourseService extends ServiceImpl<CourseMapper, Course> implements ICourseService {@ResourceRestHighLevelClient client;@Overridepublic void insertDocById(Long id) {try {//0.根据ID查数据,并转为文档类型Course Course = getById(id);CourseDoc CourseDoc = new CourseDoc(Course);//1.准备requestIndexRequest request = new IndexRequest("Course").id(CourseDoc.getId().toString());//2.准备DSLrequest.source(JSON.toJSONString(CourseDoc), XContentType.JSON);//3.发送请求client.index(request,RequestOptions.DEFAULT);} catch (IOException e) {throw new RuntimeException(e);}}@Overridepublic void deleteDocById(Long id) {try {//1.准备requestDeleteRequest request = new DeleteRequest("Course",id.toString());//2.发送请求client.delete(request,RequestOptions.DEFAULT);} catch (IOException e) {throw new RuntimeException(e);}}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词