框架使用技巧
单表,多表动态查询条件实现,基于Mybatis-Plus。
单表,多表分页功能实现,基于Mybatis-Plus。
本框架的条件查询和分页查询基于Mybatis-Plus,在此功能上做了部分封装和扩展,关于Mybatis-Plus的基本用法和实现逻辑可以查看参照Mybatis-Plus官网。
1.1.单表查询操作
Mybatis-Plus本身对于单表查询的支持已经非常完善,具体使用请查看Mybatis-Plus官网。
1.2.多表动态条件分页查询操作
本开发框架使用Mybatis-Plus数据库处理框架,底层还是基于MyBatis,但是不推荐使用mapper.xml,而是使用MyBatis集中存储sql的java类的方式,在类中的每个方法里写具体的sql,动态查询的基本的操作流程和原理如下:
- 在SqlProvider中预先写好需要查询的字段和表的关联操作对应的基础sql
- 根据需求在Controller动态添加和删除SqlParam
- 根据SqlParam列表构建框架识别的QueryWrapper
- 根据需求设置MyPage分页查询参数
- 框架将QueryWrapper和MyPage转译成Sql跟基础sql进行拼接
本例中有两个表用户信息表–DEMO_USERINFO和组织架构表–DEMO_DEPARTMENT,在用户信息表中有一个外键org_id对应组织架构表中id字段。
完整代码见backend-framework-template项目:
1.2.1.Controller层
本例中实现根据用户所属部门、用户账号和用户年龄三个条件进行多表动态条件查询,并支持分页查询和排序。Controller层代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@RequestMapping(value = "/pageList", method = RequestMethod.POST)
public MyPage<UserInfo> pageList(@RequestBody UserInfo user) {
List<SqlParam> sqlParams = new ArrayList<>();
// 根据需要动态设置查询条件,支持多表多条件查询
SqlParam codeParam = new SqlParam("b.CODE", user.getOrgCode(), SqlOperator.EQ);
SqlParam accountParam = new SqlParam("a.ACCOUNT", user.getAccount(), SqlOperator.LIKE);
SqlParam ageParam = new SqlParam("a.AGE", user.getAge(), SqlOperator.GT);
sqlParams.add(codeParam);
sqlParams.add(accountParam);
sqlParams.add(ageParam);
// 根据用户创建时间倒序排序
SqlParam orderParam = new SqlParam("a.CREATE_TIME", SqlOperator.ORDER_BY_DESC);
sqlParams.add(orderParam);
// 生成QueryWrapper查询条件
QueryWrapper queryWrapper = DaoUtils.generateQueryWrapper(sqlParams);
// 设置分页信息,默认当前页是1,每页10条
MyPage<UserInfo> page = new MyPage<>();
if (user.getCurrentPage() != 0) {
page.setCurrentPage(user.getCurrentPage());
}
if (user.getPageSize() != 0) {
page.setPageSize(user.getPageSize());
}
return myBaseService.pageList(page, queryWrapper);
}
其中sqlParam中的字段对应条件查询的字段,字段前面的表名为基础sql中定义的表名。
SqlOperator枚举类中存放着目前框架支持的条件操作符,对于操作符的说明如下:
LIKE,EQ,GE,GT,LE,LT,NE用于拼接单个条件中字段和值之间的关系,具体代表含义和Mybatis-Plus的条件构造器保持一致;
OR,AND是用于连接多个条件的,目前框架默认将所有条件用AND相连,如果有OR的需求可以调用下面的构造函数构造SqlParam:
1
2
3
4
5
6
7
8
public SqlParam(String columnName, String value, SqlOperator sqlOperator, SqlOperator linkOperator) {
this.columnName = columnName;
this.value = value;
this.sqlOperator = sqlOperator;
this.linkOperator = linkOperator;
}
// 调用方式
SqlParam orgNameParam = new SqlParam("b.NAME", user.getOrgName(), SqlOperator.LIKE, SqlOperator.OR);
这样框架会将此条件作为OR的后一个条件语句和前面的条件语句进行拼接。
ORDER_BY_ASC,ORDER_BY_DESC 分别支持顺序和倒序排序;
GROUP _BY支持分组操作。
1.2.2.Service层
如果有额外的业务逻辑可以在Service层进行处理,目前为了保证给前端的分页参数和其他项目保持一致,重新封装了MyPage分页类,故在这一层对分页参数进行设置。
1
2
3
4
5
6
7
@Override
public MyPage<UserInfo> pageList(MyPage<UserInfo> page, Wrapper wrapper) {
MyPage<UserInfo> myPage = baseMapper.pageList(page, wrapper);
myPage.setCurrentPage(myPage.getCurrent());
myPage.setPageSize(myPage.getSize());
return myPage;
}
1.2.3.Dao层
在dao层调用具体的sql,其中type对应最初创建的SqlProvider类,method对应类中具体的方法名,框架会自动将wapper和page参数转译成sql拼接在基础sql上,请注意@Param注解中的参数需要和下面的SqlProvider中的参数保持一致,且均为Constants.WRAPPER
1
2
3
4
5
6
7
8
9
/**
* 分页条件查找用户数据
*
* @param page
* @param wrapper
* @return
*/
@SelectProvider(type = UserSqlProvider.class, method = "pageList")
MyPage<UserInfo> pageList(MyPage<UserInfo> page, @Param(Constants.WRAPPER) Wrapper wrapper);
1.2.4.SqlProvider
在SqlProvider中创建存储基础sql的类UserSqlProvider,其中wapper参数就是从调用方需要传过来的条件,${ew.customSqlSegment}目前不支持写成别的方式,最终此占位符会替换成wapper转译成的sql语句
1
2
3
4
5
6
7
8
9
public class UserSqlProvider {
public String pageList(@Param(Constants.WRAPPER) Wrapper wrapper) {
String sql =
"select a.*,b.NAME,b.CODE from DEMO_USERINFO as a inner join DEMO_DEPARTMENT as b on a.ORG_ID = b.ID";
sql += " ${ew.customSqlSegment} ";
return sql;
}
}