feat: 添加 xml 分页功能,baseMapper.xmlPaginate

This commit is contained in:
开源海哥 2023-08-01 11:04:18 +08:00
parent 942bad8b47
commit 6e3106789e
8 changed files with 129 additions and 11 deletions

View File

@ -29,6 +29,9 @@ import com.mybatisflex.core.util.*;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.builder.annotation.ProviderContext;
import org.apache.ibatis.cursor.Cursor;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import java.io.Serializable;
import java.util.*;
@ -364,6 +367,7 @@ public interface BaseMapper<T> {
/**
* 执行类似 {@code update table set field = field + 1 where ... } 的场景
* TODO: 2023/7/27 该方法将在 v1.6.0 被删除
*
* @param fieldName 字段名
* @param value 大于等于 0 小于 0
* @param queryWrapper 条件
@ -377,6 +381,7 @@ public interface BaseMapper<T> {
/**
* 执行类似 {@code update table set field = field + 1 where ... } 的场景
* TODO: 该方法将在 v1.6.0 被删除
*
* @param column 字段名
* @param value 大于等于 0 小于 0
* @param queryWrapper 条件
@ -392,6 +397,7 @@ public interface BaseMapper<T> {
/**
* 执行类似 {@code update table set field = field + 1 where ... } 的场景
* TODO: 该方法将在 v1.6.0 被删除
*
* @param fn 字段名
* @param value 大于等于 0 小于 0
* @param queryWrapper 条件
@ -505,7 +511,8 @@ public interface BaseMapper<T> {
/**
* 根据主表主键来查询 1 条数据
* @param id 表主键
*
* @param id 表主键
* @param asType 接收数据类型
* @return 实体类数据
*/
@ -517,6 +524,7 @@ public interface BaseMapper<T> {
MappedStatementTypes.clear();
}
}
/**
* 根据查询条件来查询 1 条数据
*
@ -1117,4 +1125,44 @@ public interface BaseMapper<T> {
return MapperUtil.doPaginate(this, page, queryWrapper, asType, true, consumers);
}
default <E> Page<E> xmlPaginate(String dataSelectId, Page<E> page, QueryWrapper queryWrapper) {
return xmlPaginate(dataSelectId, dataSelectId + "_COUNT", page, queryWrapper, null);
}
default <E> Page<E> xmlPaginate(String dataSelectId, Page<E> page, Map<String, Object> otherParams) {
return xmlPaginate(dataSelectId, dataSelectId + "_COUNT", page, null, otherParams);
}
default <E> Page<E> xmlPaginate(String dataSelectId, Page<E> page, QueryWrapper queryWrapper, Map<String, Object> otherParams) {
return xmlPaginate(dataSelectId, dataSelectId + "_COUNT", page, queryWrapper, otherParams);
}
default <E> Page<E> xmlPaginate(String dataSelectId, String countSelectId, Page<E> page, QueryWrapper queryWrapper, Map<String, Object> otherParams) {
SqlSessionFactory sqlSessionFactory = FlexGlobalConfig.getDefaultConfig().getSqlSessionFactory();
ExecutorType executorType = FlexGlobalConfig.getDefaultConfig().getConfiguration().getDefaultExecutorType();
String mapperClassName = ClassUtil.getUsefulClass(this.getClass()).getName();
Map<String, Object> preparedParams = MapperUtil.preparedParams(page, queryWrapper, otherParams);
if (!dataSelectId.contains(".")) {
dataSelectId = mapperClassName + "." + dataSelectId;
}
try (SqlSession sqlSession = sqlSessionFactory.openSession(executorType, false)) {
if (page.getTotalRow() < 0) {
if (!countSelectId.contains(".")) {
countSelectId = mapperClassName + "." + countSelectId;
}
Number number = sqlSession.selectOne(countSelectId, preparedParams);
page.setTotalRow(number);
}
if (!page.isEmpty()) {
List<E> entities = sqlSession.selectList(dataSelectId, preparedParams);
page.setRecords(entities);
}
}
return page;
}
}

View File

@ -196,5 +196,7 @@ public enum DbType {
this.remarks = remarks;
}
public String getName() {
return name;
}
}

View File

@ -193,7 +193,7 @@ public class Page<T> implements Serializable {
* @param pageSize 每页数据数量
*/
public void setPageSize(Number pageSize) {
if (pageSize.longValue() < 0) {
if (pageSize == null || pageSize.longValue() < 0) {
throw new IllegalArgumentException("pageSize must greater than or equal 0current value is: " + pageSize);
}
this.pageSize = pageSize.longValue();
@ -233,7 +233,7 @@ public class Page<T> implements Serializable {
* @param totalRow 数据总数
*/
public void setTotalRow(Number totalRow) {
this.totalRow = totalRow.longValue();
this.totalRow = totalRow == null ? INIT_VALUE : totalRow.longValue();
this.calcTotalPage();
}

View File

@ -16,7 +16,10 @@
package com.mybatisflex.core.util;
import com.mybatisflex.core.BaseMapper;
import com.mybatisflex.core.FlexGlobalConfig;
import com.mybatisflex.core.constant.SqlConsts;
import com.mybatisflex.core.dialect.DbType;
import com.mybatisflex.core.dialect.DialectFactory;
import com.mybatisflex.core.exception.FlexExceptions;
import com.mybatisflex.core.field.FieldQuery;
import com.mybatisflex.core.field.FieldQueryBuilder;
@ -254,4 +257,60 @@ public class MapperUtil {
}
}
public static Map<String, Object> preparedParams(Page<?> page, QueryWrapper queryWrapper, Map<String, Object> params) {
Map<String, Object> newParams = new HashMap<>();
if (params != null) {
newParams.putAll(params);
}
newParams.put("pageOffset", page.offset());
newParams.put("pageNumber", page.getPageNumber());
newParams.put("pageSize", page.getPageSize());
DbType dbType = DialectFactory.getHintDbType();
newParams.put("dbType", dbType != null ? dbType : FlexGlobalConfig.getDefaultConfig().getDbType());
if (queryWrapper != null) {
preparedQueryWrapper(newParams, queryWrapper);
}
return newParams;
}
private static void preparedQueryWrapper(Map<String, Object> params, QueryWrapper queryWrapper) {
String sql = DialectFactory.getDialect().buildNoSelectSql(queryWrapper);
StringBuilder sqlBuilder = new StringBuilder();
char quote = 0;
int index = 0;
for (int i = 0; i < sql.length(); ++i) {
char ch = sql.charAt(i);
if (ch == '\'') {
if (quote == 0) {
quote = ch;
} else if (quote == '\'') {
quote = 0;
}
} else if (ch == '"') {
if (quote == 0) {
quote = ch;
} else if (quote == '"') {
quote = 0;
}
}
if (quote == 0 && ch == '?') {
sqlBuilder.append("#{qwParams_").append(index++).append("}");
} else {
sqlBuilder.append(ch);
}
}
params.put("qwSql", sqlBuilder.toString());
Object[] valueArray = CPI.getValueArray(queryWrapper);
for (int i = 0; i < valueArray.length; i++) {
params.put("qwParams_" + i, valueArray[i]);
}
}
}

View File

@ -56,8 +56,15 @@ public class AccountController {
@GetMapping("/account/byName/{name}")
AccountDto selectName(@PathVariable("name") String name) {
return myAccountMapper.selectByName(name);
Page<AccountDto> selectName(@PathVariable("name") String name) {
// return myAccountMapper.selectByName(name);
QueryWrapper qw = QueryWrapper.create()
// .where(Account::getAge).eq("18")
.and(Account::getId).ge(0);
Page<AccountDto> accountPage = myAccountMapper.xmlPaginate("selectByName", Page.of(1, 10), qw);
return accountPage;
}
@ -106,7 +113,6 @@ public class AccountController {
}
@GetMapping("/ds")
@UseDataSource("ds2222")
public String ds() {

View File

@ -17,14 +17,13 @@
package com.mybatisflex.test.mapper;
import com.mybatisflex.test.model.Account;
import com.mybatisflex.test.model.AccountDto;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
public interface MyAccountMapper extends AccountMapper {
AccountDto selectByName(@Param("name") String name);
// AccountDto selectByName(@Param("name") String name);
@Select("select * from tb_account where id = #{id} and id =#{id}")
Account selectById(@Param("id") Object id);

View File

@ -7,7 +7,7 @@ spring:
# driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/flex_test
username: root
password: 12345678
password: 123456
# driver-class-name:
# datasource:
# driver-class-name: org.h2.Driver

View File

@ -19,7 +19,11 @@
<!-- selectByName -->
<select id="selectByName" resultType="com.mybatisflex.test.model.AccountDto">
select * from `tb_account` where `user_name` = #{name}
select * from `tb_account` ${qwSql} limit ${pageOffset}, ${pageSize}
</select>
<select id="selectByName_COUNT" resultType="long">
select count(*) from `tb_account` ${qwSql}
</select>
</mapper>