Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.beetl.sql.core.SQLScript Maven / Gradle / Ivy
package org.beetl.sql.core;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.beetl.core.GroupTemplate;
import org.beetl.core.Template;
import org.beetl.core.om.MethodInvoker;
import org.beetl.core.om.ObjectUtil;
import org.beetl.sql.core.annotatoin.AssignID;
import org.beetl.sql.core.db.ClassDesc;
import org.beetl.sql.core.db.DBStyle;
import org.beetl.sql.core.db.KeyHolder;
import org.beetl.sql.core.db.MetadataManager;
import org.beetl.sql.core.db.TableDesc;
import org.beetl.sql.core.kit.BeanKit;
import org.beetl.sql.core.kit.CaseInsensitiveOrderSet;
import org.beetl.sql.core.kit.EnumKit;
import org.beetl.sql.core.mapping.BeanProcessor;
import org.beetl.sql.core.mapping.QueryMapping;
import org.beetl.sql.core.mapping.RowMapperResultSetExt;
import org.beetl.sql.core.mapping.handler.BeanHandler;
import org.beetl.sql.core.mapping.handler.BeanListHandler;
import org.beetl.sql.core.mapping.handler.MapListHandler;
import org.beetl.sql.core.mapping.handler.ScalarHandler;
import org.beetl.sql.core.orm.MappingEntity;
public class SQLScript {
final SQLManager sm;
final String id;
final String sql;
final SQLSource sqlSource;
final String dbName ;
final QueryMapping queryMapping = QueryMapping.getInstance();
public SQLScript(SQLSource sqlSource, SQLManager sm) {
this.sqlSource = sqlSource;
this.sql = sqlSource.getTemplate();
this.sm = sm;
this.id = sqlSource.getId();
this.dbName = sm.getDbStyle().getName();
}
protected SQLResult run(Map paras) {
GroupTemplate gt = sm.beetl.getGroupTemplate();
Template t = gt.getTemplate(sqlSource.getId());
List jdbcPara = new LinkedList();
if (paras != null) {
for (Entry entry : paras.entrySet()) {
t.binding(entry.getKey(), entry.getValue());
}
}
t.binding("_paras", jdbcPara);
t.binding("_manager", this.sm);
t.binding("_id", id);
String jdbcSql = t.render();
SQLResult result = new SQLResult();
result.jdbcSql = jdbcSql;
result.jdbcPara = jdbcPara;
result.mapingEntrys= (List)t.getCtx().getGlobal("_mapping");
return result;
}
protected SQLResult run(Map paras, String parentId) {
GroupTemplate gt = sm.beetl.getGroupTemplate();
Template t = gt.getTemplate(sqlSource.getId(), parentId);
List jdbcPara = new LinkedList();
if (paras != null) {
for (Entry entry : paras.entrySet()) {
t.binding(entry.getKey(), entry.getValue());
}
}
t.binding("_paras", jdbcPara);
t.binding("_manager", this.sm);
t.binding("_id", id);
String jdbcSql = t.render();
SQLResult result = new SQLResult();
result.jdbcSql = jdbcSql;
result.jdbcPara = jdbcPara;
result.mapingEntrys= (List)t.getCtx().getGlobal("_mapping");
return result;
}
public int insert(Object paras) {
Map map = new HashMap();
map.put("_root", paras);
addParaIfAssignId(paras);
PreparedStatement ps = null;
Connection conn = null;
SQLResult result = this.run(map);
String sql = result.jdbcSql;
List objs = result.jdbcPara;
InterceptorContext ctx = this.callInterceptorAsBefore(this.id, sql, true, objs,map);
sql = ctx.getSql();
objs = ctx.getParas();
try {
conn = sm.getDs().getConn(this.id, true, sql, objs);
ps = conn.prepareStatement(sql);
this.setPreparedStatementPara(ps, objs);
int ret = ps.executeUpdate();
this.callInterceptorAsAfter(ctx, ret);
return ret;
} catch (SQLException e) {
throw new BeetlSQLException(BeetlSQLException.SQL_EXCEPTION, e);
} finally {
clean(true, conn, ps);
}
}
public int insert(Object paras, KeyHolder holder) {
Map map = new HashMap();
map.put("_root", paras);
addParaIfAssignId(paras);
PreparedStatement ps = null;
Connection conn = null;
try {
SQLResult result = this.run(map);
String sql = result.jdbcSql;
List objs = result.jdbcPara;
InterceptorContext ctx = this.callInterceptorAsBefore(this.id, sql, true, objs,map);
sql = ctx.getSql();
objs = ctx.getParas();
if (conn == null) {
conn = sm.getDs().getConn(id, true, sql, objs);
}
if (this.sqlSource.getIdType() == DBStyle.ID_ASSIGN) {
ps = conn.prepareStatement(sql);
} else if (this.sqlSource.getIdType() == DBStyle.ID_AUTO) {
ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
} else if(this.sqlSource.getIdType() == DBStyle.ID_SEQ) {
CaseInsensitiveOrderSet idCols = (CaseInsensitiveOrderSet)this.sqlSource.getTableDesc().getIdNames();
if(idCols.size()!=1){
throw new BeetlSQLException(BeetlSQLException.ID_EXPECTED_ONE_ERROR);
}
ps = conn.prepareStatement(sql, new String[]{idCols.getFirst()});
}
else {
ps = conn.prepareStatement(sql);
}
this.setPreparedStatementPara(ps, objs);
int ret = ps.executeUpdate();
if (this.sqlSource.getIdType() == DBStyle.ID_AUTO||this.sqlSource.getIdType() == DBStyle.ID_SEQ) {
ResultSet seqRs = ps.getGeneratedKeys();
seqRs.next();
Object key = seqRs.getObject(1);
holder.setKey(key);
seqRs.close();
}
this.callInterceptorAsAfter(ctx, ret);
return ret;
} catch (SQLException e) {
throw new BeetlSQLException(BeetlSQLException.SQL_EXCEPTION, e);
} finally {
clean(true, conn, ps);
}
}
public int insertBySqlId(Map map, KeyHolder holder,String keyName) {
boolean getKey = holder!=null ;
PreparedStatement ps = null;
Connection conn = null;
try {
SQLResult result = this.run(map);
String sql = result.jdbcSql;
List objs = result.jdbcPara;
InterceptorContext ctx = this.callInterceptorAsBefore(this.id, sql, true, objs,map);
sql = ctx.getSql();
objs = ctx.getParas();
if (conn == null) {
conn = sm.getDs().getConn(id, true, sql, objs);
}
if(getKey){
ps = conn.prepareStatement(sql, new String[]{keyName});
}else{
ps = conn.prepareStatement(sql);
}
this.setPreparedStatementPara(ps, objs);
int ret = ps.executeUpdate();
if(getKey){
ResultSet seqRs = ps.getGeneratedKeys();
seqRs.next();
Object key = seqRs.getObject(1);
holder.setKey(key);
seqRs.close();
}
this.callInterceptorAsAfter(ctx, ret);
return ret;
} catch (SQLException e) {
throw new BeetlSQLException(BeetlSQLException.SQL_EXCEPTION, e);
} finally {
clean(true, conn, ps);
}
}
public T singleSelect(Object paras, Class target) {
Map map = new HashMap();
map.put("_root", paras);
return this.selectSingle(map, target);
}
public T selectSingle(Map map, Class target) {
List result = select(target, map);
if (result.size() > 0) {
return result.get(0);
}
return null;
}
public T selectUnique(Map map, Class target) {
List result = select(target, map);
if (result.size() == 1) {
return result.get(0);
}else{
throw new BeetlSQLException(BeetlSQLException.UNIQUE_EXCEPT_ERROR, "unique查询,但数据库未找到结果集:参数是"+map);
}
}
public List select(Class clazz, Object paras) {
Map map = new HashMap();
map.put("_root", paras);
return this.select(clazz, map);
}
public List select(Class clazz, Map paras, RowMapper mapper) {
SQLResult result = run(paras);
String sql = result.jdbcSql;
List objs = result.jdbcPara;
ResultSet rs = null;
PreparedStatement ps = null;
List resultList = null;
InterceptorContext ctx = this.callInterceptorAsBefore(this.id, sql, false, objs,paras);
if(ctx.getResult()!=null){
this.callInterceptorAsAfter(ctx, ctx.getResult());
return (List)ctx.getResult();
}
//再次获取参数,因为有可能被改变
sql = ctx.getSql();
objs = ctx.getParas();
Connection conn = null;
try {
conn = sm.getDs().getConn(id, false, sql, objs);
ps = conn.prepareStatement(sql);
this.setPreparedStatementPara(ps, objs);
rs = ps.executeQuery();
if (mapper != null) {
BeanProcessor beanProcessor = new BeanProcessor(this.sm.getNc(), this.sm);
resultList = new RowMapperResultSetExt(mapper, beanProcessor).handleResultSet(rs, clazz);
this.callInterceptorAsAfter(ctx, resultList);
} else {
resultList = mappingSelect(rs, clazz);
}
this.callInterceptorAsAfter(ctx, resultList);
if(mapper==null){
//1.5.0 feature
if(result.mapingEntrys!=null){
for(MappingEntity mapConf:result.mapingEntrys){
mapConf.map(resultList, sm);
}
}
}
return resultList;
} catch (SQLException e) {
throw new BeetlSQLException(BeetlSQLException.SQL_EXCEPTION, e);
} finally {
clean(false, conn, ps, rs);
}
}
public List select(Class clazz, Map paras) {
return this.select(clazz, paras, null);
}
public List mappingSelect(ResultSet rs, Class clazz) throws SQLException {
List resultList = null;
if (isBaseDataType(clazz)) { // 基本数据类型,如果有需要可以继续在isBaseDataType()添加
resultList = new ArrayList();
while(rs.next()){
T result = queryMapping.query(rs, new ScalarHandler(clazz));
resultList.add(result);
}
} else if (Map.class.isAssignableFrom(clazz)) { // 如果是Map的子类或者父类,返回List>
resultList = (List) queryMapping.query(rs, new MapListHandler(this.sm.getNc(), this.sm,clazz));
} else {
resultList = queryMapping.query(rs, new BeanListHandler(clazz, this.sm.getNc(), this.sm));
}
return resultList;
}
private static boolean isBaseDataType(Class> clazz) {
return (clazz.equals(String.class) || clazz.equals(Integer.class) || clazz.equals(Byte.class)
|| clazz.equals(Long.class) || clazz.equals(Double.class) || clazz.equals(Float.class)
|| clazz.equals(Character.class) || clazz.equals(Short.class) || clazz.equals(BigDecimal.class)
|| clazz.equals(BigInteger.class) || clazz.equals(Boolean.class) || clazz.equals(Date.class)
|| clazz.isPrimitive());
}
public List select(Map paras, Class mapping, RowMapper mapper, long start, long size) {
SQLScript pageScript = this.sm.getPageSqlScript(this.id);
if (paras == null)
paras = new HashMap();
this.sm.getDbStyle().initPagePara(paras, start, size);
return pageScript.select(mapping, paras, mapper);
// return pageScript.se
}
public List select(Object paras, Class mapping, RowMapper mapper, long start, long end) {
Map map = new HashMap();
map.put("_root", paras);
return this.select(map, mapping, mapper, start, end);
}
public long selectCount(Object paras) {
return this.singleSelect(paras, Long.class);
}
public long selectCount(Map paras) {
return this.selectSingle(paras, Long.class);
}
public int update(Map paras) {
SQLResult result = run(paras);
String sql = result.jdbcSql;
List objs = result.jdbcPara;
InterceptorContext ctx = this.callInterceptorAsBefore(this.id, sql, true, objs,paras);
sql = ctx.getSql();
objs = ctx.getParas();
int rs = 0;
PreparedStatement ps = null;
// 执行jdbc
Connection conn = null;
try {
conn = sm.getDs().getConn(id, true, sql, objs);
ps = conn.prepareStatement(sql);
this.setPreparedStatementPara(ps, objs);
rs = ps.executeUpdate();
this.callInterceptorAsAfter(ctx, rs);
} catch (SQLException e) {
// TODO Auto-generated catch block
throw new BeetlSQLException(BeetlSQLException.SQL_EXCEPTION, e);
} finally {
clean(true, conn, ps);
}
return rs;
}
public int update(Object obj) {
Map paras = new HashMap();
paras.put("_root", obj);
return this.update(paras);
}
public int[] updateBatch(Map[] maps) {
int[] rs = null;
PreparedStatement ps = null;
// 执行jdbc
Connection conn = null;
InterceptorContext ctx = null;
try {
for (int k = 0; k < maps.length; k++) {
Map paras = maps[k];
SQLResult result = run(paras);
List objs = result.jdbcPara;
if (ps == null) {
conn = sm.getDs().getConn(id, true, sql, objs);
ps = conn.prepareStatement(result.jdbcSql);
ctx = this.callInterceptorAsBefore(this.id, sql, true, Collections.EMPTY_LIST,paras);
}
this.setPreparedStatementPara(ps, objs);
ps.addBatch();
}
rs = ps.executeBatch();
this.callInterceptorAsAfter(ctx, rs);
} catch (SQLException e) {
// TODO Auto-generated catch block
throw new BeetlSQLException(BeetlSQLException.SQL_EXCEPTION, e);
} finally {
clean(true, conn, ps);
}
return rs;
}
public int[] insertBatch(List> list) {
//与updateBatch区别是需要考虑到id生成
if(list.size()==0){
return new int[0];
}
int[] rs = null;
PreparedStatement ps = null;
Connection conn = null;
// 执行jdbc
InterceptorContext ctx = null;
try {
for (int k = 0; k < list.size(); k++) {
Map paras = new HashMap();
Object entity = list.get(k);
this.addParaIfAssignId(entity);
paras.put("_root",entity);
SQLResult result = run(paras);
List objs = result.jdbcPara;
if (ps == null) {
conn = sm.getDs().getConn(id, true, sql, objs);
ps = conn.prepareStatement(result.jdbcSql);
ctx = this.callInterceptorAsBefore(this.id, sql, true, Collections.emptyList(),paras);
}
this.setPreparedStatementPara(ps, objs);
ps.addBatch();
}
rs = ps.executeBatch();
this.callInterceptorAsAfter(ctx, rs);
} catch (SQLException e) {
throw new BeetlSQLException(BeetlSQLException.SQL_EXCEPTION, e);
} finally {
clean(true, conn, ps);
}
return rs;
}
public int[] updateBatch(List> list) {
if(list.size()==0){
return new int[0];
}
int[] rs = null;
PreparedStatement ps = null;
Connection conn = null;
// 执行jdbc
InterceptorContext ctx = null;
try {
for (int k = 0; k < list.size(); k++) {
Map paras = new HashMap();
paras.put("_root", list.get(k));
SQLResult result = run(paras);
List objs = result.jdbcPara;
if (ps == null) {
conn = sm.getDs().getConn(id, true, sql, objs);
ps = conn.prepareStatement(result.jdbcSql);
ctx = this.callInterceptorAsBefore(this.id, sql, true, Collections.emptyList(),paras);
}
this.setPreparedStatementPara(ps, objs);
ps.addBatch();
}
rs = ps.executeBatch();
this.callInterceptorAsAfter(ctx, rs);
} catch (SQLException e) {
throw new BeetlSQLException(BeetlSQLException.SQL_EXCEPTION, e);
} finally {
clean(true, conn, ps);
}
return rs;
}
public T unique(Class clazz, RowMapper mapper, Object objId) {
return single(clazz,mapper,objId,true);
}
public T single(Class clazz, RowMapper mapper, Object objId) {
return single(clazz,mapper,objId,false);
}
public T single(Class clazz, RowMapper mapper, Object objId,boolean throwException) {
MetadataManager mm = this.sm.getDbStyle().getMetadataManager();
TableDesc table = mm.getTable(this.sm.getNc().getTableName(clazz));
ClassDesc classDesc = table.getClassDesc(clazz, this.sm.getNc());
Map paras = new HashMap();
this.setIdsParas(classDesc, objId, paras);
SQLResult result = run(paras);
String sql = result.jdbcSql;
List objs = result.jdbcPara;
ResultSet rs = null;
PreparedStatement ps = null;
T model = null;
InterceptorContext ctx = this.callInterceptorAsBefore(this.id, sql, false, objs,paras);
if(ctx.getResult()!=null){
this.callInterceptorAsAfter(ctx, ctx.getResult());
return (T) ctx.getResult();
}
sql = ctx.getSql();
objs = ctx.getParas();
Connection conn = null;
try {
conn = sm.getDs().getConn(id, false, sql, objs);
ps = conn.prepareStatement(sql);
this.setPreparedStatementPara(ps, objs);
rs = ps.executeQuery();
try{
model = queryMapping.query(rs, new BeanHandler(clazz, this.sm.getNc(), this.sm,throwException));
}catch(BeetlSQLException ex){
if(ex.code==BeetlSQLException.UNIQUE_EXCEPT_ERROR){
throw new BeetlSQLException(BeetlSQLException.UNIQUE_EXCEPT_ERROR,"unique查询"+table.getName()+",但数据库未找到结果集:主键是"+objId);
}else{
throw ex;
}
}
this.callInterceptorAsAfter(ctx, model);
} catch (SQLException e) {
throw new BeetlSQLException(BeetlSQLException.SQL_EXCEPTION, e);
} finally {
clean(false, conn, ps, rs);
}
return model;
}
public int deleteById(Class> clazz, Object objId) {
MetadataManager mm = this.sm.getDbStyle().getMetadataManager();
TableDesc table = mm.getTable(this.sm.getNc().getTableName(clazz));
ClassDesc classDesc = table.getClassDesc(clazz, this.sm.getNc());
Map paras = new HashMap();
this.setIdsParas(classDesc, objId, paras);
SQLResult result = run(paras);
String sql = result.jdbcSql;
List objs = result.jdbcPara;
InterceptorContext ctx = this.callInterceptorAsBefore(this.id, sql, true, objs,paras);
sql = ctx.getSql();
objs = ctx.getParas();
int rs = 0;
PreparedStatement ps = null;
Connection conn = null;
try {
conn = sm.getDs().getConn(id, true, sql, objs);
ps = conn.prepareStatement(sql);
this.setPreparedStatementPara(ps, objs);
rs = ps.executeUpdate();
this.callInterceptorAsAfter(ctx, rs);
} catch (SQLException e) {
throw new BeetlSQLException(BeetlSQLException.SQL_EXCEPTION, e);
} finally {
clean(true, conn, ps);
}
return rs;
}
public List sqlReadySelect(Class clazz, SQLReady p) {
String sql = this.sql;
List objs = Arrays.asList(p.getArgs());
ResultSet rs = null;
PreparedStatement ps = null;
List resultList = null;
InterceptorContext ctx = this.callInterceptorAsBefore(this.id, sql, false, objs,this.getSQLReadyParas(objs));
sql = ctx.getSql();
objs = ctx.getParas();
Connection conn = null;
try {
conn = sm.getDs().getConn(id, false, sql, objs);
ps = conn.prepareStatement(sql);
this.setPreparedStatementPara(ps, objs);
rs = ps.executeQuery();
resultList = mappingSelect(rs, clazz);
this.callInterceptorAsAfter(ctx, resultList);
return resultList;
} catch (SQLException e) {
throw new BeetlSQLException(BeetlSQLException.SQL_EXCEPTION, e);
} finally {
clean(false, conn, ps, rs);
}
}
public int sqlReadyExecuteUpdate(SQLReady p) {
String sql = this.sql;
List objs = Arrays.asList(p.args);
InterceptorContext ctx = this.callInterceptorAsBefore(this.id, sql, true, objs,this.getSQLReadyParas(objs));
sql = ctx.getSql();
objs = ctx.getParas();
int rs = 0;
PreparedStatement ps = null;
// 执行jdbc
Connection conn = null;
try {
conn = sm.getDs().getConn(id, true, sql, objs);
ps = conn.prepareStatement(sql);
this.setPreparedStatementPara(ps, objs);
rs = ps.executeUpdate();
this.callInterceptorAsAfter(ctx, rs);
} catch (SQLException e) {
// TODO Auto-generated catch block
throw new BeetlSQLException(BeetlSQLException.SQL_EXCEPTION, e);
} finally {
clean(true, conn, ps);
}
return rs;
}
private void setPreparedStatementPara(PreparedStatement ps,List objs) throws SQLException {
for (int i = 0; i < objs.size(); i++) {
Object o = objs.get(i);
// 兼容性修改:oralce 驱动 不识别util.Date
if (o != null ) {
Class c = o.getClass();
if(c== java.util.Date.class){
o = new Timestamp(((java.util.Date) o).getTime());
}else if(Enum.class.isAssignableFrom(c)){
o = EnumKit.getValueByEnum(o);
}
// o =new java.sql.Date(((java.util.Date)o).getTime());
}
ps.setObject(i + 1, o);
}
}
protected void clean(boolean isUpdate, Connection conn, PreparedStatement ps, ResultSet rs) {
try {
if (rs != null)
rs.close();
if (ps != null)
ps.close();
if (!this.sm.getDs().isTransaction()) {
try {
if (conn != null) {
// colse 不一定能保证能自动commit
if (isUpdate && !conn.getAutoCommit())
conn.commit();
conn.close();
}
} catch (SQLException e) {
throw new BeetlSQLException(BeetlSQLException.SQL_EXCEPTION, e);
}
}
} catch (SQLException e) {
// ignore
}
}
protected void clean(boolean isUpdate, Connection conn, PreparedStatement ps) {
this.clean(isUpdate, conn, ps, null);
}
protected void clean( Connection conn) {
this.clean(true, conn, null, null);
}
private InterceptorContext callInterceptorAsBefore(String sqlId, String sql,
boolean isUpdate, List jdbcParas,Map inputParas) {
InterceptorContext ctx = new InterceptorContext(sqlId, sql, jdbcParas,inputParas, isUpdate);
for (Interceptor in : sm.inters) {
in.before(ctx);
}
return ctx;
}
private void callInterceptorAsAfter(InterceptorContext ctx, Object result) {
if (sm.inters == null)
return;
if (!ctx.isUpdate()) {
ctx.setResult(result);
} else {
ctx.setResult(result);
}
for (Interceptor in : sm.inters) {
in.after(ctx);
}
return;
}
private Map getSQLReadyParas(List paras){
Map map = new HashMap();
map.put("_root", paras);
return map ;
}
public String getId() {
return id;
}
/**
* 为主键设置参数
* @param desc
* @param obj
* @param paras
*/
private void setIdsParas(ClassDesc desc,Object obj,Map paras){
List idAttrs = desc.getIdAttrs();
if(idAttrs.size()==1){
paras.put(idAttrs.get(0), obj);
}else{
//来自对象id的属性.
List idClos = desc.getIdCols();
Map map = desc.getIdMethods();
for(int i=0;i ids = sqlSource.getAssignIds();
for(Entry entry:ids.entrySet()){
String attrName = entry.getKey();
AssignID assignId = entry.getValue();
String algorithm = assignId.value();
String param = assignId.param();
Object o = this.sm.getAssignIdByIdAutonGen(algorithm,param,sqlSource.getTableDesc().getName());
BeanKit.setBeanProperty(obj, o, attrName);
}
}
}
public String getSql() {
return sql;
}
}