欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

首頁綜合 正文
目錄

柚子快報邀請碼778899分享:mybatis實(shí)踐篇(一)

柚子快報邀請碼778899分享:mybatis實(shí)踐篇(一)

http://yzkb.51969.com/

日志(logImpl)

StdOutImpl

Slf4jImpl

引入maven文件

org.slf4j

slf4j-simple

2.0.12

編寫配置文件

org.slf4j.simpleLogger.defaultLogLevel=debug

org.slf4j.simpleLogger.showDateTime=true

org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss

org.slf4j.simpleLogger.levelInBrackets=true

org.slf4j.simpleLogger.logFile=System.out

執(zhí)行器

默認(rèn)執(zhí)行器(SimpleExecutor)

try(SqlSession sqlSession = sqlSessionFactory.openSession()) {

// 使用SqlSession獲取映射器實(shí)例

FullCityMapper mapper = sqlSession.getMapper(FullCityMapper.class);

// 使用映射器執(zhí)行操作

FullCity fullCity = mapper.selectByName("廣東省");

System.out.println("城市的名稱:"+fullCity.getName());

}

重用執(zhí)行器(ReuseExecutor)

try(SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.REUSE)) {

// 使用SqlSession獲取映射器實(shí)例

FullCityMapper mapper = sqlSession.getMapper(FullCityMapper.class);

// 使用映射器執(zhí)行操作

FullCity fullCity = mapper.selectByName("廣東省");

System.out.println("城市的名稱:"+fullCity.getName());

}

批量執(zhí)行器(BatchExecutor)

try(SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) {

// 使用SqlSession獲取映射器實(shí)例

FullCityMapper mapper = sqlSession.getMapper(FullCityMapper.class);

// 使用映射器執(zhí)行操作

FullCity fullCity = mapper.selectByName("廣東省");

System.out.println("城市的名稱:"+fullCity.getName());

}

起別名

配置文件

mapper文件

插件

注解

@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.TYPE)

public @interface Intercepts {

/**

* Returns method signatures to intercept.

*

* @return method signatures

*/

Signature[] value();

}

@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target({})

public @interface Signature {

// Executor.class

Class type();

// update

String method();

// MappedStatement.class, Object.class

Class[] args();

}

主要用到了上面兩個注解:@Intercepts和@Signature 方法名和參數(shù)的定義如下:

時間插件

作用:打印SQL語句執(zhí)行的時間,分析慢查詢原因(一般針對查詢query來說)

package com.wyl.mybatis.intercept;

import cn.hutool.json.JSONArray;

import cn.hutool.json.JSONUtil;

import org.apache.ibatis.binding.MapperMethod;

import org.apache.ibatis.executor.Executor;

import org.apache.ibatis.mapping.BoundSql;

import org.apache.ibatis.mapping.MappedStatement;

import org.apache.ibatis.plugin.Interceptor;

import org.apache.ibatis.plugin.Intercepts;

import org.apache.ibatis.plugin.Invocation;

import org.apache.ibatis.plugin.Signature;

import org.apache.ibatis.session.ResultHandler;

import org.apache.ibatis.session.RowBounds;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;

import java.util.HashMap;

import java.util.Map;

/**

* @Description 時間插件

* @Author WuYiLong

* @Date 2024/2/29 9:51

*/

@Intercepts({@Signature(

type = Executor.class,

method = "query",

args = {

MappedStatement.class,

Object.class,

RowBounds.class,

ResultHandler.class

})})

public class TimeIntercept implements Interceptor {

private final static Logger log = LoggerFactory.getLogger(TimeIntercept.class);

@Override

public Object intercept(Invocation invocation) throws Throwable {

Object[] args = invocation.getArgs();

MappedStatement ms = (MappedStatement)args[0];

MapperMethod.ParamMap pm = ( MapperMethod.ParamMap) args[1];

Map paramsMap = new HashMap<>();

pm.forEach((k,v)->{

String key = String.valueOf(k);

if(!key.contains("param")) {

paramsMap.put(String.valueOf(k),v);

}

});

BoundSql boundSql = ms.getBoundSql(ms.getParameterMap());

// sql執(zhí)行之前

long startTime = System.currentTimeMillis();

Object proceed = invocation.proceed();

JSONArray jsonArray = JSONUtil.parseArray(proceed);

long endTime = System.currentTimeMillis();

log.info("----sql執(zhí)行語句: {}",boundSql.getSql());

log.info("----sql輸入?yún)?shù): {}", JSONUtil.toJsonStr(paramsMap));

log.info("----sql輸出結(jié)果數(shù): {}", jsonArray.size());

log.info("----sql執(zhí)行花費(fèi)時間: {}", (endTime-startTime)/1000);

// sql執(zhí)行之后

return proceed;

}

}

分頁插件

FullCityMapper mapper = sqlSession.getMapper(FullCityMapper.class);

for (int i = 1; i <= 3 ; i++) {

Page page = new Page<>(i, 10);

List fullCities = mapper.selectFullCityPage(page);

log.info("當(dāng)前頁:{}",page.getCurrentPage());

log.info("頁數(shù):{}",page.getPageSize());

log.info("總數(shù):{}",page.getTotal());

log.info("列表:{}", JSONUtil.toJsonStr(fullCities));

}

作用:mysql數(shù)據(jù)庫物理分頁,簡化分頁流程

package com.wyl.mybatis.page;

import java.util.List;

/**

* @Description

* @Author WuYiLong

* @Date 2024/3/13 13:48

*/

public class Page {

private Integer currentPage = 1;

private Integer pageSize = 10;

private Integer total;

private List records;

public Page(Integer currentPage,Integer pageSize) {

this.currentPage = currentPage;

this.pageSize = pageSize;

}

public Page(){};

public Integer getCurrentPage() {

return currentPage;

}

public void setCurrentPage(Integer currentPage) {

this.currentPage = currentPage;

}

public Integer getPageSize() {

return pageSize;

}

public void setPageSize(Integer pageSize) {

this.pageSize = pageSize;

}

public Integer getTotal() {

return total;

}

public void setTotal(Integer total) {

this.total = total;

}

public List getRecords() {

return records;

}

public void setRecords(List records) {

this.records = records;

}

}

/**

* 分頁

* @param page

* @return

*/

@Select("select * from d_full_city")

List selectFullCityPage(@Param("page") Page page);

package com.wyl.mybatis.intercept;

import cn.hutool.db.sql.SqlBuilder;

import com.alibaba.druid.DbType;

import com.alibaba.druid.sql.SQLUtils;

import com.alibaba.druid.sql.ast.SQLStatement;

import com.alibaba.druid.sql.ast.statement.SQLSelectStatement;

import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock;

import com.wyl.mybatis.config.SqlSessionFactoryConfig;

import com.wyl.mybatis.page.Page;

import com.wyl.mybatis.util.SqlParamUtil;

import org.apache.ibatis.cache.CacheKey;

import org.apache.ibatis.executor.Executor;

import org.apache.ibatis.mapping.BoundSql;

import org.apache.ibatis.mapping.MappedStatement;

import org.apache.ibatis.plugin.*;

import org.apache.ibatis.session.ResultHandler;

import org.apache.ibatis.session.RowBounds;

import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactory;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.util.List;

import java.util.Map;

/**

* @Description

* @Author WuYiLong

* @Date 2024/3/13 12:06

*/

@Intercepts({

@Signature(

type = Executor.class,

method = "query",

args = {

MappedStatement.class,

Object.class,

RowBounds.class,

ResultHandler.class

}),

@Signature(

type = Executor.class,

method = "query",

args = {MappedStatement.class,

Object.class,

RowBounds.class,

ResultHandler.class,

CacheKey.class,

BoundSql.class})})

public class PageIntercept implements Interceptor {

private final static Logger log = LoggerFactory.getLogger(PageIntercept.class);

@Override

public Object intercept(Invocation invocation) throws Throwable {

Executor executor = (Executor) invocation.getTarget();

Object[] args = invocation.getArgs();

MappedStatement ms = (MappedStatement) args[0];

Object params = args[1];

RowBounds rowBounds = (RowBounds) args[2];

BoundSql boundSql = ms.getBoundSql(params);

String sql = boundSql.getSql();

ResultHandler resultHandler = (ResultHandler) args[3];

Page page = null;

Map paramMap = SqlParamUtil.filter(params);

for (Map.Entry mapEntry : paramMap.entrySet()) {

Object v = mapEntry.getValue();

if (v instanceof Page) {

page = (Page) v;

}

}

if(page != null) {

String countSql = countSql(sql);

int count = 0;

SqlSessionFactory sqlSessionFactory = SqlSessionFactoryConfig.buildSqlSessionFactory();

try (SqlSession sqlSession = sqlSessionFactory.openSession()) {

Connection connection = sqlSession.getConnection();

PreparedStatement preparedStatement = connection.prepareStatement(countSql);

ResultSet resultSet = preparedStatement.executeQuery();

while (resultSet.next()) {

count = resultSet.getInt("count");

}

}

page.setTotal(count);

rowBounds = new RowBounds(page.getCurrentPage()-1,page.getPageSize());

}

CacheKey cacheKey;

if (args.length == 4) {

cacheKey = executor.createCacheKey(ms, params, rowBounds, boundSql);

} else {

cacheKey = (CacheKey) args[4];

boundSql = (BoundSql) args[5];

}

List query = executor.query(ms, params, rowBounds, resultHandler, cacheKey, boundSql);

return query;

}

@Override

public Object plugin(Object target) {

if (target instanceof Executor) {

return Plugin.wrap(target, this);

}

return target;

}

private String countSql(String sql) {

SqlBuilder sqlBuilder = new SqlBuilder();

sqlBuilder.select("count(*) count");

List sqlStatements = SQLUtils.parseStatements(sql, DbType.mysql);

SQLSelectStatement sqlStatement = (SQLSelectStatement) sqlStatements.get(0);

MySqlSelectQueryBlock queryBlock = (MySqlSelectQueryBlock) sqlStatement.getSelect().getQueryBlock();

sqlBuilder.from(queryBlock.getFrom().toString());

if (queryBlock.getWhere() != null) {

sqlBuilder.where(queryBlock.getWhere().toString());

}

return sqlBuilder.build();

}

}

這里需要注意的是CacheKey緩存key,因?yàn)閟ql的變化直接影響了查詢的輸出,從上面可以看出分頁參數(shù),是不需要用戶輸入的,通過內(nèi)置分頁插件即可完成分頁,所以說sql實(shí)質(zhì)上是沒有發(fā)生變化的,從而導(dǎo)致重新生成的緩存key都是一樣的,如源碼所示:

@Override

public CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql) {

if (closed) {

throw new ExecutorException("Executor was closed.");

}

CacheKey cacheKey = new CacheKey();

cacheKey.update(ms.getId());

cacheKey.update(rowBounds.getOffset());

cacheKey.update(rowBounds.getLimit());

cacheKey.update(boundSql.getSql());

List parameterMappings = boundSql.getParameterMappings();

TypeHandlerRegistry typeHandlerRegistry = ms.getConfiguration().getTypeHandlerRegistry();

// mimic DefaultParameterHandler logic

for (ParameterMapping parameterMapping : parameterMappings) {

if (parameterMapping.getMode() != ParameterMode.OUT) {

Object value;

String propertyName = parameterMapping.getProperty();

if (boundSql.hasAdditionalParameter(propertyName)) {

value = boundSql.getAdditionalParameter(propertyName);

} else if (parameterObject == null) {

value = null;

} else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {

value = parameterObject;

} else {

MetaObject metaObject = configuration.newMetaObject(parameterObject);

value = metaObject.getValue(propertyName);

}

cacheKey.update(value);

}

}

if (configuration.getEnvironment() != null) {

// issue #176

cacheKey.update(configuration.getEnvironment().getId());

}

return cacheKey;

}

看到了cacheKey的update方法,所以我們只需要每次請求改變其中之一即可,很明顯,我們改變下RowBounds對象的參數(shù)就好,這個對象也是控制行數(shù)的,從它的名字就可以直接看出來。

項(xiàng)目地址

demo地址

柚子快報邀請碼778899分享:mybatis實(shí)踐篇(一)

http://yzkb.51969.com/

精彩文章

評論可見,查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場。

轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://gantiao.com.cn/post/18912349.html

發(fā)布評論

您暫未設(shè)置收款碼

請?jiān)谥黝}配置——文章設(shè)置里上傳

掃描二維碼手機(jī)訪問

文章目錄