![JAR search and dependency download from the Maven repository](/logo.png)
com.centit.framework.jdbc.dao.BaseDaoImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of centit-persistence-jdbc Show documentation
Show all versions of centit-persistence-jdbc Show documentation
南大先腾自己的Orm框架,借用spring-jdbc管理链接和事物
package com.centit.framework.jdbc.dao;
import com.alibaba.fastjson.JSONArray;
import com.centit.framework.core.dao.CodeBook;
import com.centit.framework.core.dao.ExtendedQueryPool;
import com.centit.framework.core.dao.QueryParameterPrepare;
import com.centit.framework.core.po.EntityWithDeleteTag;
import com.centit.support.algorithm.ListOpt;
import com.centit.support.algorithm.NumberBaseOpt;
import com.centit.support.algorithm.ReflectionOpt;
import com.centit.support.algorithm.StringBaseOpt;
import com.centit.support.compiler.Lexer;
import com.centit.support.database.jsonmaptable.GeneralJsonObjectDao;
import com.centit.support.database.metadata.SimpleTableField;
import com.centit.support.database.metadata.SimpleTableReference;
import com.centit.support.database.orm.JpaMetadata;
import com.centit.support.database.orm.OrmDaoUtils;
import com.centit.support.database.orm.TableMapInfo;
import com.centit.support.database.utils.PageDesc;
import com.centit.support.database.utils.PersistenceException;
import com.centit.support.database.utils.QueryAndNamedParams;
import com.centit.support.database.utils.QueryUtils;
import com.centit.support.file.FileType;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.Triple;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.CannotGetJdbcConnectionException;
import org.springframework.jdbc.core.ConnectionCallback;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceUtils;
import javax.annotation.Resource;
import javax.sql.DataSource;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.util.*;
@SuppressWarnings({"unused","unchecked"})
public abstract class BaseDaoImpl {
protected static Logger logger = LoggerFactory.getLogger(BaseDaoImpl.class);
private Class> poClass = null;
private Class> pkClass = null;
protected Map filterField = null;
protected JdbcTemplate jdbcTemplate;
/**
* Set the JDBC DataSource to obtain connections from.
* @param dataSource 数据源
*/
@Resource
public void setDataSource(DataSource dataSource) {
if (this.jdbcTemplate == null || dataSource != this.jdbcTemplate.getDataSource()) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
}
/**
* 获取spring jdbc 的 jdbcTemplate
* @return JdbcTemplate
*/
public JdbcTemplate getJdbcTemplate() {
return this.jdbcTemplate;
}
/**
* 获取数据源 这个一般不要使用
* @return DataSource
*/
public DataSource getDataSource() {
return (this.jdbcTemplate != null ? this.jdbcTemplate.getDataSource() : null);
}
/**
* Get a JDBC Connection, either from the current transaction or a new one.
* 请不要使用这个方法,我们一般获取jdbcTemplate来操作数据库
* @return the JDBC Connection
* @throws CannotGetJdbcConnectionException if the attempt to get a Connection failed
* @see org.springframework.jdbc.datasource.DataSourceUtils#getConnection(javax.sql.DataSource)
*/
public Connection getConnection() throws CannotGetJdbcConnectionException {
return DataSourceUtils.getConnection(getDataSource());
}
/**
* Close the given JDBC Connection, created via this DAO's DataSource,
* if it isn't bound to the thread.
*
* @param con Connection to close
* @see org.springframework.jdbc.datasource.DataSourceUtils#releaseConnection
*/
public void releaseConnection(Connection con) {
DataSourceUtils.releaseConnection(con, getDataSource());
}
private void fetchTypeParams() {
ParameterizedType genType = (ParameterizedType) getClass()
.getGenericSuperclass();
Type[] params = genType.getActualTypeArguments();
poClass = ((Class>) params[0]);
pkClass = ((Class>) params[1]);
}
public Class> getPoClass() {
//return this.getClass().getTypeParameters()[0];
if (poClass == null) {
fetchTypeParams();
}
return poClass;
}
public Class> getPkClass() {
if (pkClass == null) {
fetchTypeParams();
}
return pkClass;
}
public String encapsulateFilterToSql(String filterQuery) {
//QueryUtils.hasOrderBy(filterQuery)
TableMapInfo mapInfo = JpaMetadata.fetchTableMapInfo(getPoClass());
if (mapInfo == null)
throw new PersistenceException(PersistenceException.ORM_METADATA_EXCEPTION,
"没有对应的元数据信息:" + getPoClass().getName());
return "select " + GeneralJsonObjectDao.buildFieldSql(mapInfo, null) +
" from " + mapInfo.getTableName() +
" where 1=1 {" + mapInfo.getTableName() + "}" + filterQuery +
(StringUtils.isBlank(mapInfo.getOrderBy()) ? "" : " order by " + mapInfo.getOrderBy())
;
}
/**
* 可以在外部注入查询语句来屏蔽内部标量getFilterField中定义的查询语句
* @return 外部语句
*/
public String getExtendFilterQuerySql() {
return ExtendedQueryPool.getExtendedSql(
FileType.getFileExtName(getPoClass().getName()) + "_QUERY_0");
}
/**
* 分析参数,这个主要用于解释,分析参数前面括号中的预处理标识
* @param sParameter 传入的参数
* @return ImmutablePair < String, String >
*/
protected static ImmutablePair parseParameter(String sParameter) {
int e = sParameter.indexOf(')');
if (e > 0) {
int b = sParameter.indexOf('(') + 1;
/* b = b<0 ? 0 : b+1;*/
String paramPretreatment = sParameter.substring(b, e).trim();
String paramAlias = sParameter.substring(e + 1).trim();
return new ImmutablePair<>(paramAlias, paramPretreatment);
} else
return new ImmutablePair<>(sParameter, null);
}
public static Map>
getFilterFieldWithPretreatment(Map fieldMap) {
if (fieldMap == null)
return null;
Map> filterFieldWithPretreatment =
new HashMap<>(fieldMap.size() * 2);
for (Map.Entry ent : fieldMap.entrySet()) {
if (StringUtils.isNotBlank(ent.getKey())) {
ImmutablePair paramMeta =
parseParameter(ent.getKey());
filterFieldWithPretreatment.put(paramMeta.left,
new ImmutablePair<>(ent.getValue(), paramMeta.getRight()));
}
}
return filterFieldWithPretreatment;
}
public static String translatePropertyNameToColumnName(TableMapInfo mapInfo, String sql, String alias) {
StringBuilder sqlb = new StringBuilder();
Lexer lex = new Lexer(sql, Lexer.LANG_TYPE_SQL);
boolean needTranslate = true;
int prePos = 0;
int preWordPos = 0;
String aWord = lex.getAWord();
boolean addAlias = StringUtils.isNotBlank(alias);
//skeep to |
if ("[".equals(aWord)) {
aWord = lex.getAWord();
while (aWord != null && !"".equals(aWord) && !"|".equals(aWord)) {
if ("(".equals(aWord)) {
lex.seekToRightBracket();
}
aWord = lex.getAWord();
}
}
while (aWord != null && !"".equals(aWord)) {
if ("select".equalsIgnoreCase(aWord) || "from".equalsIgnoreCase(aWord)
/* || "group".equalsIgnoreCase(aWord) || "order".equalsIgnoreCase(aWord)*/) {
needTranslate = false;
} else if ("where".equalsIgnoreCase(aWord)) {
needTranslate = true;
}
if (!needTranslate) {
preWordPos = lex.getCurrPos();
aWord = lex.getAWord();
continue;
}
if (":".equals(aWord)) {
lex.getAWord(); // 跳过参数
preWordPos = lex.getCurrPos();
aWord = lex.getAWord();
}
if (Lexer.isLabel(aWord)) {
SimpleTableField col = mapInfo.findFieldByName(aWord);
if (col != null) {
if (preWordPos > prePos)
sqlb.append(sql.substring(prePos, preWordPos));
sqlb.append(addAlias ? (" " + alias + ".") : " ").append(col.getColumnName());
prePos = lex.getCurrPos();
}
}
preWordPos = lex.getCurrPos();
aWord = lex.getAWord();
}
sqlb.append(sql.substring(prePos));
return sqlb.toString();
}
/**
* 每个dao都需要重载这个函数已获得自定义的查询条件,否则listObjects、pageQuery就等价与listObjectsByProperties
* 根据 getFilterField 中的内容初始化
* @param alias 数据库表别名
* @param useDefaultFilter 使用默认过滤器
* @return FilterQuery
*/
public String buildFieldFilterSql(String alias, boolean useDefaultFilter) {
StringBuilder sBuilder = new StringBuilder();
TableMapInfo mapInfo = JpaMetadata.fetchTableMapInfo(getPoClass());
boolean addAlias = StringUtils.isNotBlank(alias);
Map> fieldFilter =
getFilterFieldWithPretreatment(getFilterField());
if (useDefaultFilter || fieldFilter == null || fieldFilter.size() == 0) {//添加默认的过滤条件
mapInfo.getColumns().stream()
.filter(col -> fieldFilter == null || !fieldFilter.containsKey(col.getPropertyName()))
.forEach(col ->
sBuilder.append(" [:").append(col.getPropertyName()).append("| and ")
.append(col.getColumnName()).append(" = :").append(col.getPropertyName())
.append(" ]"));
}
if (fieldFilter != null) {
for (Map.Entry> ent : fieldFilter.entrySet()) {
String skey = ent.getKey();
String sSqlFormat = ent.getValue().getLeft();
if (CodeBook.ORDER_BY_HQL_ID.equalsIgnoreCase(skey))
continue;
if (skey.startsWith(CodeBook.NO_PARAM_FIX)) {
sBuilder.append(" [").append(skey).append("| and ")
.append(translatePropertyNameToColumnName(mapInfo, sSqlFormat, alias))
.append(" ]");
} else {
String pretreatment = ent.getValue().getRight();
if (sSqlFormat.equalsIgnoreCase(CodeBook.EQUAL_HQL_ID)) {
SimpleTableField col = mapInfo.findFieldByName(skey);
if (col != null) {
sBuilder.append(" [:");
if (StringUtils.isNotBlank(pretreatment)) {
sBuilder.append("(").append(pretreatment).append(")");
}
sBuilder.append(skey).append("| and ")
.append(addAlias ? (alias + ".") : "")
.append(col.getColumnName()).append(" = :").append(col.getPropertyName())
.append(" ]");
}
} else if (sSqlFormat.equalsIgnoreCase(CodeBook.LIKE_HQL_ID)) {
SimpleTableField col = mapInfo.findFieldByName(skey);
if (col != null) {
sBuilder.append(" [:(")
.append(StringUtils.isBlank(pretreatment) ? "like" : pretreatment)
.append(")").append(skey).append("| and ")
.append(addAlias ? (alias + ".") : "")
.append(col.getColumnName()).append(" like :").append(col.getPropertyName())
.append(" ]");
}
} else if (sSqlFormat.equalsIgnoreCase(CodeBook.IN_HQL_ID)) {
SimpleTableField col = mapInfo.findFieldByName(skey);
if (col != null) {
sBuilder.append(" [:");
if (StringUtils.isNotBlank(pretreatment)) {
sBuilder.append("(").append(pretreatment).append(")");
}
sBuilder.append(skey).append("| and ")
.append(addAlias ? (alias + ".") : "")
.append(col.getColumnName()).append(" in (:").append(col.getPropertyName())
.append(") ]");
}
} else {
if ("[".equals(Lexer.getFirstWord(sSqlFormat))) {
sBuilder.append(translatePropertyNameToColumnName(mapInfo, sSqlFormat, alias));
} else {
sBuilder.append(" [:");
if (StringUtils.isNotBlank(pretreatment)) {
sBuilder.append("(").append(pretreatment).append(")");
}
sBuilder.append(skey).append("| and ")
.append(translatePropertyNameToColumnName(mapInfo, sSqlFormat, alias))
.append(" ]");
}
}
}// else
}// for
}//if(fieldFilter!=null)
return sBuilder.toString();
}
private String daoEmbeddedFilter;
/**
* 每个dao都要初始化filterField这个对象,在 getFilterField 初始化,并且返回
* @return 返回 getFilterField 属性
*/
public abstract Map getFilterField();
/**
* 是否为每一个没有配置 filterField 配置过滤条件的属性自动配置一个 equal 类型的过滤条件
* @return 默认值为false
*/
public boolean enableDefaultFilter(){
return false;
}
public String buildDefaultFieldFilterSql() {
if (daoEmbeddedFilter == null) {
daoEmbeddedFilter = buildFieldFilterSql(null, enableDefaultFilter());
}
return daoEmbeddedFilter;
}
public String getFilterQuerySql() {
String querySql = getExtendFilterQuerySql();
if (StringUtils.isBlank(querySql)) {
querySql = buildDefaultFieldFilterSql();
return encapsulateFilterToSql(querySql);
} else {
if ("[".equals(Lexer.getFirstWord(querySql))) {
return encapsulateFilterToSql(querySql);
}
return querySql;
}
}
public void saveNewObject(T o) {
/* Integer execute = */
jdbcTemplate.execute(
(ConnectionCallback) conn ->
OrmDaoUtils.saveNewObject(conn, o));
}
public void deleteObjectForce(T o) {
/* Integer execute = */
jdbcTemplate.execute(
(ConnectionCallback) conn ->
OrmDaoUtils.deleteObject(conn, o));
}
public void deleteObjectForceById(Object id) {
jdbcTemplate.execute(
(ConnectionCallback) conn ->
OrmDaoUtils.deleteObjectById(conn, id, getPoClass()));
}
public void deleteObjectsForceByProperties(Map filterMap) {
jdbcTemplate.execute(
(ConnectionCallback) conn ->
OrmDaoUtils.deleteObjectByProperties(conn, filterMap, getPoClass()));
}
public void deleteObject(T o) {
/* Integer execute = */
if (o instanceof EntityWithDeleteTag) {
((EntityWithDeleteTag) o).setDeleted(true);
this.updateObject(o);
} else {
deleteObjectForce(o);
}
}
public void deleteObjectById(Object id) {
/* Integer execute = */
if (EntityWithDeleteTag.class.isAssignableFrom(getPoClass())) {
T o = getObjectById(id);
((EntityWithDeleteTag) o).setDeleted(true);
this.updateObject(o);
} else {
deleteObjectForceById(id);
}
}
public void deleteObjectsByProperties(Map filterMap) {
if (EntityWithDeleteTag.class.isAssignableFrom(getPoClass())) {
List deleteList = listObjectsByProperties(filterMap);
if (deleteList != null) {
for (T obj : deleteList) {
((EntityWithDeleteTag) obj).setDeleted(true);
this.updateObject(obj);
}
}
} else {
deleteObjectsForceByProperties(filterMap);
}
}
public void updateObject(T o) {
jdbcTemplate.execute(
(ConnectionCallback) conn ->
OrmDaoUtils.updateObject(conn, o));
}
/**
* 只更改对象的部分属性
* @param fields 需要修改的部分属性
* @param object 除了对应修改的属性 需要有相应的值,主键对应的属性也必须要值
* @throws PersistenceException 运行时异常
*/
public void updateObject(Collection fields, T object)
throws PersistenceException {
jdbcTemplate.execute(
(ConnectionCallback) conn ->
OrmDaoUtils.updateObject(conn, fields, object));
}
/**
* 只更改对象的部分属性
* @param fields 需要修改的部分属性
* @param object 除了对应修改的属性 需要有相应的值,主键对应的属性也必须要值
* @throws PersistenceException 运行时异常
*/
public void updateObject(String[] fields, T object)
throws PersistenceException {
updateObject(ListOpt.arrayToList(fields), object);
}
public void mergeObject(T o) {
jdbcTemplate.execute(
(ConnectionCallback) conn ->
OrmDaoUtils.mergeObject(conn, o));
}
public T getObjectById(Object id) {
return jdbcTemplate.execute(
(ConnectionCallback) conn ->
OrmDaoUtils.getObjectById(conn, id, (Class) getPoClass()));
}
public T getObjectIncludeLazyById(Object id) {
return jdbcTemplate.execute(
(ConnectionCallback) conn ->
OrmDaoUtils.getObjectIncludeLazyById(conn, id, (Class) getPoClass()));
}
public T getObjectWithReferences(Object id) {
T obj = getObjectById(id);
return fetchObjectReferences(obj);
}
public T fetchObjectLazyColumn(T o, String columnName) {
return jdbcTemplate.execute(
(ConnectionCallback) conn ->
OrmDaoUtils.fetchObjectLazyColumn(conn, o, columnName));
}
public T fetchObjectLazyColumns(T o) {
return jdbcTemplate.execute(
(ConnectionCallback) conn ->
OrmDaoUtils.fetchObjectLazyColumns(conn, o));
}
public T fetchObjectReference(T object, String columnName) {
TableMapInfo mapInfo = JpaMetadata.fetchTableMapInfo(getPoClass());
SimpleTableReference ref = mapInfo.findReference(columnName);
SimpleTableField field = mapInfo.findFieldByName(columnName);
if(ref==null || field == null || ref.getReferenceColumns().size()<1)
return object;
Class> refType = ref.getTargetEntityType();
TableMapInfo refMapInfo = JpaMetadata.fetchTableMapInfo( refType );
if( refMapInfo == null )
return object;
Map properties = new HashMap<>(6);
for(Map.Entry ent : ref.getReferenceColumns().entrySet()){
properties.put(ent.getValue(), ReflectionOpt.getFieldValue(object,ent.getKey()));
}
List> refs = jdbcTemplate.execute(
(ConnectionCallback>) conn ->
OrmDaoUtils.listObjectsByProperties(conn, properties, refType));
if(refs!=null && refs.size()>0) {
if (//ref.getReferenceType().equals(refType) /*||
ref.getReferenceType().isAssignableFrom(refType) ){
if( EntityWithDeleteTag.class.isAssignableFrom(refType)){
for(Object refObject : refs)
if( ! ((EntityWithDeleteTag)refObject).isDeleted()){
field.setObjectFieldValue(object,refObject);
break;
}
}else {
field.setObjectFieldValue(object, refs.get(0));
}
}else if(Set.class.isAssignableFrom(ref.getReferenceType())){
Set
© 2015 - 2025 Weber Informatics LLC | Privacy Policy