Переглянути джерело

为SQL数据集添加存储过程支持,SQL数据集中SQL以call关键字开头,引擎将识别为存储过程调用

master
jacky6024 6 роки тому
джерело
коміт
ed2f6d1f3f
  1. 76
      ureport2-console/src/main/java/com/bstek/ureport/console/designer/DatasourceServletAction.java
  2. 1
      ureport2-core/src/main/java/com/bstek/ureport/Utils.java
  3. 5
      ureport2-core/src/main/java/com/bstek/ureport/definition/dataset/SqlDatasetDefinition.java
  4. 117
      ureport2-core/src/main/java/com/bstek/ureport/utils/ProcedureUtils.java

76
ureport2-console/src/main/java/com/bstek/ureport/console/designer/DatasourceServletAction.java

@ -67,6 +67,7 @@ import com.bstek.ureport.expression.ExpressionUtils;
import com.bstek.ureport.expression.model.Expression;
import com.bstek.ureport.expression.model.data.ExpressionData;
import com.bstek.ureport.expression.model.data.ObjectExpressionData;
import com.bstek.ureport.utils.ProcedureUtils;
/**
* @author Jacky.gao
@ -79,15 +80,6 @@ public class DatasourceServletAction extends RenderPageServletAction {
String method=retriveMethod(req);
if(method!=null){
invokeMethod(method, req, resp);
}else{
/*VelocityContext context = new VelocityContext();
context.put("contextPath", req.getContextPath());
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
Template template=ve.getTemplate("html/designer.html","utf-8");
PrintWriter writer=resp.getWriter();
template.merge(context, writer);
writer.close();*/
}
}
@ -169,16 +161,8 @@ public class DatasourceServletAction extends RenderPageServletAction {
}catch(Exception ex){
throw new ServletException(ex);
}finally{
try {
if(rs!=null){
rs.close();
}
if(conn!=null){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
JdbcUtils.closeResultSet(rs);
JdbcUtils.closeConnection(conn);
}
}
@ -191,27 +175,32 @@ public class DatasourceServletAction extends RenderPageServletAction {
conn=buildConnection(req);
Map<String, Object> map = buildParameters(parameters);
sql=parseSql(sql, map);
DataSource dataSource=new SingleConnectionDataSource(conn,false);
NamedParameterJdbcTemplate jdbc=new NamedParameterJdbcTemplate(dataSource);
PreparedStatementCreator statementCreator=getPreparedStatementCreator(sql,new MapSqlParameterSource(map));
jdbc.getJdbcOperations().execute(statementCreator, new PreparedStatementCallback<Object>() {
@Override
public Object doInPreparedStatement(PreparedStatement ps) throws SQLException, DataAccessException {
ResultSet rs = null;
try {
rs = ps.executeQuery();
ResultSetMetaData metadata=rs.getMetaData();
int columnCount=metadata.getColumnCount();
for(int i=0;i<columnCount;i++){
String columnName=metadata.getColumnLabel(i+1);
fields.add(new Field(columnName));
if(sql.trim().toLowerCase().startsWith("call ")){
List<Field> fieldsList = ProcedureUtils.procedureColumnsQuery(sql, map, conn);
fields.addAll(fieldsList);
}else{
DataSource dataSource=new SingleConnectionDataSource(conn,false);
NamedParameterJdbcTemplate jdbc=new NamedParameterJdbcTemplate(dataSource);
PreparedStatementCreator statementCreator=getPreparedStatementCreator(sql,new MapSqlParameterSource(map));
jdbc.getJdbcOperations().execute(statementCreator, new PreparedStatementCallback<Object>() {
@Override
public Object doInPreparedStatement(PreparedStatement ps) throws SQLException, DataAccessException {
ResultSet rs = null;
try {
rs = ps.executeQuery();
ResultSetMetaData metadata=rs.getMetaData();
int columnCount=metadata.getColumnCount();
for(int i=0;i<columnCount;i++){
String columnName=metadata.getColumnLabel(i+1);
fields.add(new Field(columnName));
}
return null;
}finally {
JdbcUtils.closeResultSet(rs);
}
return null;
}finally {
JdbcUtils.closeResultSet(rs);
}
}
});
});
}
writeObjectToJson(resp, fields);
}catch(Exception ex){
throw new ReportDesignException(ex);
@ -237,9 +226,14 @@ public class DatasourceServletAction extends RenderPageServletAction {
Connection conn=null;
try{
conn=buildConnection(req);
DataSource dataSource=new SingleConnectionDataSource(conn,false);
NamedParameterJdbcTemplate jdbc=new NamedParameterJdbcTemplate(dataSource);
List<Map<String,Object>> list=jdbc.queryForList(sql, map);
List<Map<String,Object>> list=null;
if(sql.trim().toLowerCase().startsWith("call ")){
list=ProcedureUtils.procedureQuery(sql, map, conn);
}else{
DataSource dataSource=new SingleConnectionDataSource(conn,false);
NamedParameterJdbcTemplate jdbc=new NamedParameterJdbcTemplate(dataSource);
list=jdbc.queryForList(sql, map);
}
int size=list.size();
int currentTotal=size;
if(currentTotal>500){

1
ureport2-core/src/main/java/com/bstek/ureport/Utils.java

@ -69,6 +69,7 @@ public class Utils implements ApplicationContextAware{
public static Collection<ImageProvider> getImageProviders() {
return imageProviders;
}
public static Connection getBuildinConnection(String name){
for(BuildinDatasource datasource:buildinDatasources){

5
ureport2-core/src/main/java/com/bstek/ureport/definition/dataset/SqlDatasetDefinition.java

@ -33,6 +33,7 @@ import com.bstek.ureport.expression.ExpressionUtils;
import com.bstek.ureport.expression.model.Expression;
import com.bstek.ureport.expression.model.data.ExpressionData;
import com.bstek.ureport.expression.model.data.ObjectExpressionData;
import com.bstek.ureport.utils.ProcedureUtils;
/**
@ -64,6 +65,10 @@ public class SqlDatasetDefinition implements DatasetDefinition {
}
Utils.logToConsole("RUNTIME SQL:"+sqlForUse);
Map<String, Object> pmap = buildParameters(parameterMap);
if(sqlForUse.trim().toLowerCase().startsWith("call ")){
List<Map<String,Object>> result = ProcedureUtils.procedureQuery(sqlForUse,pmap,conn);
return new Dataset(name,result);
}
SingleConnectionDataSource datasource=new SingleConnectionDataSource(conn,false);
NamedParameterJdbcTemplate jdbcTemplate=new NamedParameterJdbcTemplate(datasource);
List<Map<String,Object>> list= jdbcTemplate.queryForList(sqlForUse, pmap);

117
ureport2-core/src/main/java/com/bstek/ureport/utils/ProcedureUtils.java

@ -0,0 +1,117 @@
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.utils;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.jdbc.support.JdbcUtils;
import com.bstek.ureport.definition.dataset.Field;
import com.bstek.ureport.exception.ReportException;
/**
* @author Jacky.gao
* @since 2017年12月27日
*/
public class ProcedureUtils {
public static List<Field> procedureColumnsQuery(String sql,Map<String, Object> pmap,Connection conn){
CallableStatement cs=buildProcedureCallableStatement(sql, pmap, conn);
ResultSet rs=null;
try {
rs=cs.executeQuery();
ResultSetMetaData metadata=rs.getMetaData();
int columnCount=metadata.getColumnCount();
List<Field> fields=new ArrayList<Field>();
for(int i=1;i<=columnCount;i++){
String columnName=metadata.getColumnLabel(i);
fields.add(new Field(columnName));
}
return fields;
} catch (SQLException e) {
throw new ReportException(e);
}finally{
JdbcUtils.closeResultSet(rs);
JdbcUtils.closeStatement(cs);
JdbcUtils.closeConnection(conn);
}
}
public static List<Map<String,Object>> procedureQuery(String sql,Map<String, Object> pmap,Connection conn){
CallableStatement cs=buildProcedureCallableStatement(sql, pmap, conn);
ResultSet rs=null;
try {
rs=cs.executeQuery();
ResultSetMetaData metadata=rs.getMetaData();
int columnCount=metadata.getColumnCount();
List<Map<String,Object>> result=new ArrayList<Map<String,Object>>();
while(rs.next()){
Map<String,Object> map=new HashMap<String,Object>();
for(int i=1;i<=columnCount;i++){
String columnName=metadata.getColumnLabel(i);
map.put(columnName, rs.getObject(columnName));
}
result.add(map);
}
return result;
} catch (SQLException e) {
throw new ReportException(e);
}finally{
JdbcUtils.closeResultSet(rs);
JdbcUtils.closeStatement(cs);
JdbcUtils.closeConnection(conn);
}
}
private static CallableStatement buildProcedureCallableStatement(String sql,Map<String, Object> pmap,Connection conn){
try {
Map<String,Object> paramMap=new LinkedHashMap<String,Object>();
int leftParnPos=sql.indexOf("(");
int rightParnPos=sql.indexOf(")");
String paramStr=sql.substring(leftParnPos+1,rightParnPos);
String[] str=paramStr.split(",");
for(String param:str){
param=param.trim();
if(!param.startsWith(":")){
continue;
}
sql=sql.replaceFirst(param, "?");
String paramName=param.substring(1,param.length());
Object paramValue=pmap.get(paramName);
paramMap.put(paramName, (paramValue==null ? "" : paramValue));
}
String procedure="{"+sql+"}";
CallableStatement cs= conn.prepareCall(procedure);
int index=1;
for(String name:paramMap.keySet()){
cs.setObject(index, paramMap.get(name));
index++;
}
return cs;
} catch (SQLException e) {
throw new ReportException(e);
}
}
}
Завантаження…
Відмінити
Зберегти