安能摧眉折腰事权贵,使我不得开心颜
1. 项目介绍及环境配置
2. 短信验证码登录
3. 用户信息
4. MongoDB
通用设置包含:
通用设置:
CREATE TABLE `tb_settings` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) DEFAULT NULL,
`like_notification` tinyint(4) DEFAULT '1' COMMENT '推送喜欢通知',
`pinglun_notification` tinyint(4) DEFAULT '1' COMMENT '推送评论通知',
`gonggao_notification` tinyint(4) DEFAULT '1' COMMENT '推送公告通知',
`created` datetime DEFAULT NULL,
`updated` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='设置表';
陌生人问题:
CREATE TABLE `tb_question` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) DEFAULT NULL COMMENT '用户id',
`txt` varchar(200) DEFAULT NULL COMMENT '问题内容',
`created` datetime DEFAULT NULL,
`updated` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8
黑名单:
CREATE TABLE `tb_black_list` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) DEFAULT NULL,
`black_user_id` bigint(20) DEFAULT NULL,
`created` datetime DEFAULT NULL,
`updated` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='黑名单';
新建 tanhua-model/src/main/java/com/tanhua/model/domain/Settings.java
通用设置 实体类:
/**
* 通知设置
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Settings extends BasePojo {
private Long id;
private Long userId;
private Boolean likeNotification;
private Boolean pinglunNotification;
private Boolean gonggaoNotification;
}
新建 tanhua-model/src/main/java/com/tanhua/model/domain/Question.java
陌生人问题 实体类:
/**
* 陌生人问题
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Question extends BasePojo {
private Long id;
private Long userId;
//问题内容
private String txt;
}
新建 tanhua-model/src/main/java/com/tanhua/model/domain/BlackList.java
黑名单 实体类:
/**
* 黑名单
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class BlackList extends BasePojo {
private Long id;
private Long userId;
private Long blackUserId;
}
新建 tanhua-dubbo/tanhua-dubbo-db/src/main/java/com/tanhua/dubbo/mappers/SettingsMapper.java
通用设置 Mapper接口:
public interface SettingsMapper extends BaseMapper<Settings> {
}
新建 tanhua-dubbo/tanhua-dubbo-db/src/main/java/com/tanhua/dubbo/mappers/QuestionMapper.java
陌生人问题 Mapper接口:
public interface QuestionMapper extends BaseMapper<Question> {
}
新建 tanhua-dubbo/tanhua-dubbo-db/src/main/java/com/tanhua/dubbo/mappers/BlackListMapper.java
黑名单 Mapper接口:
public interface BlackListMapper extends BaseMapper<BlackList> {
}
新建 tanhua-dubbo/tanhua-dubbo-interface/src/main/java/com/tanhua/dubbo/api/SettingsApi.java
通用设置 Api接口:
public interface SettingsApi {
}
新建 tanhua-dubbo/tanhua-dubbo-interface/src/main/java/com/tanhua/dubbo/api/QuestionApi.java
陌生人问题 Api接口:
public interface QuestionApi {
}
新建 tanhua-dubbo/tanhua-dubbo-interface/src/main/java/com/tanhua/dubbo/api/BlackListApi.java
黑名单 Api接口:
public interface BlackListApi {
}
新建 tanhua-dubbo/tanhua-dubbo-db/src/main/java/com/tanhua/dubbo/api/SettingsApiImpl.java
通用设置 Api接口实现类:
@DubboService
public class SettingsApiImpl implements SettingsApi{
@Autowired
private SettingsMapper settingsMapper;
// 根据用户id查询
@Override
public Settings findByUserId(Long userId) {
QueryWrapper<Settings> qw = new QueryWrapper<>();
qw.eq("user_id", userId);
return settingsMapper.selectOne(qw);
}
}
新建 tanhua-dubbo/tanhua-dubbo-db/src/main/java/com/tanhua/dubbo/api/QuestionApiImpl.java
陌生人问题 Api接口实现类:
@DubboService
public class QuestionApiImpl implements QuestionApi{
@Autowired
private QuestionMapper questionMapper;
@Override
public Question findByUserId(Long userId) {
QueryWrapper<Question> qw = new QueryWrapper<>();
qw.eq("user_id", userId);
return questionMapper.selectOne(qw);
}
}
新建 tanhua-dubbo/tanhua-dubbo-db/src/main/java/com/tanhua/dubbo/api/BlackListApiImpl.java
黑名单 Api接口实现类:
@DubboService
public class BlackListApiImpl implements BlackListApi {
}
新建 tanhua-model/src/main/java/com/tanhua/model/vo/SettingsVo.java
文件:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SettingsVo implements Serializable {
private Long id;
private String strangerQuestion = "";
private String phone;
private Boolean likeNotification = true;
private Boolean pinglunNotification = true;
private Boolean gonggaoNotification = true;
}
新建 tanhua-app-server/src/main/java/com/tanhua/server/controller/SettingsController.java
文件:
@RestController
@RequestMapping("/users")
public class SettingsController {
@Autowired
private SettingsService settingsService;
/**
* 查询通用设置
*/
@GetMapping("/settings")
public ResponseEntity settings() {
SettingsVo vo = settingsService.settings();
return ResponseEntity.ok(vo);
}
}
新建 tanhua-app-server/src/main/java/com/tanhua/server/service/SettingsService.java
文件:
@Service
public class SettingsService {
@DubboReference
private QuestionApi questionApi;
@DubboReference
private SettingsApi settingsApi;
// 查询用户通用设置
public SettingsVo settings() {
SettingsVo vo = new SettingsVo();
// 1. 查询用户id
Long userId = UserHolder.getUserId();
vo.setId(userId);
// 2. 查询用户手机号
vo.setPhone(UserHolder.getMobile());
// 3. 查询用户陌生人问题
Question question = questionApi.findByUserId(userId);
// 设置默认问题
String txt = question == null ? "你喜欢Java吗?" : question.getTxt();
vo.setStrangerQuestion(txt);
// 4. APP通知开关数据
Settings settings = settingsApi.findByUserId(userId);
if(settings != null) {
vo.setGonggaoNotification(settings.getGonggaoNotification());
vo.setLikeNotification(settings.getLikeNotification());
vo.setPinglunNotification(settings.getPinglunNotification());
}
return vo;
}
}
新建 tanhua-dubbo/tanhua-dubbo-interface/src/main/java/com/tanhua/dubbo/api/QuestionApi.java
文件:
public interface QuestionApi {
// 根据用户查询陌生人问题
Question findByUserId(Long userId);
}
新建 tanhua-dubbo/tanhua-dubbo-interface/src/main/java/com/tanhua/dubbo/api/SettingsApi.java
文件:
public interface SettingsApi {
// 根据用户id查询
Settings findByUserId(Long userId);
}
断点测试,查看返回数据
关闭断点,可正常查看通知设置、陌生人问题
编辑 tanhua-app-server/src/main/java/com/tanhua/server/controller/SettingsController.java
文件:
@RestController
@RequestMapping("/users")
public class SettingsController {
@Autowired
private SettingsService settingsService;
/**
* 查询通用设置
*/
@GetMapping("/settings")
public ResponseEntity settings() {
SettingsVo vo = settingsService.settings();
return ResponseEntity.ok(vo);
}
/**
* 设置陌生人问题
*/
@PostMapping("/questions")
public ResponseEntity questions(@RequestBody Map map) {
String content = (String) map.get("content");
settingsService.saveQuestions(content);
return ResponseEntity.ok(null);
}
}
编辑 tanhua-app-server/src/main/java/com/tanhua/server/service/SettingsService.java
文件:
@Service
public class SettingsService {
@DubboReference
private QuestionApi questionApi;
@DubboReference
private SettingsApi settingsApi;
// 查询用户通用设置
public SettingsVo settings() {
SettingsVo vo = new SettingsVo();
// 1. 查询用户id
Long userId = UserHolder.getUserId();
vo.setId(userId);
// 2. 查询用户手机号
vo.setPhone(UserHolder.getMobile());
// 3. 查询用户陌生人问题
Question question = questionApi.findByUserId(userId);
// 设置默认问题
String txt = question == null ? "你喜欢Java吗?" : question.getTxt();
vo.setStrangerQuestion(txt);
// 4. APP通知开关数据
Settings settings = settingsApi.findByUserId(userId);
if(settings != null) {
vo.setGonggaoNotification(settings.getGonggaoNotification());
vo.setLikeNotification(settings.getLikeNotification());
vo.setPinglunNotification(settings.getPinglunNotification());
}
return vo;
}
// 设置陌生人问题
public void saveQuestions(String content) {
// 1. 获取用户id
Long userId = UserHolder.getUserId();
// 2. 调用api查询用户陌生人问题
Question question = questionApi.findByUserId(userId);
// 3. 判断问题是否存在
if(question == null) {
// 3.1 如果不存在,保存
question = new Question();
question.setUserId(userId);
question.setTxt(content);
questionApi.save(question);
} else {
// 3.2 如果存在,更新
question.setTxt(content);
questionApi.update(question);
}
}
}
编辑 tanhua-dubbo/tanhua-dubbo-interface/src/main/java/com/tanhua/dubbo/api/QuestionApi.java
文件:
public interface QuestionApi {
// 根据用户查询陌生人问题
Question findByUserId(Long userId);
// 保存
void save(Question question);
// 更新
void update(Question question);
}
编辑 tanhua-dubbo/tanhua-dubbo-db/src/main/java/com/tanhua/dubbo/api/QuestionApiImpl.java
文件:
@DubboService
public class QuestionApiImpl implements QuestionApi{
@Autowired
private QuestionMapper questionMapper;
@Override
public Question findByUserId(Long userId) {
QueryWrapper<Question> qw = new QueryWrapper<>();
qw.eq("user_id", userId);
return questionMapper.selectOne(qw);
}
@Override
public void save(Question question) {
questionMapper.insert(question);
}
@Override
public void update(Question question) {
questionMapper.updateById(question);
}
}
编辑 tanhua-app-server/src/main/java/com/tanhua/server/controller/SettingsController.java
文件:
@RestController
@RequestMapping("/users")
public class SettingsController {
@Autowired
private SettingsService settingsService;
/**
* 查询通用设置
*/
@GetMapping("/settings")
public ResponseEntity settings() {
SettingsVo vo = settingsService.settings();
return ResponseEntity.ok(vo);
}
/**
* 设置陌生人问题
*/
@PostMapping("/questions")
public ResponseEntity questions(@RequestBody Map map) {
String content = (String) map.get("content");
settingsService.saveQuestions(content);
return ResponseEntity.ok(null);
}
/**
* 通知设置
*/
@PostMapping("notifications/setting")
public ResponseEntity notifications(@RequestBody Map map) {
// 获取参数
settingsService.saveSettings(map);
return ResponseEntity.ok(null);
}
}
编辑 tanhua-app-server/src/main/java/com/tanhua/server/service/SettingsService.java
文件:
@Service
public class SettingsService {
@DubboReference
private QuestionApi questionApi;
@DubboReference
private SettingsApi settingsApi;
// 查询用户通用设置
public SettingsVo settings() {
SettingsVo vo = new SettingsVo();
// 1. 查询用户id
Long userId = UserHolder.getUserId();
vo.setId(userId);
// 2. 查询用户手机号
vo.setPhone(UserHolder.getMobile());
// 3. 查询用户陌生人问题
Question question = questionApi.findByUserId(userId);
// 设置默认问题
String txt = question == null ? "你喜欢Java吗?" : question.getTxt();
vo.setStrangerQuestion(txt);
// 4. APP通知开关数据
Settings settings = settingsApi.findByUserId(userId);
if(settings != null) {
vo.setGonggaoNotification(settings.getGonggaoNotification());
vo.setLikeNotification(settings.getLikeNotification());
vo.setPinglunNotification(settings.getPinglunNotification());
}
return vo;
}
// 设置陌生人问题
public void saveQuestions(String content) {
// 1. 获取用户id
Long userId = UserHolder.getUserId();
// 2. 调用api查询用户陌生人问题
Question question = questionApi.findByUserId(userId);
// 3. 判断问题是否存在
if(question == null) {
// 3.1 如果不存在,保存
question = new Question();
question.setUserId(userId);
question.setTxt(content);
questionApi.save(question);
} else {
// 3.2 如果存在,更新
question.setTxt(content);
questionApi.update(question);
}
}
// 通知设置
public void saveSettings(Map map) {
Boolean likeNotification = (Boolean) map.get("likeNotification");
Boolean pinglunNotification = (Boolean) map.get("pinglunNotification");
Boolean gonggaoNotification = (Boolean) map.get("gonggaoNotification");
// 1. 获取用户id
Long userId = UserHolder.getUserId();
// 2. 调用api查询用户通知设置
Settings settings = settingsApi.findByUserId(userId);
// 3. 判断通知设置是否存在
if(settings == null) {
// 4.1 如果不存在,保存
settings = new Settings();
settings.setUserId(userId);
settings.setLikeNotification(likeNotification);
settings.setGonggaoNotification(gonggaoNotification);
settings.setPinglunNotification(pinglunNotification);
settingsApi.save(settings);
} else {
// 4.2 如果存在,更新
settings.setLikeNotification(likeNotification);
settings.setGonggaoNotification(gonggaoNotification);
settings.setPinglunNotification(pinglunNotification);
settingsApi.update(settings);
}
}
}
编辑 tanhua-dubbo/tanhua-dubbo-interface/src/main/java/com/tanhua/dubbo/api/SettingsApi.java
文件:
public interface SettingsApi {
// 根据用户id查询
Settings findByUserId(Long userId);
// 保存
void save(Settings settings);
// 更新
void update(Settings settings);
}
编辑 tanhua-dubbo/tanhua-dubbo-db/src/main/java/com/tanhua/dubbo/api/SettingsApiImpl.java
文件:
@DubboService
public class SettingsApiImpl implements SettingsApi{
@Autowired
private SettingsMapper settingsMapper;
// 根据用户id查询
@Override
public Settings findByUserId(Long userId) {
QueryWrapper<Settings> qw = new QueryWrapper<>();
qw.eq("user_id", userId);
return settingsMapper.selectOne(qw);
}
// 保存
@Override
public void save(Settings settings) {
settingsMapper.insert(settings);
}
// 更新
@Override
public void update(Settings settings) {
settingsMapper.updateById(settings);
}
}
新建 tanhua-model/src/main/java/com/tanhua/model/vo/PageResult.java
文件:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageResult implements Serializable {
private Long counts = 0l;//总记录数
private Integer pagesize;//页大小
private Long pages = 0l;//总页数
private Integer page;//当前页码
private List<?> items = Collections.emptyList(); //列表
public PageResult(Integer page,Integer pagesize,
Long counts,List list) {
this.page = page;
this.pagesize = pagesize;
this.items = list;
this.counts = counts;
this.pages = counts % pagesize == 0 ? counts / pagesize : counts / pagesize + 1;
}
}
编辑 tanhua-app-server/src/main/java/com/tanhua/server/controller/SettingsController.java
文件:
@RestController
@RequestMapping("/users")
public class SettingsController {
@Autowired
private SettingsService settingsService;
/**
* 查询通用设置
*/
@GetMapping("/settings")
public ResponseEntity settings() {
SettingsVo vo = settingsService.settings();
return ResponseEntity.ok(vo);
}
/**
* 设置陌生人问题
*/
@PostMapping("/questions")
public ResponseEntity questions(@RequestBody Map map) {
String content = (String) map.get("content");
settingsService.saveQuestions(content);
return ResponseEntity.ok(null);
}
/**
* 通知设置
*/
@PostMapping("notifications/setting")
public ResponseEntity notifications(@RequestBody Map map) {
// 获取参数
settingsService.saveSettings(map);
return ResponseEntity.ok(null);
}
/**
* 分页查询黑名单
*/
@GetMapping("blacklist")
public ResponseEntity blacklist(
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int size) {
// 1. 调用Service查询
PageResult pr = settingsService.blacklist(page, size);
// 2. 构造返回结果
return ResponseEntity.ok(pr);
}
}
编辑 tanhua-app-server/src/main/java/com/tanhua/server/service/SettingsService.java
文件:
@Service
public class SettingsService {
@DubboReference
private QuestionApi questionApi;
@DubboReference
private SettingsApi settingsApi;
@DubboReference
private BlackListApi blackListApi;
// 查询用户通用设置
public SettingsVo settings() {
SettingsVo vo = new SettingsVo();
// 1. 查询用户id
Long userId = UserHolder.getUserId();
vo.setId(userId);
// 2. 查询用户手机号
vo.setPhone(UserHolder.getMobile());
// 3. 查询用户陌生人问题
Question question = questionApi.findByUserId(userId);
// 设置默认问题
String txt = question == null ? "你喜欢Java吗?" : question.getTxt();
vo.setStrangerQuestion(txt);
// 4. APP通知开关数据
Settings settings = settingsApi.findByUserId(userId);
if(settings != null) {
vo.setGonggaoNotification(settings.getGonggaoNotification());
vo.setLikeNotification(settings.getLikeNotification());
vo.setPinglunNotification(settings.getPinglunNotification());
}
return vo;
}
// 设置陌生人问题
public void saveQuestions(String content) {
// 1. 获取用户id
Long userId = UserHolder.getUserId();
// 2. 调用api查询用户陌生人问题
Question question = questionApi.findByUserId(userId);
// 3. 判断问题是否存在
if(question == null) {
// 3.1 如果不存在,保存
question = new Question();
question.setUserId(userId);
question.setTxt(content);
questionApi.save(question);
} else {
// 3.2 如果存在,更新
question.setTxt(content);
questionApi.update(question);
}
}
// 通知设置
public void saveSettings(Map map) {
Boolean likeNotification = (Boolean) map.get("likeNotification");
Boolean pinglunNotification = (Boolean) map.get("pinglunNotification");
Boolean gonggaoNotification = (Boolean) map.get("gonggaoNotification");
// 1. 获取用户id
Long userId = UserHolder.getUserId();
// 2. 调用api查询用户通知设置
Settings settings = settingsApi.findByUserId(userId);
// 3. 判断通知设置是否存在
if(settings == null) {
// 4.1 如果不存在,保存
settings = new Settings();
settings.setUserId(userId);
settings.setLikeNotification(likeNotification);
settings.setGonggaoNotification(gonggaoNotification);
settings.setPinglunNotification(pinglunNotification);
settingsApi.save(settings);
} else {
// 4.2 如果存在,更新
settings.setLikeNotification(likeNotification);
settings.setGonggaoNotification(gonggaoNotification);
settings.setPinglunNotification(pinglunNotification);
settingsApi.update(settings);
}
}
// 分页查询黑名单
public PageResult blacklist(int page, int size) {
// 1. 获取当前用户id
Long userId = UserHolder.getUserId();
// 2. 调用API查询用户黑名单分页列表 IPage对象
IPage<UserInfo> iPage = blackListApi.findByUserId(userId, page, size);
// 3. 对象转化,将查询的IPage对象的内容封装到PageResult中
PageResult pr = new PageResult(page, size, iPage.getTotal(), iPage.getRecords());
// 4. 返回
return pr;
}
}
编辑 tanhua-dubbo/tanhua-dubbo-interface/src/main/java/com/tanhua/dubbo/api/BlackListApi.java
文件:
public interface BlackListApi {
// 分页查询黑名单列表
IPage<UserInfo> findByUserId(Long userId, int page, int size);
}
编辑 tanhua-dubbo/tanhua-dubbo-db/src/main/java/com/tanhua/dubbo/mappers/BlackListMapper.java
文件:
public interface BlackListMapper extends BaseMapper<BlackList> {
}
编辑 tanhua-dubbo/tanhua-dubbo-db/src/main/java/com/tanhua/dubbo/api/BlackListApiImpl.java
文件:
@DubboService
public class BlackListApiImpl implements BlackListApi {
@Autowired
private UserInfoMapper userInfoMapper;
@Override
public IPage<UserInfo> findByUserId(Long userId, int page, int size) {
// 1. 构建分页参数对象Page
Page pages = new Page(page, size);
// 2. 调用方法分页(自定义编写 分页参数Page sql条件参数)
return userInfoMapper.findBlackList(pages, userId);
}
}
编辑 tanhua-dubbo/tanhua-dubbo-db/src/main/java/com/tanhua/dubbo/DubboDBApplication.java
Dubbo启动类:
@SpringBootApplication
@MapperScan("com.tanhua.dubbo.mappers")
public class DubboDBApplication {
public static void main(String[] args) {
SpringApplication.run(DubboDBApplication.class, args);
}
// 开启 myBatis-Plus分页插件支持
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
新建 tanhua-app-server/src/test/java/com/tanhua/test/BlackListApiTest.java
测试类:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = AppServerApplication.class)
public class BlackListApiTest {
@DubboReference
private BlackListApi blackListApi;
@Test
public void testFindByMobile() {
IPage<UserInfo> page = blackListApi.findByUserId(106l, 1, 2);
for (UserInfo record :page.getRecords()) {
System.out.println(record);
}
}
}
编辑 tanhua-app-server/src/main/java/com/tanhua/server/controller/SettingsController.java
文件:
@RestController
@RequestMapping("/users")
public class SettingsController {
@Autowired
private SettingsService settingsService;
/**
* 查询通用设置
*/
@GetMapping("/settings")
public ResponseEntity settings() {
SettingsVo vo = settingsService.settings();
return ResponseEntity.ok(vo);
}
/**
* 设置陌生人问题
*/
@PostMapping("/questions")
public ResponseEntity questions(@RequestBody Map map) {
String content = (String) map.get("content");
settingsService.saveQuestions(content);
return ResponseEntity.ok(null);
}
/**
* 通知设置
*/
@PostMapping("notifications/setting")
public ResponseEntity notifications(@RequestBody Map map) {
// 获取参数
settingsService.saveSettings(map);
return ResponseEntity.ok(null);
}
/**
* 分页查询黑名单
*/
@GetMapping("blacklist")
public ResponseEntity blacklist(
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int size) {
// 1. 调用Service查询
PageResult pr = settingsService.blacklist(page, size);
// 2. 构造返回结果
return ResponseEntity.ok(pr);
}
/**
* 取消黑名单
*/
@DeleteMapping("/blacklist/{uid}")
public ResponseEntity deleteBlackList(@PathVariable("uid") Long blackUserId) {
settingsService.deleteBlackList(blackUserId);
return ResponseEntity.ok(null);
}
}
编辑 tanhua-app-server/src/main/java/com/tanhua/server/service/SettingsService.java
文件:
@Service
public class SettingsService {
@DubboReference
private QuestionApi questionApi;
@DubboReference
private SettingsApi settingsApi;
@DubboReference
private BlackListApi blackListApi;
// 查询用户通用设置
public SettingsVo settings() {
SettingsVo vo = new SettingsVo();
// 1. 查询用户id
Long userId = UserHolder.getUserId();
vo.setId(userId);
// 2. 查询用户手机号
vo.setPhone(UserHolder.getMobile());
// 3. 查询用户陌生人问题
Question question = questionApi.findByUserId(userId);
// 设置默认问题
String txt = question == null ? "你喜欢Java吗?" : question.getTxt();
vo.setStrangerQuestion(txt);
// 4. APP通知开关数据
Settings settings = settingsApi.findByUserId(userId);
if(settings != null) {
vo.setGonggaoNotification(settings.getGonggaoNotification());
vo.setLikeNotification(settings.getLikeNotification());
vo.setPinglunNotification(settings.getPinglunNotification());
}
return vo;
}
// 设置陌生人问题
public void saveQuestions(String content) {
// 1. 获取用户id
Long userId = UserHolder.getUserId();
// 2. 调用api查询用户陌生人问题
Question question = questionApi.findByUserId(userId);
// 3. 判断问题是否存在
if(question == null) {
// 3.1 如果不存在,保存
question = new Question();
question.setUserId(userId);
question.setTxt(content);
questionApi.save(question);
} else {
// 3.2 如果存在,更新
question.setTxt(content);
questionApi.update(question);
}
}
// 通知设置
public void saveSettings(Map map) {
Boolean likeNotification = (Boolean) map.get("likeNotification");
Boolean pinglunNotification = (Boolean) map.get("pinglunNotification");
Boolean gonggaoNotification = (Boolean) map.get("gonggaoNotification");
// 1. 获取用户id
Long userId = UserHolder.getUserId();
// 2. 调用api查询用户通知设置
Settings settings = settingsApi.findByUserId(userId);
// 3. 判断通知设置是否存在
if(settings == null) {
// 4.1 如果不存在,保存
settings = new Settings();
settings.setUserId(userId);
settings.setLikeNotification(likeNotification);
settings.setGonggaoNotification(gonggaoNotification);
settings.setPinglunNotification(pinglunNotification);
settingsApi.save(settings);
} else {
// 4.2 如果存在,更新
settings.setLikeNotification(likeNotification);
settings.setGonggaoNotification(gonggaoNotification);
settings.setPinglunNotification(pinglunNotification);
settingsApi.update(settings);
}
}
// 分页查询黑名单
public PageResult blacklist(int page, int size) {
// 1. 获取当前用户id
Long userId = UserHolder.getUserId();
// 2. 调用API查询用户黑名单分页列表 IPage对象
IPage<UserInfo> iPage = blackListApi.findByUserId(userId, page, size);
// 3. 对象转化,将查询的IPage对象的内容封装到PageResult中
PageResult pr = new PageResult(page, size, iPage.getTotal(), iPage.getRecords());
// 4. 返回
return pr;
}
// 取消黑名单
public void deleteBlackList(Long blackUserId) {
// 1. 获取当前用户id
Long userId = UserHolder.getUserId();
// 2. 调用api删除
blackListApi.delete(userId, blackUserId);
}
}
编辑 tanhua-dubbo/tanhua-dubbo-interface/src/main/java/com/tanhua/dubbo/api/BlackListApi.java
文件:
public interface BlackListApi {
// 分页查询黑名单列表
IPage<UserInfo> findByUserId(Long userId, int page, int size);
// 取消黑名单
void delete(Long userId, Long blackUserId);
}
编辑 tanhua-dubbo/tanhua-dubbo-db/src/main/java/com/tanhua/dubbo/api/BlackListApiImpl.java
文件:
@DubboService
public class BlackListApiImpl implements BlackListApi {
@Autowired
private UserInfoMapper userInfoMapper;
@Autowired
private BlackListMapper blackListMapper;
// 查询黑名单分页列表
@Override
public IPage<UserInfo> findByUserId(Long userId, int page, int size) {
// 1. 构建分页参数对象Page
Page pages = new Page(page, size);
// 2. 调用方法分页(自定义编写 分页参数Page sql条件参数)
return userInfoMapper.findBlackList(pages, userId);
}
// 取消黑名单
@Override
public void delete(Long userId, Long blackUserId) {
QueryWrapper<BlackList> qw = new QueryWrapper<>();
qw.eq("user_id", userId);
qw.eq("black_user_id", blackUserId);
blackListMapper.delete(qw);
}
}
对于社交类软件的功能,它具有以下特点:
针对以上特点,结合MySQL、Redis来分析一下:
探花交友项目的数据库使用:
MongoDB官网:https://www.mongodb.com
MongoDB与Redis和Mysql的对比:
Mongodb的适用场景:
为了更好的理解,下面与SQL中的概念进行对比:
SQL术语/概念 | MongoDB术语/概念 | 解释/说明 |
---|---|---|
database | database | 数据库 |
table | collection | 数据库表/集合 |
row | document | 表中的一条数据 |
column | field | 数据字段/域 |
index | index | 索引 |
table joins | 表连接,MongoDB不支持 | |
primary key | primary key | 主键,MongoDB自动将_id字段设置为主键 |
MongoDB中使用Bson存储数据( Binary JSON ),一种类似Json的数据格式。
MongoDB 的逻辑结构是一种层次结构。主要由: 文档(document)、集合(collection)、数据库(database)这三部分组成的。逻辑结构是面 向用户的,用户使用 MongoDB 开发应用程序使用的就是逻辑结构。
# 拉取镜像
docker pull mongo
# 创建容器
docker run --name mongo-service -p 27017:27017 -v ~/data/mongodata:/data -d mongo
在博主的虚拟机中已经提供了MongoDB的镜像和容器,我们只需要使用简单的命令即可启动
# 进入base目录
cd /root/docker-file/base/
# 批量创建启动容器,其中已经包含了redis,zookeeper,mongodb容器
docker-compose up -d
# 查看容器
docker ps -a
# 可以看到mongoDB已经启动,对外暴露了27017的操作端口
使用Navicat15连接 MongoDB:
网盘资源地址(不需要密码): https://pan.baidu.com/s/1daL566ehyZuQ6s5vzXYNpA?pwd=java
#查看所有的数据库
> show dbs
#通过use关键字切换数据库
> use admin
#创建数据库
#说明:在MongoDB中,数据库是自动创建的,通过use切换到新数据库中,进行插入数据即可自动创建数据库
> use testdb
> show dbs #并没有创建数据库
> db.user.insert({id:1,name:'zhangsan'}) #插入数据
> show dbs
#查看表
> show tables
> show collections
#删除集合(表)
> db.user.drop()
true #如果成功删除选定集合,则 drop() 方法返回 true,否则返回 false。
#删除数据库
> use testdb #先切换到要删除的数据中
> db.dropDatabase() #删除数据库
在MongoDB中,存储的文档结构是一种类似于json的结构,称之为bson(全称为:Binary JSON)。
#插入数据
#语法:db.表名.insert(json字符串)
> db.user.insert({id:1,username:'zhangsan',age:20})
> db.user.find() #查询数据
update() 方法用于更新已存在的文档。语法格式如下:
db.collection.update(
<query>,
<update>,
[
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
]
)
参数说明:
#查询全部
> db.user.find()
#更新数据
> db.user.update({id:1},{$set:{age:22}})
#注意:如果这样写,会删除掉其他的字段
> db.user.update({id:1},{age:25})
#更新不存在的字段,会新增字段
> db.user.update({id:2},{$set:{sex:1}}) #更新数据
#更新不存在的数据,默认不会新增数据
> db.user.update({id:3},{$set:{sex:1}})
#如果设置第一个参数为true,就是新增数据
> db.user.update({id:3},{$set:{sex:1}},true)
通过remove()方法进行删除数据,语法如下:
db.collection.remove(
<query>,
{
justOne: <boolean>,
writeConcern: <document>
}
)
参数说明:
#删除数据
> db.user.remove({})
#插入4条测试数据
db.user.insert({id:1,username:'zhangsan',age:20})
db.user.insert({id:2,username:'lisi',age:21})
db.user.insert({id:3,username:'wangwu',age:22})
db.user.insert({id:4,username:'zhaoliu',age:22})
> db.user.remove({age:22},true)
#删除所有数据
> db.user.remove({})
MongoDB 查询数据的语法格式如下:
db.user.find([query],[fields])
条件查询:
操作 | 格式 | 范例 | RDBMS中的类似语句 |
---|---|---|---|
等于 | { } |
db.col.find({"by":"黑马程序员"}).pretty() |
where by = '黑马程序员' |
小于 | { |
db.col.find({"likes":{$lt:50}}).pretty() |
where likes < 50 |
小于或等于 | { |
db.col.find({"likes":{$lte:50}}).pretty() |
where likes <= 50 |
大于 | { |
db.col.find({"likes":{$gt:50}}).pretty() |
where likes > 50 |
大于或等于 | { |
db.col.find({"likes":{$gte:50}}).pretty() |
where likes >= 50 |
不等于 | { |
db.col.find({"likes":{$ne:50}}).pretty() |
where likes != 50 |
#插入测试数据
db.user.insert({id:1,username:'zhangsan',age:20})
db.user.insert({id:2,username:'lisi',age:21})
db.user.insert({id:3,username:'wangwu',age:22})
db.user.insert({id:4,username:'zhaoliu',age:22})
db.user.find() #查询全部数据
db.user.find({},{id:1,username:1}) #只查询id与username字段
db.user.find().count() #查询数据条数
db.user.find({id:1}) #查询id为1的数据
db.user.find({age:{$lte:21}}) #查询小于等于21的数据
db.user.find({$or:[{id:1},{id:2}]}) #查询id=1 or id=2
#分页查询:Skip()跳过几条,limit()查询条数
db.user.find().limit(2).skip(1) #跳过1条数据,查询2条数据
db.user.find().sort({id:-1}) #按照id倒序排序,-1为倒序,1为正序
索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。
索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构
#创建索引
> db.user.createIndex({'age':1})
#查看索引
> db.user.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "testdb.user"
}
]
#说明:1表示升序创建索引,-1表示降序创建索引。
执行计划:
MongoDB 查询分析可以确保我们建议的索引是否有效,是查询语句性能分析的重要工具。
#插入1000条数据
for(var i=1;i<1000;i++)db.user.insert({id:100+i,username:'name_'+i,age:10+i})
#查看执行计划
> db.user.find({age:{$gt:100},id:{$lt:200}}).explain()
#测试没有使用索引
> db.user.find({username:'zhangsan'}).explain()
#winningPlan:最佳执行计划
#"stage" : "FETCH", #查询方式,常见的有COLLSCAN/全表扫描、IXSCAN/索引扫描、FETCH/根据索引去检索文档、SHARD_MERGE/合并分片结果、IDHACK/针对_id进行查询
...
<!--导入MongoDB依赖-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.9.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
新建 application.yml
文件:
# 配置MongoDB连接地址
spring:
data:
mongodb:
uri: mongodb://192.168.136.160:27017/testdb
新建 com/tanhua/mongo/MonGoApplication.java
文件:
@SpringBootApplication
public class MonGoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootApplication.class, args);
}
}
新建 com/tanhua/mongo/domain/Person.java
文件:
// 指定实体类和MongoDB的映射关系
@Document("tb_person") // 如果为空默认monGoDB同名集合
@Data
public class Person {
@Id
private ObjectId id; // MongoDB推荐用法
@Field("myname") // 如果不写,默认属性名为字段名
private String name;
private Integer age;
private String address;
}
新建 com/tanhua/mongo/test/MongoTest.java
文件:
@RunWith(SpringRunner.class)
@SpringBootTest
public class MongoTest {
// 1. 注入MongoTemplate对象
@Autowired
private MongoTemplate mongoTemplate;
// 2. 调用其方法完成数据的CRUD
// 3.1 保存
@Test
public void testSave() {
Person person = new Person();
person.setName("zoe");
person.setAge(18);
person.setAddress("北京海淀区");
mongoTemplate.save(person);
}
// 3.2 插入测试数据
@Test
public void testInsert() {
for (int i = 0; i < 10; i++) {
Person person = new Person();
person.setName("zoe" + i);
person.setAge(18 + i);
person.setAddress("北京海淀区" + i);
mongoTemplate.save(person);
}
}
// 3.3 查询所有
@Test
public void testFIndAll() {
List<Person> list = mongoTemplate.findAll(Person.class);
for (Person person : list) {
System.out.println(person);
}
}
// 3.4 条件查询
@Test
public void testFind() {
// 1. 创建Criteria对象,并设置查询条件
Criteria criteria = Criteria.where("myname").is("zoe"); // is 相当于 SQL中的 =
// 2. 根据Critical创建Query对象
Query query = Query.query(criteria);
// 3. 查询
List<Person> list = mongoTemplate.find(query, Person.class);// Query对象, 实体类对象
for (Person person : list) {
System.out.println(person);
}
}
// 3.5 多个条件查询
@Test
public void testFind2() {
// 1. 创建Criteria对象,并设置查询条件
Criteria criteria = Criteria.where("myname").is("zoe")
.and("age").is(18);
// 2. 根据Critical创建Query对象
Query query = Query.query(criteria);
// 3. 查询
List<Person> list = mongoTemplate.find(query, Person.class);// Query对象, 实体类对象
for (Person person : list) {
System.out.println(person);
}
}
// 分页查询
@Test
public void testFindPage() {
int page = 1;
int size = 2;
// 1. 创建Criteria对象,并设置查询条件
Criteria criteria = Criteria.where("age").lt(50); // 年龄小于50
// 2. 根据Critical创建Query对象
Query query = Query.query(criteria)
.skip((page - 1) * size) // 查询页数
.limit(size) // 每页条数
.with(Sort.by(Sort.Order.desc("age"))); // 排序,按年龄降序排列
// 3. 查询
List<Person> list = mongoTemplate.find(query, Person.class);// Query对象, 实体类对象
for (Person person : list) {
System.out.println(person);
}
}
// 更新
@Test
public void testUpdate() {
// 1. 构建query对象
Query query = Query.query(Criteria.where("id").is("63428ba254fedd7eb5a9b066"));
// 2. 设置需要更新的数据内容
Update update = new Update();
update.set("age", 10);
update.set("myname", "tom");
// 3. 调用方法
mongoTemplate.updateFirst(query, update, Person.class);
}
// 删除
@Test
public void testDelete() {
// 1. 构建query对象
Query query = Query.query(Criteria.where("id").is("63428ba254fedd7eb5a9b066"));
// 2. 调用方法
mongoTemplate.remove(query, Person.class);
}
}
新建 tanhua-dubbo/tanhua-dubbo-mongo/src/main/java/com/tanhua/dubbo/DubboMongoApplication.java
启动类:
@SpringBootApplication
public class DubboMongoApplication {
public static void main(String[] args) {
SpringApplication.run(DubboMongoApplication.class,args);
}
}
新建 tanhua-dubbo/tanhua-dubbo-mongo/src/main/resources/application.yml
yml文件:
server:
port: 18082
spring:
application:
name: tanhua-dubbo-mongo
cloud:
nacos:
discovery:
server-addr: 192.168.136.160:8848
data:
mongodb:
uri: mongodb://192.168.136.160:27017/tanhua
dubbo:
protocol:
name: dubbo
port: 20882
registry:
address: spring-cloud://localhost
scan:
base-packages: com.tanhua.dubbo.api #dubbo中包扫描
新建 tanhua-model/src/main/java/com/tanhua/model/mongo/RecommendUser.java
文件:
@AllArgsConstructor
@NoArgsConstructor
@Data
@Document(collection = "recommend_user")
public class RecommendUser implements java.io.Serializable {
private ObjectId id; //主键id
private Long userId; //推荐的用户id
private Long toUserId; //用户id
private Double score =0d; //推荐得分
private String date; //日期
}
新建 tanhua-dubbo/tanhua-dubbo-interface/src/main/java/com/tanhua/dubbo/api/RecommendUserApi.java
文件:
public interface RecommendUserApi {
// 查询今日佳人
RecommendUser queryWithMaxScore(Long toUserId);
}
新建 tanhua-dubbo/tanhua-dubbo-mongo/src/main/java/com/tanhua/dubbo/api/RecommendUserApiImpl.java
文件:
@DubboService
public class RecommendUserApiImpl implements RecommendUserApi{
@Autowired
private MongoTemplate mongoTemplate;
// 查询今日佳人
public RecommendUser queryWithMaxScore(Long toUserId) {
// 根据toUserId查询,根据评分score排序,获取第一条
// 1. 构建Criteria
Criteria criteria = Criteria.where("toUserId").is(toUserId);
// 2. 构建Query
Query query = Query.query(criteria).with(Sort.by(Sort.Order.desc("score")))
.limit(1); // 查询第一条(第一页第一条)
// 3. 调用mongoTemplate查询
return mongoTemplate.findOne(query, RecommendUser.class);
}
}
新建 tanhua-app-server/src/test/java/com/tanhua/test/RecommendUserApiTest.java
文件:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = AppServerApplication.class)
public class RecommendUserApiTest {
@DubboReference
private RecommendUserApi recommendUserApi;
@Test
public void testFindByMobile() {
RecommendUser recommendUser = recommendUserApi.queryWithMaxScore(106L);
System.out.println(recommendUser);
}
}
查看打印结果,返回的用户(今日佳人)数据
新建 tanhua-app-server/src/main/java/com/tanhua/server/controller/TanhuaController.java
文件:
@RestController
@RequestMapping("/tanhua")
public class TanhuaController {
@Autowired
private TanhuaService tanhuaService;
// 今日佳人
@GetMapping("/todayBest")
public ResponseEntity todayBest() {
TodayBest vo = tanhuaService.todayBest();
return ResponseEntity.ok(vo);
}
}
新建 tanhua-app-server/src/main/java/com/tanhua/server/service/TanhuaService.java
文件:
@Service
public class TanhuaService {
@DubboReference
private RecommendUserApi recommendUserApi;
@DubboReference
private UserInfoApi userInfoApi;
// 查询今日佳人数据
public TodayBest todayBest() {
// 1. 获取用户id
Long userId = UserHolder.getUserId();
// 2. 调用api查询
RecommendUser recommendUser = recommendUserApi.queryWithMaxScore(userId);
// 3. 设置默认值
if(recommendUser == null) {
recommendUser = new RecommendUser();
recommendUser.setUserId(1l);
recommendUser.setScore(99d);
}
// 4. 将recommendUser 转化成 todayBest对象
UserInfo userInfo = userInfoApi.findById(recommendUser.getUserId());
TodayBest vo = TodayBest.init(userInfo, recommendUser);
// 5. 返回
return vo;
}
}
新建 tanhua-model/src/main/java/com/tanhua/model/vo/TodayBest.java
文件:
/**
* 今日佳人
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TodayBest {
private Long id; //用户id
private String avatar;
private String nickname;
private String gender; //性别 man woman
private Integer age;
private String[] tags;
private Long fateValue; //缘分值
/**
* 在vo对象中,补充一个工具方法,封装转化过程
*/
public static TodayBest init(UserInfo userInfo, RecommendUser recommendUser) {
TodayBest vo = new TodayBest();
BeanUtils.copyProperties(userInfo,vo);
if(userInfo.getTags() != null) {
vo.setTags(userInfo.getTags().split(","));
}
vo.setFateValue(recommendUser.getScore().longValue());
return vo;
}
}
在项目中,添加了mongo的依赖,springboot就会自动去连接本地的mongo,由于连接不上会导致出错。
解决有2种方案:
编辑 tanhua-app-server/src/main/java/com/tanhua/server/AppServerApplication.java
文件:
//启动类
// @SpringBootApplication
@SpringBootApplication(exclude = {
MongoAutoConfiguration.class,
MongoDataAutoConfiguration.class
}) //排除mongo的自动配置
public class AppServerApplication {
public static void main(String[] args) {
SpringApplication.run(AppServerApplication.class,args);
}
}