《tkMybatis進階(sql監控+業務監控+添加cache緩存)》

生活語錄:別人下一代活得像自己一樣窩囊。

記得有人說過:別人快的時候,你要學會慢下來!

一、目錄

1.1、tk-mybtais的使用案例(三種例子)。

1.2、tk-mybtatis接入監控。

1.3、添加cache緩存。

1.4、tk-mybtais和mybatis-plus的區別。

二、接入步驟

2.1、tk-mybatis使用案例。

2.1.1、使用自帶對象查詢類似jpa和mybtais-plus。

<code> /**
     * 方式一 使用自帶的查詢
     * 主要涉及對象 Criteria 和 Example
     * @date 2020-05-07
     * @param account
     * @return
     */
     default List getUserInfoByParam(String account){
        Example example = new Example(UserInfo.class);
        Example.Criteria criteria =example.createCriteria();
        if(StringUtils.isEmpty(account)){
            criteria.andEqualTo("account",account);
        }
        return selectByExample(example);
    }/<code>

2.1.2、配置xml文件,和mybatis一致。

<code>/**
     * 方式二 和 mybatis 一致
     *  步驟:
     *   (1)需要配置xml
     *  (2)在配置文件中指定xml 路徑
     * @param account
     */
    UserInfo getUserInfoByAccount(@Param("account") String account);/<code>

注:添加xml 文件,application指定路徑。

2.1.3、使用自帶方法

<code>    /**
     * 方式三
     *  直接使用內置方法
     * @param uid
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class,timeout = 10)
    @Override
    public UserInfo getUserInfo(Long uid) {
        return userInfoMapper.selectByPrimaryKey(uid);
    }/<code> 

2.2、添加監控

2.2.1、封裝自己的Mapper

<code>/**
 * 封裝自己的   MyBaseMapper
 * @param 
 */
public interface MyBaseMapper extends Mapper, MySqlMapper {
    
}/<code>

2.2.2、注入自定義SQLMapper

<code>
@tk.mybatis.mapper.annotation.RegisterMapper
public interface SQLMapper {

	@Select(" ")
	T executeSQL(@Param("sql") String sql);
	
	public default T execute(String relationWhere, Weekend... weekendList) {
		String sql = null;
		try {
			SQLMapperProvider provider = new SQLMapperProvider();
			sql = provider.getSelectSQL(relationWhere, weekendList);
		}catch(Exception ex) {
			ex.printStackTrace();
		}
		if(!StringUtils.isEmpty(sql)) {
			return executeSQL(sql);
		}
		return null;
	}
}/<code>

2.2.3、自定義SQLMapperProvider

<code>/**
 * note:映射script
 * @ExampleProvider
 */
public class SQLMapperProvider {
	/**
	 * note:多表關聯查詢方法
	 * @param relationWhere 關聯表間的條件
	 * @param weekendList   查詢對象集
	 * @return
	 */
	public String getSelectSQL(String relationWhere, Weekend... weekendList) {
		List tableList = new ArrayList();
		List whereList = new ArrayList();

		StringBuilder sql = new StringBuilder("SELECT ");
		if(weekendList[0].isDistinct()) {
			sql.append("distinct ");
		}

		for (int i = 0; i < weekendList.length; i++) {
			EntityTable entityTable = EntityHelper.getEntityTable(weekendList[i].getEntityClass());
			if(!ObjectUtils.isEmpty(entityTable)) {
				// 條
				if (i > 0) {
					sql.append(",");
				}
				String columnSQL = EntityHelper.getSelectColumns(weekendList[i].getEntityClass());
				String[] columns = columnSQL.split(",");
				// 段
				for (int num = 0; num < columns.length; num++) {
					if (num > 0) {
						sql.append(",");
					}
					sql.append(entityTable.getName() + "." + columns[num]);
				}
				
				// where
				if(!CollectionUtils.isEmpty(weekendList[i].getOredCriteria())) {
					whereList.add(weekendList[i].getOredCriteria()
							.stream().map(criteriaList->criteriaList.getCriteria()
							.stream().map(
										criteria -> entityTable.getName() + "." 
										+ criteria.getCondition()
										+ ((criteria.getValue() instanceof String)?"'"+criteria.getValue()+"'":criteria.getValue())
									)
								.collect(Collectors.joining(" and "))
							).collect(Collectors.joining(" and ")));
				}
				tableList.add(entityTable);
			}
		}
		sql.append(" FROM " + tableList.stream().map(table -> table.getName()).collect(Collectors.joining(",")));

		// condition
//      sql.append(SqlHelper.exampleWhereClause());		兼容count翻頁問題
		String where = "";
		if(!CollectionUtils.isEmpty(whereList)) {
			where = whereList.stream().collect(Collectors.joining(" and "));
		}
		if(!StringUtils.isEmpty(where) || !StringUtils.isEmpty(relationWhere)) {
			sql.append(" WHERE ");
			if(!StringUtils.isEmpty(where)) {
				sql.append(where);
				
				if(!StringUtils.isEmpty(relationWhere)) {
					sql.append(" and ");
				}
			}
			if(!StringUtils.isEmpty(relationWhere)) {
				sql.append(relationWhere);
			}
		}
		// order
		sql.append(SqlHelper.orderByDefault(weekendList[0].getEntityClass()));
		return sql.toString();
	}
}/<code>

2.2.4封裝service層

<code>/**
 * Service接口類
 * @date 2020-05-07
 */
public interface BaseInterfaceService {

	Boolean create(T entity);

	Boolean updateById(T entity);

	T get(T entity);

	T getById(T id);

	int count(T entity);

	List list(T entity, int pageNum, int pageSize);

	List listAll();

	Boolean deleteById(T id);
}
/<code>

2.2.5、封裝MyBaseService

<code>/**
 * note:Service基礎類
 * 
 */
public abstract class MyBaseService {

	@Autowired(required = false)
	protected MyBaseMapper mapper;

	public Boolean create(T entity) {
		int count = this.mapper.insertSelective(entity);
		return count == 0? false: true;
	}
}/<code>

2.2.6、封裝業務ServiceTemlate 添加業務層監控

<code>Slf4j
public abstract class ServiceTemplate {

	protected String monitorKey;

	protected ServiceTemplate(String monitorKey) {
		this.monitorKey = monitorKey;
	}

	protected ServiceTemplate(String monitoryKey, String monitorType) {
		this.monitorKey = monitoryKey;
	}

	/**
	 * AOP統一記監控
	 */
	protected ServiceTemplate() {
	}

	protected abstract void checkParams();

	protected abstract T process();

	protected void afterProcess() {
	}

	protected void onSuccess() {
	}

	protected void onServiceException(Exception e) {
		log.warn("執行邏輯異常 monitoryKey={}, msg={}", monitorKey, e.getMessage(), e);
		throw new ServiceException(e.getMessage());
	}

	protected void onServiceCodeException(ServiceException e) {
		log.warn("執行邏輯異常 monitoryKey={}, code={}, msg={}", monitorKey, e.getCode(), e.getMsg(), e);
		throw e;
	}

	protected void onError(Throwable e) {
		log.error("執行邏輯異常 monitoryKey={}", monitorKey, e);
		throw new ServiceException(RespCode.SYSTEM_ERROR.getErrorCode(), RespCode.SYSTEM_ERROR.getErrorMsg());
	}

	public T execute() {
		if (monitorKey==null || monitorKey.equals("")) {
			return doExecute();
		} else {
			// TODO Monitor
			return doExecute();
		}
	}

	protected T doExecute() {
		try {
			checkParams();
		} catch (IllegalArgumentException e) {
			if (log.isDebugEnabled()) {
				log.debug("校驗參數失敗", e);
			} else {
				log.info("校驗參數失敗: " + e.getMessage());
			}
			throw new ServiceException(RespCode.COMMON_PARAM_ERROR.getErrorCode(),
					RespCode.COMMON_PARAM_ERROR.getErrorMsg() + e.getMessage(), e);
		} catch (ServiceException e) {
			log.error("校驗參數失敗:" + e.getMsg());
			throw e;
		}

		try {
			T result = process();
			onSuccess();
			return result;
		} catch (ServiceException e) {
			onServiceCodeException(e);
			return null;
		} catch (Throwable e) {
			onError(e);
			return null;
		} finally {
			afterProcess();
		}
	}
}/<code>

2.2.7、業務層調用

<code>/**
 * 業務層
 * 2020-05-06
 *
 */
@Service
public class UserInfoServiceImpl extends BaseService implements UserInfoService {

    @Autowired(required = false)
    private UserInfoMapper userInfoMapper;

    @Override
    public boolean updateUserInfo(UserInfo userInfo){
        Integer update = userInfoMapper.updateUserInfo(userInfo.getAccount(), userInfo.getUserName(),
                userInfo.getPhone(), userInfo.getUid());
        return update > 0;
    }/<code>

2.2.8、Mapper層調用

<code>/**
 * 接入 tk-mybatis
 *
 */
@org.apache.ibatis.annotations.Mapper
public interface UserInfoMapper extends MyBaseMapper {

    default Integer  updateUserInfo(String account,String userName,String phone,Long uid){
        StringBuffer sqlSb = new StringBuffer();
        StringBuffer whereSB = new StringBuffer();
        sqlSb.append("account = "+account+",");
        sqlSb.append("username = "+userName+",");
        sqlSb.append("phone = "+phone+",");
        whereSB.append("where uid = "+uid);
        sqlSb.append(whereSB.toString());
        return update(sqlSb.toString());
    }

    @Update("update user_info set ${sql}")
    Integer update(@Param("sql") String sql);/<code>

2.3、添加查詢緩存

2.3.1、引入maven

<code>
            org.springframework.boot
            spring-boot-starter-data-redis
        
         
		
		    com.alicp.jetcache
		    jetcache-starter-redis
		    2.5.13
		/<code>

2.3.2、添加redis及jetcache配置

<code>#緩存設置
jetcache:
  statIntervalMinutes: 15
  areaInCacheName: false
  remote:
    default:
      type: redis
      keyConvertor: fastjson
      valueEncoder: kryo
      valueDecoder: kryo
      poolConfig:
        minIdle: 5
        maxIdle: 20
        maxTotal: 50
      database: 1
  #jetcache使用
  redis:
    database: 0
    host: 127.0.0.1
    port: 6379
    password: qwe123456

    lettuce:
      pool:
        max-idle: 10
        min-idle: 0
        max-wait-millis: 1000
        max-total: 20/<code>

2.3.3、引入業務層緩存

<code>import com.alicp.jetcache.anno.Cached;
import com.cloud.user.entity.UserInfo;

import java.util.concurrent.TimeUnit;

public interface UserInfoService {
    /**
     * 緩存用戶信息
     * @param uid
     * @return
     */
    @Cached(expire = 10,timeUnit = TimeUnit.SECONDS)
    UserInfo getUserInfo(Long uid);/<code>

2.4、tk-mybtais和mybatis-plus的區別。

<code>#-----------mybatis-plus----------------
# mybatis-plus 支持熱加載 。
# mybatis-plus內置代碼生成器。
# mybatis-plus內置分頁插件。
# mybatis-plus內置性能解析插件 對於update delete 有隻能分析阻斷策略。
# mybatis-plus內置sql注入剝離器 ,防止sql注入攻擊。
#-----------tk-mybatis----------------
# tk-mybatis 自帶樂觀鎖
# tk-mybatis 支持pagehelper/<code>


分享到:


相關文章: