使用'ParameterizedPreparedStatementSetter'设置参数有没有更好的优化代码的方法?
Is there any better way to optimize code in setting parameters using 'ParameterizedPreparedStatementSetter'?
实际上我正在使用 JDBCTemplate,它可以使用 ParameterizedPreparedStatementSetter
对象批量插入。
但是查询参数多的时候设置参数很不方便。
在我的例子中,实际上,它有 44 个参数。
这是我的代码。
jdbcTemplate.batchUpdate(query.toString(), batchArgs, listSize,
new ParameterizedPreparedStatementSetter<DocUsageDTO>() {
@Override
public void setValues(PreparedStatement ps, DocUsageDTO arg) throws SQLException {
ps.setString(1, arg.getClientIp());
ps.setInt(2, arg.getClientOs());
ps.setString(3, arg.getClientOsVersion());
ps.setString(4, arg.getContentCode());
ps.setString(5, arg.getContentCreateTime());
ps.setString(6, arg.getContentName());
ps.setString(7, arg.getCurrentContentName());
ps.setString(8, arg.getDeptCode());
ps.setString(9, arg.getDeptName());
ps.setString(10, arg.getDomainCode());
ps.setString(11, arg.getEtc1());
ps.setString(12, arg.getEtc2());
ps.setString(13, arg.getEtc3());
ps.setString(14, arg.getEtc4());
ps.setString(15, arg.getEtc5());
ps.setString(16, arg.getFileSyncId());
ps.setString(17, arg.getFileSyncManagerCode());
ps.setString(18, arg.getFileSyncManagerName());
ps.setString(19, arg.getFileSyncRevisionNo());
ps.setString(20, arg.getFileSyncTagCode());
ps.setString(21, arg.getFileSyncTagName());
ps.setInt(22, arg.getLocationContext());
ps.setString(23, arg.getLogDate());
ps.setInt(24, arg.getLogType());
ps.setString(25, arg.getOwnerCode());
ps.setString(26, arg.getOwnerDeptCode());
ps.setString(27, arg.getOwnerDeptName());
ps.setString(28, arg.getOwnerName());
ps.setString(29, arg.getPositionCode());
ps.setString(30, arg.getPositionName());
ps.setString(31, arg.getProcessCode());
ps.setString(32, arg.getProcessName());
ps.setInt(33, arg.getProductType());
ps.setInt(34, arg.getPurpose());
ps.setInt(35, arg.getPurposeFailReason());
ps.setInt(36, arg.getPurposeStatus());
ps.setString(37, arg.getSecLevelCode());
ps.setString(38, arg.getSecLevelName());
ps.setString(39, arg.getUserCode());
ps.setString(40, arg.getUserName());
ps.setString(41, arg.getWriterCode());
ps.setString(42, arg.getWriterDeptCode());
ps.setString(43, arg.getWriterDeptName());
ps.setString(44, arg.getWriterName());
}
});
使用ParameterizedPreparedStatementSetter
设置参数有没有更好的优化代码的方法?
您可以使用命名参数语句而不是像这样手动分配每个参数以提高可读性:
Connection con=getConnection();
String query="select * from my_table where name=:name or
docUsageDTO =:docUsageDTO ";
NamedParameterStatement p=new NamedParameterStatement(con, query);
p.setString("name", "bob");
p.setString("docUsageDTO", arg); // this just expects all paramters as string ! Didn't want to copy and edit your lengthy code
ResultSet rs=p.executeQuery();
通过这种方式,您也许可以创建通用方法来设置参数,方法是通过循环传递参数名称和值,或者可以减少代码的方法。
否则,如果您想减少代码但不介意添加繁重的库,那么使用 Hibernate 可以减轻您的负担。
您的问题不在于 ParameterizedPreparedStatementSetter
,而是您的查询具有如此多的参数,以至于 任何 代码都会显得笨重。
您可以尝试 NamedParameterJdbcTemplate
在地图中提供参数,但随后您将以某种方式将这 44 个参数放入地图中,这可能仍需要等量的代码。
你可以把你当前的 StatementSetter 变成一个真正的 class(而不是现在的匿名的),然后它至少会被封装并且看不见。毕竟只是外表的问题,代码本身并没有什么问题。这将使您的服务 class 看起来更干净,例如
jdbcTemplate.batchUpdate(query.toString(), batchArgs, listSize, new DocUsageDTOSetter());
实际上,您不一定需要 NamedParameterJdbcTemplate, as it can use a bean source 的地图。但是,这需要参数名称与属性相匹配。这意味着 INSERT INTO FOO(bar, baz) VALUES (?, ?)
变为 INSERT INTO FOO(bar, baz) VALUES (:myBeanProperty1, :myBeanProperty2)
,并且您必须包装每个 DTO。所以你会把(源代码)角色移动到不同的地方,并添加一些额外的对象创建。
实际上我正在使用 JDBCTemplate,它可以使用 ParameterizedPreparedStatementSetter
对象批量插入。
但是查询参数多的时候设置参数很不方便。
在我的例子中,实际上,它有 44 个参数。
这是我的代码。
jdbcTemplate.batchUpdate(query.toString(), batchArgs, listSize,
new ParameterizedPreparedStatementSetter<DocUsageDTO>() {
@Override
public void setValues(PreparedStatement ps, DocUsageDTO arg) throws SQLException {
ps.setString(1, arg.getClientIp());
ps.setInt(2, arg.getClientOs());
ps.setString(3, arg.getClientOsVersion());
ps.setString(4, arg.getContentCode());
ps.setString(5, arg.getContentCreateTime());
ps.setString(6, arg.getContentName());
ps.setString(7, arg.getCurrentContentName());
ps.setString(8, arg.getDeptCode());
ps.setString(9, arg.getDeptName());
ps.setString(10, arg.getDomainCode());
ps.setString(11, arg.getEtc1());
ps.setString(12, arg.getEtc2());
ps.setString(13, arg.getEtc3());
ps.setString(14, arg.getEtc4());
ps.setString(15, arg.getEtc5());
ps.setString(16, arg.getFileSyncId());
ps.setString(17, arg.getFileSyncManagerCode());
ps.setString(18, arg.getFileSyncManagerName());
ps.setString(19, arg.getFileSyncRevisionNo());
ps.setString(20, arg.getFileSyncTagCode());
ps.setString(21, arg.getFileSyncTagName());
ps.setInt(22, arg.getLocationContext());
ps.setString(23, arg.getLogDate());
ps.setInt(24, arg.getLogType());
ps.setString(25, arg.getOwnerCode());
ps.setString(26, arg.getOwnerDeptCode());
ps.setString(27, arg.getOwnerDeptName());
ps.setString(28, arg.getOwnerName());
ps.setString(29, arg.getPositionCode());
ps.setString(30, arg.getPositionName());
ps.setString(31, arg.getProcessCode());
ps.setString(32, arg.getProcessName());
ps.setInt(33, arg.getProductType());
ps.setInt(34, arg.getPurpose());
ps.setInt(35, arg.getPurposeFailReason());
ps.setInt(36, arg.getPurposeStatus());
ps.setString(37, arg.getSecLevelCode());
ps.setString(38, arg.getSecLevelName());
ps.setString(39, arg.getUserCode());
ps.setString(40, arg.getUserName());
ps.setString(41, arg.getWriterCode());
ps.setString(42, arg.getWriterDeptCode());
ps.setString(43, arg.getWriterDeptName());
ps.setString(44, arg.getWriterName());
}
});
使用ParameterizedPreparedStatementSetter
设置参数有没有更好的优化代码的方法?
您可以使用命名参数语句而不是像这样手动分配每个参数以提高可读性:
Connection con=getConnection();
String query="select * from my_table where name=:name or
docUsageDTO =:docUsageDTO ";
NamedParameterStatement p=new NamedParameterStatement(con, query);
p.setString("name", "bob");
p.setString("docUsageDTO", arg); // this just expects all paramters as string ! Didn't want to copy and edit your lengthy code
ResultSet rs=p.executeQuery();
通过这种方式,您也许可以创建通用方法来设置参数,方法是通过循环传递参数名称和值,或者可以减少代码的方法。
否则,如果您想减少代码但不介意添加繁重的库,那么使用 Hibernate 可以减轻您的负担。
您的问题不在于 ParameterizedPreparedStatementSetter
,而是您的查询具有如此多的参数,以至于 任何 代码都会显得笨重。
您可以尝试 NamedParameterJdbcTemplate
在地图中提供参数,但随后您将以某种方式将这 44 个参数放入地图中,这可能仍需要等量的代码。
你可以把你当前的 StatementSetter 变成一个真正的 class(而不是现在的匿名的),然后它至少会被封装并且看不见。毕竟只是外表的问题,代码本身并没有什么问题。这将使您的服务 class 看起来更干净,例如
jdbcTemplate.batchUpdate(query.toString(), batchArgs, listSize, new DocUsageDTOSetter());
实际上,您不一定需要 NamedParameterJdbcTemplate, as it can use a bean source 的地图。但是,这需要参数名称与属性相匹配。这意味着 INSERT INTO FOO(bar, baz) VALUES (?, ?)
变为 INSERT INTO FOO(bar, baz) VALUES (:myBeanProperty1, :myBeanProperty2)
,并且您必须包装每个 DTO。所以你会把(源代码)角色移动到不同的地方,并添加一些额外的对象创建。