diff --git a/ureport2-console/src/main/java/com/bstek/ureport/console/designer/DatasourceServletAction.java b/ureport2-console/src/main/java/com/bstek/ureport/console/designer/DatasourceServletAction.java index 2fddcb6..fe073a5 100644 --- a/ureport2-console/src/main/java/com/bstek/ureport/console/designer/DatasourceServletAction.java +++ b/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 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() { - @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 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() { + @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> list=jdbc.queryForList(sql, map); + List> 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){ diff --git a/ureport2-core/src/main/java/com/bstek/ureport/Utils.java b/ureport2-core/src/main/java/com/bstek/ureport/Utils.java index 097f15f..0bad1e5 100644 --- a/ureport2-core/src/main/java/com/bstek/ureport/Utils.java +++ b/ureport2-core/src/main/java/com/bstek/ureport/Utils.java @@ -69,6 +69,7 @@ public class Utils implements ApplicationContextAware{ public static Collection getImageProviders() { return imageProviders; } + public static Connection getBuildinConnection(String name){ for(BuildinDatasource datasource:buildinDatasources){ diff --git a/ureport2-core/src/main/java/com/bstek/ureport/definition/dataset/SqlDatasetDefinition.java b/ureport2-core/src/main/java/com/bstek/ureport/definition/dataset/SqlDatasetDefinition.java index 5d2ee84..68ea82b 100644 --- a/ureport2-core/src/main/java/com/bstek/ureport/definition/dataset/SqlDatasetDefinition.java +++ b/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 pmap = buildParameters(parameterMap); + if(sqlForUse.trim().toLowerCase().startsWith("call ")){ + List> result = ProcedureUtils.procedureQuery(sqlForUse,pmap,conn); + return new Dataset(name,result); + } SingleConnectionDataSource datasource=new SingleConnectionDataSource(conn,false); NamedParameterJdbcTemplate jdbcTemplate=new NamedParameterJdbcTemplate(datasource); List> list= jdbcTemplate.queryForList(sqlForUse, pmap); diff --git a/ureport2-core/src/main/java/com/bstek/ureport/utils/ProcedureUtils.java b/ureport2-core/src/main/java/com/bstek/ureport/utils/ProcedureUtils.java new file mode 100644 index 0000000..631edd0 --- /dev/null +++ b/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 procedureColumnsQuery(String sql,Map 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 fields=new ArrayList(); + 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> procedureQuery(String sql,Map 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> result=new ArrayList>(); + while(rs.next()){ + Map map=new HashMap(); + 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 pmap,Connection conn){ + try { + Map paramMap=new LinkedHashMap(); + 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); + } + } +}