Dao父类,自动查找sql模板

基类
package com.future.common.base;

import java.util.List;
import java.util.Map;

import com.jfinal.aop.Aop;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.SqlPara;

import cn.hutool.core.util.ClassUtil;

/**
 * Dao类的基类,继承此类后能简化Dao层的代码
 * 例如
 * Dao中的代码是
 * package com.test;
 * public class User{
 *   public SysUser getUser(String username){
 * 		return find(username);
 *   }
 * }
 * find(username)会去找key为 com.test.getUser的sql模板执行	
 *
 *
 * Model类型 
 * @param <T>
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
public class BaseDao<T extends Model<T>> {
	/**
	 * 获取model对象,此处不用DB是因为DB会在主数据源中查找sql,不适合多数据源的情况
	 */
	private T t = (T) Aop.get(ClassUtil.getTypeArgument(
			getClass().getName().indexOf("$$EnhancerBy") == -1 ? getClass() : getClass().getSuperclass()));

	public List<T> find(Object... paras) {
		List<T> result = t.find(getSqlPara(paras));
		return result;
	}

	public List<T> find(Map data) {
		List<T> result = t.find(getSqlPara(data));
		return result;
	}

	public T findFirst(Object... paras) {
		return t.findFirst(getSqlPara(paras));
	}

	public T findFirst(Map data) {
		return t.findFirst(getSqlPara(data));
	}

	private SqlPara getSqlPara(Object... paras) {
		return this.t.getSqlPara(getsqlKey(), paras);
	}

	private SqlPara getSqlPara(Map data) {
		return this.t.getSqlPara(getsqlKey(), data);
	}

	/**
	 * 获取sql模板的key,这里key的构成是Dao里面的packageName+className+"."+methodName
	 * @return
	 */
	private String getsqlKey() {
		Class currentClass = getClass();
		//不使用动态代理的情况也适用
		Class useFullClass = currentClass.getName().indexOf("$$EnhancerBy") == -1 ? currentClass
				: currentClass.getSuperclass();
		String className = useFullClass.getName();
		String methodName = "";
		StackTraceElement[] stacktraceItems = Thread.currentThread().getStackTrace();
		for (StackTraceElement item : stacktraceItems) {
			if (item.getClassName().equals(className)) {
				methodName = item.getMethodName();
				break;
			}
		}
		return className + "." + methodName;
	}
}

在Dao中的用法

package com.future.dao;

import com.future.common.base.BaseDao;
import com.future.model.SysUser;

public class SysUserDao extends BaseDao<SysUser>{
	public SysUser findUserByUsername(String username) {
		return findFirst(username);
	}
}

   

sql模板

#namespace("com.future.dao.SysUserDao")
#sql("findUserByUsername")
	SELECT
		*
	FROM
		sys_user
	WHERE
	 username = #para(0)
#end

#end



关注我的公众号,免费获取Java + Jfinal学习视频

image.png


评论区

快乐的蹦豆子

2018-12-24 15:55

有了sqlpara 大家想怎么丰富就怎么丰富里面的方法

JFinal

2018-12-24 15:56

第一次见这种用法,挺有创意,顶

快乐的蹦豆子

2018-12-24 16:19

@JFinal 感谢波总

Dull

2019-08-31 15:31

@JFinal 感觉这种用法可以收进官方源码呀,现在最不方便的就是每次都要去写#namespace #sql() 这些没有意义又繁琐的代码,浪费了不少时间

Dull

2019-08-31 15:40

@JFinal 他这个用了反射,性能是不是不太好呀

Dull

2019-08-31 15:40

而且sql算是热点操作

JFinal

2019-08-31 16:01

@Dull #sql ... #end 这种用法已然比 mybatis 将 sql 放 XML 的用法简单省事多了

如果是模板文件放 sql,总要有个指令来区隔不同的 sql

新版本的 Db.template(...).find() 与 Model.template(...).find() 方法比以前省掉了一半的代码,你可以试一试:
https://www.jfinal.com/doc/5-13

热门分享

扫码入社