编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

《tkMybatis进阶(sql监控+业务监控+添加cache缓存)》

wxchong 2024-07-16 10:08:26 开源技术 16 ℃ 0 评论

生活语录:别人下一代活得像自己一样窝囊。

记得有人说过:别人快的时候,你要学会慢下来!

一、目录

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。

 /**
     * 方式一 使用自带的查询
     * 主要涉及对象 Criteria 和 Example
     * @date 2020-05-07
     * @param account
     * @return
     */
     default List<UserInfo> 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);
    }

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

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

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

2.1.3、使用自带方法

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

2.2、添加监控

2.2.1、封装自己的Mapper

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

2.2.2、注入自定义SQLMapper


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

	@Select("<script>${sql}</script>")
	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;
	}
}

2.2.3、自定义SQLMapperProvider

/**
 * note:映射script
 * @ExampleProvider
 */
public class SQLMapperProvider {
	/**
	 * note:多表关联查询方法
	 * @param relationWhere 关联表间的条件
	 * @param weekendList   查询对象集
	 * @return
	 */
	public String getSelectSQL(String relationWhere, Weekend... weekendList) {
		List<EntityTable> tableList = new ArrayList<EntityTable>();
		List<String> whereList = new ArrayList<String>();

		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();
	}
}

2.2.4封装service层

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

	Boolean create(T entity);

	Boolean updateById(T entity);

	T get(T entity);

	T getById(T id);

	int count(T entity);

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

	List<T> listAll();

	Boolean deleteById(T id);
}

2.2.5、封装MyBaseService

/**
 * note:Service基础类
 * 
 */
public abstract class MyBaseService<T> {

	@Autowired(required = false)
	protected MyBaseMapper<T> mapper;

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

2.2.6、封装业务ServiceTemlate 添加业务层监控

Slf4j
public abstract class ServiceTemplate<T> {

	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();
		}
	}
}

2.2.7、业务层调用

/**
 * 业务层
 * 2020-05-06
 *
 */
@Service
public class UserInfoServiceImpl extends BaseService<UserInfo> 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;
    }

2.2.8、Mapper层调用

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

    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);

2.3、添加查询缓存

2.3.1、引入maven

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alicp.jetcache/jetcache-starter-redis -->
		<dependency>
		    <groupId>com.alicp.jetcache</groupId>
		    <artifactId>jetcache-starter-redis</artifactId>
		    <version>2.5.13</version>
		</dependency>

2.3.2、添加redis及jetcache配置

#缓存设置
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

2.3.3、引入业务层缓存

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);

2.4、tk-mybtais和mybatis-plus的区别。

#-----------mybatis-plus----------------
# mybatis-plus 支持热加载 。
# mybatis-plus内置代码生成器。
# mybatis-plus内置分页插件。
# mybatis-plus内置性能解析插件 对于update delete 有只能分析阻断策略。
# mybatis-plus内置sql注入剥离器 ,防止sql注入攻击。
#-----------tk-mybatis----------------
# tk-mybatis 自带乐观锁
# tk-mybatis 支持pagehelper

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表