问题描述
我在 kotlin 中有一个函数,我很好奇是否有办法让它看起来更“干净”?
我有可能为空/可选的参数
override fun readByOrderId(orderId: Int,eventType: EventType?,version: Int?): OrderDomain? {
var sql = "SELECT * FROM Orders WHERE id=?"
if(eventType != null)
{
sql += " AND eventType=?"
}
if(version != null)
{
sql += " AND version=?"
}
val result: MutableList<OrderDomain> = jdbcTemplate.query<OrderDomain>(
sql,PreparedStatementSetter { preparedStatement -> preparedStatement.setInt(1,orderId)
preparedStatement.setString(2,eventType.toString())
preparedStatement.setInt(3,version},RowMapper { rs: ResultSet,rowNum: Int ->
OrderDomain(
rs.getLong(DataColumn.EVENT_ID.toString()),)
}
)
}
但是,preparedStatement 的放置可能是一个问题,而 toString 可能会抛出 NPE……我可以调整 PreparedStatement 中的任何内容,因为两个空字段是可选字段?
解决方法
这就是我有条件地将适当的参数添加到语句并保持索引有序的方式。
PreparedStatementSetter { it.apply {
var index = 1
setInt(index++,orderId)
if (eventType != null) {
setString(index++,eventType.toString())
}
if (version != null) {
setInt(index++,version)
}
} }
,
null.toString()
在 Kotlin doesn't throw NPE 中,它返回字符串“null”。
为了避免显式参数索引声明,我建议将所有参数放在一个列表中(以便它们在列表中的顺序与它们在查询中的顺序相匹配)并使用 setObject
方法(因此所有类型的参数可以用普通的方式处理):
PreparedStatementSetter {
val params = listOfNotNull(
orderId,eventType.toString().takeIf { eventType != null },version
)
params.forEachIndexed { index,param -> it.setObject(index + 1,param) }
}