1. 数据库映射对象与视图对象
笔者在开发过程中在面向客户端展示时都是使用二次封装的视图对象(VO)来进行内容展示.
package com.fod.fodapi.vo;
import lombok.Data;
@Data
public class UrmUserInfoVO {
private Integer id;
private String userNumber;
private String userName;
private String userImage;
private Integer userSex;
private String userPhone;
private Integer status;
private String userRole;
}
2. 测试SQL
测试sql是在数据库客户端进行数据测试时进行编写,确保在编写代码时不会出现sql查询错误
SELECT
users.id, users.user_number, users.user_name, users.user_image, users.user_sex,
users.user_phone, users.native_place, users.status, roles.role_name
FROM
urm_user_info AS users
JOIN urm_user_online AS onlines ON users.id = onlines.user_info
JOIN urm_user_role_relevance AS userAndRole ON users.id = userAndRole.user_id
LEFT JOIN urm_role_info AS roles ON userAndRole.role_id = roles.id
WHERE
users.STATUS = 1
AND users.deleted = 0
AND onlines.online_status = 1
ORDER BY
users.add_time
测试结果:
3. MVC层分解
3.1 查询参数封装
查询过程中部分参数是需要重复使用比如:当前页,当前页的数量,筛选条件等等。同时也可以解决查询参数过多导致接口层接收数据的代码过多。 公共使用的字段封装:(类名:PublicSelect)
private Integer page = 1;
private Integer limit = 10;
private String sort = "add_time";
private Boolean order = true;
特定功能查询字段封装:(类名:UrmUserInfoSelect ) 在使用公共字段的时候继承一下即可
@Data
public class UrmUserInfoSelect extends PublicSelect{
private String userNumber;
private String userName;
private Integer userSex;
private String userPhone;
private Integer status;
private Date addTime;
}
3.2 Controller层代码
笔者在controller层只用做数据接收,数据的基本过滤验证,以及返回操作,业务全部在接口实现层里面(serverImpl)
@ApiOperation(value = "人员在线列表")
@GetMapping("/list")
@ResponseBody
public Object listSelective(@RequestBody UrmUserInfoSelect select){
return rdmPersonOnlineService.listSelective(select);
}
3.3 Service接口层
public interface RdmPersonOnlineService {
Object listSelective(UrmUserInfoSelect select);
}
3.4 ServiceImpl接口实现层
在这个类里面将编写所有与业务有关的内容
@Override
public Object listSelective(UrmUserInfoSelect select) {
QueryWrapper<UrmUserInfoVO> voQueryWrapper = new QueryWrapper<>();
voQueryWrapper.eq("users.status",STATUS_START);
voQueryWrapper.eq("users.deleted",DELETED_NO);
voQueryWrapper.eq("onlines.online_status",USER_ONLINE);
voQueryWrapper.orderBy(true, select.getOrder(), select.getSort());
Page<UrmUserInfoVO> voPage = new Page<>(select.getPage(),select.getLimit());
voPage.setRecords(
urmUserInfoMapper.selectiveUserInfoByOnlineStatus(voPage,voQueryWrapper));
return ResponseUtil.ok(voPage);
}
3.5 Mapper数据持久层
在mypper层编写sql时:在方法里面的条件参数中必须加上**@Param(Constants.WRAPPER),在Sql末尾必须加上${ew.customSqlSegment}**否在定义的条件无效。由于筛选条件(查询条件)在条件参数中已经配置完成,在mapper的sql里面就不需要再次写入。
@Mapper
@Repository
public interface UrmUserInfoMapper extends BaseMapper<UrmUserInfo> {
@Select("SELECT " +
"users.id, users.user_number, users.user_name, users.user_image, users.user_sex, users.user_phone, users.native_place, users.status, roles.role_name " +
"FROM " +
"urm_user_info AS users " +
"JOIN urm_user_online AS onlines ON users.id = onlines.user_info " +
"JOIN urm_user_role_relevance AS userAndRole ON users.id = userAndRole.user_id " +
"LEFT JOIN urm_role_info AS roles ON userAndRole.role_id = roles.id ${ew.customSqlSegment}")
List<UrmUserInfoVO> selectiveUserInfoByOnlineStatus(Page<UrmUserInfoVO> voPage, @Param(Constants.WRAPPER)QueryWrapper<UrmUserInfoVO> voQueryWrapper);
}
4. 结果
筛选条件
{
"page":1,
"limit":5,
"sort": null,
"order":true,
"userNumber":null,
"userName":null,
"userSex": null,
"userPhone": null,
"status": null,
"addTime":null
}
筛选结果:
{
"errno": 0,
"data": {
"records": [
{
"id": 1,
"userNumber": "admin",
"userName": "admin",
"userImage": null,
"userSex": 1,
"userPhone": "1234567890123",
"status": 1,
"userRole": null,
"userOrganize": null
},
{
"id": 2,
"userNumber": "123456",
"userName": "张三",
"userImage": null,
"userSex": 0,
"userPhone": "1234567890123",
"status": 1,
"userRole": null,
"userOrganize": null
},
{
"id": 3,
"userNumber": "123456789",
"userName": "李四",
"userImage": null,
"userSex": 1,
"userPhone": "1234567890123",
"status": 1,
"userRole": null,
"userOrganize": null
},
{
"id": 4,
"userNumber": "123123",
"userName": "王五",
"userImage": null,
"userSex": 1,
"userPhone": "1234567890123",
"status": 1,
"userRole": null,
"userOrganize": null
},
{
"id": 5,
"userNumber": "12121212",
"userName": "马六",
"userImage": null,
"userSex": 1,
"userPhone": "1234567890123",
"status": 1,
"userRole": null,
"userOrganize": null
}
],
"total": 6,
"size": 5,
"current": 1,
"orders": [],
"optimizeCountSql": true,
"hitCount": false,
"countId": null,
"maxLimit": null,
"searchCount": true,
"pages": 2
},
"errmsg": "成功"
}
图示:
5 补充
5.1 分页失效问题
分页时出现查询出来的都是所有数据,并不会进行分页。原因是mybatis-plus配置出现问题。 不同版本可能会出现配置差异(笔者使用的是3.4.1)
@Configuration(proxyBeanMethods = false)
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor()
{
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(paginationInterceptor());
return interceptor;
}
public PaginationInnerInterceptor paginationInterceptor() {
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
paginationInnerInterceptor.setDbType(DbType.MYSQL);
paginationInnerInterceptor.setOverflow(false);
paginationInnerInterceptor.setMaxLimit(-1L);
return paginationInnerInterceptor;
}
}
|