1. 程式人生 > 其它 >Java mysql語句動態執行、分頁和獲取總數

Java mysql語句動態執行、分頁和獲取總數

技術標籤:javamysqljava

Java mysql語句動態執行、分頁和獲取總數

目錄

1,動態執行

2,分頁

1,Mysql的分頁:

從零開始:

方式一:

方式二:offset

通用的規律:

3,綜合的例子:

需求:

實現:

引數:SheetQuery

返回值:SheetResult

正則替換類:RegUtils

服務:SheetService

Mapper和xml

測試:

總結:


1,動態執行

使用mybatis

SheetService:

@Resource
private SheetSourceMapper sheetSourceMapper;



String sqlParam = "select * from account"
List<Map<String,Object>> result = excuteSoureSql(sqlParam);

public List<Map<String,Object>> excuteSoureSql(String sqlParam){
 return sheetSourceMapper.executeSql(sqlParam);
}
ReportSourceMapper:
List<Map<String, Object>> executeSql(@Param("sqlParameter") String sqlParameter);
Xml:
<select id="executeSql" resultType="map">

 ${sqlParameter}

</select>

這邊注意 Mapper @Param("sqlParameter") 引數名的說明

2,分頁

1,Mysql的分頁:

從零開始:

比如: branch 有四條資料:

SELECT * FROM branch LIMIT 0, 5 ;

SELECT * FROM branch LIMIT 1, 5 ;

這時候就只有3條。 確認是從零開始計算的

方式一:

SELECT * FROM account LIMIT 0, 6 ;

LIMIT 0, 6: 0 變成開始的數字, 6表示限定的條數

方式二:offset

SELECT * FROM account LIMIT 6 OFFSET 0 ;

LIMIT 6 OFFSET 0 : 6表示限定的條數, offset 偏移量,0 表示開始的數字

這個更好理解,限制返回多少條,偏移多少,即從第xx開始

通用的規律:

假設pageSize表示每頁要顯示的條數,pageNumber表示頁碼。

設定pageNumber從數字1開始,比如限定的size為10:

第一頁: page: 1, size: 10; 即: 0-9

第二頁: page: 2, size: 10; 即: 10-19

第三頁: page: 3, size: 10; 即: 20-39

方式一:

SELECT * FROM account LIMIT (pageNumber-1)*pageSize,pageSize;

方式二:

SELECT * FROM account LIMIT pageSize OFFSET (pageNumber-1)*pageSize;

如果pageNumber是從0開始,就不用減1了。看具體情況而定

3,綜合的例子:

需求:

請求引數

typeId

page 當前頁數,為空不分頁

size 每頁大小,為空不分頁

param:{} 動態查詢引數

要求:

根據typeId動態獲取要查詢的值進行動態匹配後,再執行sql

比如: SELECT * FROM employee where f_name=$param.name anddept_id=$global.DEPT_ID

實現:

先宣告引數和返回值:

引數:SheetQuery

public class SheetQuery {

 private Long classId;

 private Integer page;

 private Integer size;

 private Map<String,Object> param = new HashMap<>();

 public Long getClassId() {
 return classId;
 }

 public void setClassId(Long classId) {
 this.classId = classId;
 }

 public Integer getPage() {
 return page;
 }

 public void setPage(Integer page) {
 this.page = page;
 }

 public Integer getSize() {
 return size;
 }

 public void setSize(Integer size) {
 this.size = size;
 }

 public Map<String, Object> getParam() {
 return param;
 }

 public void setParam(Map<String, Object> param) {
 this.param = param;
 }

}

返回值:SheetResult

public class SheetResult {

 private Long total;

 private Object data;

 public Long getTotal() {
 return total;
 }

 public void setTotal(Long total) {
 this.total = total;
 }

 public Object getData() {
 return data;
 }

 public void setData(Object data) {
 this.data = data;
 }
}

正則替換類:RegUtils

public class RegUtils {

 public static String getReplaceStr(String content, Map<String, Object> param)
 {
 String pattern = "\\$[a-zA-Z_]*\\.([a-zA-Z_]*)";
 Pattern p = Pattern.compile(pattern);
 Matcher m = p.matcher(content);
 StringBuffer sb = new StringBuffer();
 while (m.find())
 {
 String key = m.group(1);
 String value = MapUtils.getString(param, key);
 m.appendReplacement(sb, value == null ? "" : ("\"").concat(value).concat("\""));
 }

 m.appendTail(sb);
 return sb.toString();
 }

}

服務:SheetService

@Service
public class SheetService {

 @Resource
 private SheetSourceMapper sheetSourceMapper;

 public SheetResult getSheetResult(SheetQuery sheetQuery){
 //替換表示式的引數
 // 根據typeId動態獲取,這邊就直接賦值
 String sqlExpr = "SELECT * FROM employee where f_name=$param.name and dept_id=$global.DEPT_ID";
 String sqlStr = RegUtils.getReplaceStr(sqlExpr, sheetQuery.getParam());
 String sqlParam = sqlStr.concat(appendSqlParam(sheetQuery));
 SheetResult sheetResult = new SheetResult();
 List<Map<String,Object>> result = excuteSoureSql(sqlParam);
 sheetResult.setTotal(getSqlTotal(sqlStr));
 sheetResult.setData(result);
 return sheetResult;
 }

 // 獲取總數
 private long getSqlTotal(String sqlStr){
 // 處理from可能是小寫的情況
 String splitStr = "FROM";

 if(!sqlStr.contains(splitStr)){
 splitStr = "from";
 }
 String[] wheres = sqlStr.split(splitStr);
 String sqlParam = "select count(*) as total from ".concat(wheres[1]);
 List<Map<String,Object>> result = excuteSoureSql(sqlParam);
 Map<String, Object> totalMap = ListUtils.emptyIfNull(result).stream().findFirst().orElse(new HashMap<>());
 return MapUtils.getLongValue(totalMap,"total");
 }

 // 拼接分頁的查詢內容
 private String appendSqlParam(SheetQuery sheetQuery){
 Integer pageNumber = sheetQuery.getPage();
 Integer pageSize = sheetQuery.getSize();
 String limitStr = "";
 // 如果size 為空就直接分頁
 if (!Objects.isNull(pageSize)) {
 // pageNumber從1開始
 if(Objects.isNull(pageNumber) || pageNumber.equals(NumberUtils.INTEGER_ZERO)){
 pageNumber = NumberUtils.INTEGER_ONE;
 }
 limitStr = " limit "+ ((pageNumber-1)*pageSize) + ", "+ pageSize;
 }

 return limitStr;
 }

 public List<Map<String,Object>> excuteSoureSql(String sqlParam){
 return sheetSourceMapper.executeSql(sqlParam);
 }

}

Mapper和xml

Mapper:

public interface SheetSourceMapper {
 List<Map<String, Object>> executeSql(@Param("sqlParameter") String sqlParameter);
}

xml:

<select id="executeSql" resultType="map">
 ${sqlParameter}
</select>

測試:

@RunWith(SpringRunner.class)
@SpringBootTest
public class SheetApplicationTests {

 @Autowired
 private SheetService sheetService;


 @Test
 public void testSheetResult() {
 SheetQuery sheetQuery = new SheetQuery();
 int page = 0;
 int size = 10;
 Map<String,Object> param = new HashMap<>();
 param.put("name","Robert");
 param.put("DEPT_ID",1);
 sheetQuery.setPage(page);
 sheetQuery.setSize(size);
 sheetQuery.setParam(param);
 sheetService.getSheetResult(sheetQuery);

 }

}

備註: 這個是在springboot專案測試的,啟動的時候例項化service

可以從 建立spring專案 直接建一個springboot專案,再引入對應的包就行

總結:

在獲取總數的時候,也想過用一次查詢的時候,網上查了下使用:SELECT found_rows() AS recordCounts; 但是這種方式,我試驗的時候並沒有獲取到全部,就放棄了。

Mysql分頁的時候,注意從0開始。其它嘛,根據需求去寫。