Mysql Ebean调用存储过程并将结果集转换为模型
我在报表模块中工作,为此我创建了不同的存储过程。我使用in参数创建过程,然后创建一个类来映射行(resultSet) 我认为这是提高性能和清晰度的最佳方法。(你怎么看?)Mysql Ebean调用存储过程并将结果集转换为模型,mysql,stored-procedures,playframework-2.0,resultset,ebean,Mysql,Stored Procedures,Playframework 2.0,Resultset,Ebean,我在报表模块中工作,为此我创建了不同的存储过程。我使用in参数创建过程,然后创建一个类来映射行(resultSet) 我认为这是提高性能和清晰度的最佳方法。(你怎么看?) 我正在使用play框架和ebean orm(2.7.7) 我正在调用存储过程并获取结果集,但是我想使用ebean自动将行转换为model。。。另一种选择是将行单元格转换为属性,但我试图避免它 这是当前的方法 这是调用存储过程的最佳方式吗? Transaction tx = Ebean.beginTransaction(
我正在使用play框架和ebean orm(2.7.7)
我正在调用存储过程并获取结果集,但是我想使用ebean自动将行转换为model。。。另一种选择是将行单元格转换为属性,但我试图避免它 这是当前的方法
这是调用存储过程的最佳方式吗?
Transaction tx = Ebean.beginTransaction();
String sql = "{CALL report(?, ?, ?, ?, ?, ?)}";
CallableStatement callableStatement = null;
try {
Connection dbConnection = tx.getConnection();
callableStatement = dbConnection.prepareCall(sql);
callableStatement.setInt(1, 3);
callableStatement.setInt(2, 5);
callableStatement.setInt(3, 2013);
callableStatement.setInt(4, 1);
callableStatement.setInt(5, 2014);
callableStatement.setInt(6, 5);
ResultSet rs = callableStatement.executeQuery(sql);
while (rs.next()) {
//HOW TO CONVER row -> model ?
}
Ebean.commitTransaction();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
我已放弃RawSQL和查询,因为收到错误运行时异常:分析sql时出错,在:xxxxx中找不到SELECT关键字 我还找到了其他选择。。。使用CallableSql
String sql = "{call sp_order_mod(?,?)}";
CallableSql cs = Ebean.createCallableSql(sql);
cs.setParameter(1, "turbo");
cs.registerOut(2, Types.INTEGER);
Ebean.execute(cs);
// read the out parameter
Integer returnValue = (Integer) cs.getObject(2);
但是在这种情况下,我需要返回一个ResultSet,而不仅仅是参数目前,在Ebean中对存储过程的支持并不针对您正在尝试做的事情。因此,您不会从使用CallableSql或RawSql中获得太多乐趣 >>一个映射行的类(resultSet)我认为这是解决性能和清晰度问题的最佳方法 是的,我能理解你的动机 >>如何将结果集转换为模型 目前没有好的解决办法。最好的解决方案是增强RawSql,以便可以在其上设置ResultSet。RawSql所做的一件事是提供resultSet列到模型属性的映射,而这正是Ebean内部需要的。增强/代码更改将能够在RawSql对象上设置resultSet。。。并让Ebean在内部跳过resultSet(preparedStatement、binding参数和executeQuery()的创建)。就Ebean内部而言,这都是在CQuery.prepareBindExecuteQueryWithOption()方法中完成的。也就是说,如果RawSql已经提供了一个resultSet,那么跳过这些内容 这样做而不仅仅滚动您自己的行->模型映射代码的最大好处是,生成的bean仍然具有延迟加载/部分对象知识等。它们的行为与Ebean作为it查询机制的一部分构建的任何其他bean完全相同 也就是说,我个人要离开一周。。。所以在那之前你不会收到我的回复。如果您想亲自进入其中,则需要修改CQuery.prepareBindExecuteQueryWithOption()内部代码 如果你一直在关注ebean谷歌小组,你会知道,但以防万一,你还没有注意到,Play中的Model和Finder对象就在上周被合并到ebean中。这有助于两个项目。。。减少了混乱等。github master中的Ebean源代码是4.0.4,4.x中的字节码增强是不同的,我不相信在游戏中支持 我现在基本上要离线一个星期,所以我会在那之后回顾这件事
干杯,Rob。目前,Ebean中对存储过程的支持并不针对您要做的事情。因此,您不会从使用CallableSql或RawSql中获得太多乐趣 >>一个映射行的类(resultSet)我认为这是解决性能和清晰度问题的最佳方法 是的,我能理解你的动机 >>如何将结果集转换为模型 目前没有好的解决办法。最好的解决方案是增强RawSql,以便可以在其上设置ResultSet。RawSql所做的一件事是提供resultSet列到模型属性的映射,而这正是Ebean内部需要的。增强/代码更改将能够在RawSql对象上设置resultSet。。。并让Ebean在内部跳过resultSet(preparedStatement、binding参数和executeQuery()的创建)。就Ebean内部而言,这都是在CQuery.prepareBindExecuteQueryWithOption()方法中完成的。也就是说,如果RawSql已经提供了一个resultSet,那么跳过这些内容 这样做而不仅仅滚动您自己的行->模型映射代码的最大好处是,生成的bean仍然具有延迟加载/部分对象知识等。它们的行为与Ebean作为it查询机制的一部分构建的任何其他bean完全相同 也就是说,我个人要离开一周。。。所以在那之前你不会收到我的回复。如果您想亲自进入其中,则需要修改CQuery.prepareBindExecuteQueryWithOption()内部代码 如果你一直在关注ebean谷歌小组,你会知道,但以防万一,你还没有注意到,Play中的Model和Finder对象就在上周被合并到ebean中。这有助于两个项目。。。减少了混乱等。github master中的Ebean源代码是4.0.4,4.x中的字节码增强是不同的,我不相信在游戏中支持 我现在基本上要离线一个星期,所以我会在那之后回顾这件事
干杯,罗伯。我要分享我自己的解决方案
public static <T> List<T> populateInList(Class<T> c, final ResultSet rs) {
List<T> listTyped = new ArrayList<T>();
try {
if (rs != null) {
while (rs.next()) {
T o = c.newInstance();
// MAGIC LINE
populate(o, rs);
listTyped.add(o);
}
rs.close();
}
} catch (final Exception e) {
// TODO Auto-generated catch block
System.err.println(e.getMessage());
}
return listTyped;
}
- 意图:知道存储过程的名称、参数和dto结果
public class ReportTestReport extends ReportBase<ReportTestResult, ReportTestParam> { @Override protected String getProcedureName() { return STORED_NAME; } }
- OptionsHC是一个在HighCharts框架中表示option obj的类
- 最后一步是将OptionHC转换为Json,并在JavaScript中使用它(highCharts的常见用法)
public interface ReportParam {
public int countParameteres();
public void setParametersInCallableStatement(CallableStatement callableStatement) throws SQLException;
}
public class ReportTestReport extends ReportBase<ReportTestResult, ReportTestParam> {
@Override
protected String getProcedureName() {
return STORED_NAME;
}
}
public OptionsHC buildColumnReportV1(){
OptionsHC optionChart = new OptionsHC();
optionChart.chart = new ChartHC("column");
this.setTitle(optionChart);
optionChart.yAxis = new AxisHC(new TitleHC("Fruit eaten"));
.....
return optionChart;
}
public class ReportTestReport extends ReportBase<ReportTestResult, ReportTestParam> {
...
protected List<TResult> execute(Class<TResult> classT) {
List<TResult> resultDTO = null;
CallableStatement callableStatement = null;
Logger.debug("Running procedure> " + this.getProcedureName());
Transaction tx = Ebean.beginTransaction();
String sql = ProcedureBuilder.build(this.getProcedureName(), this.countParameters());
Logger.debug("SQL > " + sql);
try {
Connection dbConnection = tx.getConnection();
callableStatement = dbConnection.prepareCall(sql);
this.getFilter().setParametersInCallableStatement(callableStatement);
ResultSet rs = callableStatement.executeQuery();
resultDTO = ResultSetUtils.populateInList(classT, rs);
Ebean.commitTransaction();
Logger.debug("commitTransaction > " + sql);
} catch (Exception e) {
Ebean.rollbackTransaction();
Logger.debug("rollbackTransaction > " + sql);
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
Ebean.endTransaction();
}
return resultDTO;
}
...
}