Java Spring - RowMapper ResultSet - 整数/空值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33266078/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java Spring - RowMapper ResultSet - Integer/null values
提问by anonymous
I have a Java SE 8 Spring 4.1.6-RELEASE application, where I am implementing the org.springframework.jdbc.core.RowMapper<T>
interface, and I had some questions about the java.sql.ResultSet
interface that is passed in its T mapRow(ResultSet rs, int rowNum)
method.
我有一个 Java SE 8 Spring 4.1.6-RELEASE 应用程序,我在其中实现了org.springframework.jdbc.core.RowMapper<T>
接口,我对java.sql.ResultSet
在其T mapRow(ResultSet rs, int rowNum)
方法中传递的接口有一些疑问。
When I inspect the ResultSet
class, I see a bunch of methods to get column values back:
当我检查这个ResultSet
类时,我看到了一堆方法来获取列值:
╔══════════════╦═════════════════════╦════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗ ║ Return Type ║ Method ║ Return (javadoc, se 8) ║ ╠══════════════╬═════════════════════╬════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣ ║ String ║ getString ║ the column value; if the value is SQL NULL, the value returned is null ║ ║ boolean ║ getBoolean ║ the column value; if the value is SQL NULL, the value returned is false ║ ║ byte ║ getByte ║ the column value; if the value is SQL NULL, the value returned is 0 ║ ║ short ║ getShort ║ the column value; if the value is SQL NULL, the value returned is 0 ║ ║ int ║ getInt ║ the column value; if the value is SQL NULL, the value returned is 0 ║ ║ long ║ getLong ║ the column value; if the value is SQL NULL, the value returned is 0 ║ ║ float ║ getFloat ║ the column value; if the value is SQL NULL, the value returned is 0 ║ ║ double ║ getDouble ║ the column value; if the value is SQL NULL, the value returned is 0 ║ ║ BigDecimal ║ getBigDecimal ║ the column value; if the value is SQL NULL, the value returned is null ║ ║ byte[] ║ getBytes ║ the column value; if the value is SQL NULL, the value returned is null ║ ║ Date ║ getDate ║ the column value; if the value is SQL NULL, the value returned is null ║ ║ Time ║ getTime ║ the column value; if the value is SQL NULL, the value returned is null ║ ║ Timestamp ║ getTimestamp ║ the column value; if the value is SQL NULL, the value returned is null ║ ║ InputStream ║ getAsciiStream ║ a Java input stream that delivers the database column value as a stream of one-byte ASCII characters; if the value is SQL NULL, the value returned is null ║ ║ Reader ║ getCharacterStream ║ a java.io.Reader object that contains the column value; if the value is SQL NULL, the value returned is null in the Java programming language ║ ║ InputStream ║ getBinaryStream ║ a Java input stream that delivers the database column value as a stream of uninterpreted bytes; if the value is SQL NULL, the value returned is null ║ ║ <T> T ║ getObject ║ an instance of type holding the column value ║ ╚══════════════╩═════════════════════╩════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
Is the genernal expectation / practice to call:
是一般的期望/做法调用:
rs.getObject("COLUMN_NAME", Boolean.class);
rs.getObject("COLUMN_NAME", Byte.class);
rs.getObject("COLUMN_NAME", Short.class);
rs.getObject("COLUMN_NAME", Integer.class);
rs.getObject("COLUMN_NAME", Long.class);
etc., for all of the primitive types? As everything else returns null
for the instance of SQL NULL
.
等等,对于所有的原始类型?由于一切回报null
的实例SQL NULL
。
If so, what's the point of having all the methods for the different types when the typed Object method is there?
如果是这样,当类型化 Object 方法存在时,拥有不同类型的所有方法有什么意义?
Also, what are the pros/cons of each approach?
另外,每种方法的优缺点是什么?
Using
getInt(String columnLabel)
:Integer resultingActionId = rs.getInt("RESULTING_ACTION_ID"); if (rs.wasNull) { resultingActionId = null }
Using
getObject(String columnLabel)
and casting toInteger
:Integer resultingActionId = (Integer) rs.getObject("RESULTING_ACTION_ID");
Using
getObject(String columnLabel, Class type)
:Integer resultingActionId = rs.getObject("RESULTING_ACTION_ID", Integer.class);
使用
getInt(String columnLabel)
:Integer resultingActionId = rs.getInt("RESULTING_ACTION_ID"); if (rs.wasNull) { resultingActionId = null }
使用
getObject(String columnLabel)
和投射到Integer
:Integer resultingActionId = (Integer) rs.getObject("RESULTING_ACTION_ID");
使用
getObject(String columnLabel, Class type)
:Integer resultingActionId = rs.getObject("RESULTING_ACTION_ID", Integer.class);
For instance, I noticed the org.springframework.jdbc.core.JdbcTemplate
used to have , queryForLong
, etc. methods for getting a single value from a single row query and replaced them all in favor of a typed queryForInt
queryForObject
method.
例如,我注意到org.springframework.jdbc.core.JdbcTemplate
以前有,queryForLong
等方法用于从单行查询中获取单个值,并将它们全部替换为类型化queryForInt
queryForObject
方法。
Thanks!
谢谢!
回答by aaiezza
If you take a look at java.sql.ResultSet, you can see you don't need to be so explicit. Actually, unless you have a typeMapper for you connection which allows you to use the getObject method, it will not work (java.sql.ResultSet.getObject).
如果您查看java.sql.ResultSet,您会发现您不需要如此明确。实际上,除非您有一个允许您使用 getObject 方法的连接类型映射器,否则它将无法工作(java.sql.ResultSet.getObject)。
I don't know if it would help you, but I managed to find a RowMapper of my own that worked great for my needs.
我不知道它是否会帮助你,但我设法找到了一个我自己的 RowMapper,它非常适合我的需求。
private class ShabaUserMapper implements RowMapper<ShabaUser>
{
@Override
public ShabaUser mapRow( ResultSet rs, int rowNum ) throws SQLException
{
Collection<SimpleGrantedAuthority> roles = new ArrayList<SimpleGrantedAuthority>();
String auths = rs.getString( "role" );
roles.add( new SimpleGrantedAuthority( auths ) );
ShabaUser user = new ShabaUser( rs.getString( "username" ), rs.getString( "password" ),
rs.getBoolean( "enabled" ), rs.getString( "first_name" ),
rs.getString( "last_name" ), rs.getString( "email" ),
rs.getString( "date_joined" ), rs.getString( "last_online" ), true, true, true,
roles );
// Can be null!
Integer awesomeness = rs.getInt( "awesomeness" );
if ( rs.wasNull() )
{
awesomeness = null;
}
user.setAwesomeness( awesomeness );
return user;
}
}
private class ShabaUserListExtractor implements ResultSetExtractor<List<ShabaUser>>
{
private final ShabaUserMapper rowMapper;
private int rowsExpected;
public ShabaUserListExtractor()
{
this( new ShabaUserMapper(), 0 );
}
public ShabaUserListExtractor( ShabaUserMapper rowMapper, int rowsExpected )
{
Assert.notNull( rowMapper, "RowMapper is required" );
this.rowMapper = rowMapper;
this.rowsExpected = rowsExpected;
}
@Override
public List<ShabaUser> extractData( ResultSet rs ) throws SQLException
{
HashMap<String, ShabaUser> results = ( this.rowsExpected > 0
? new HashMap<String, ShabaUser>(
rowsExpected )
: new HashMap<String, ShabaUser>() );
int rowNum = 0;
while ( rs.next() )
{
ShabaUser user = rowMapper.mapRow( rs, rowNum++ );
if ( results.containsKey( user.getUsername() ) )
{
ShabaUser inUser = results.get( user.getUsername() );
ArrayList<GrantedAuthority> combinedAuthorities = new ArrayList<GrantedAuthority>();
combinedAuthorities.addAll( inUser.getAuthorities() );
combinedAuthorities.addAll( user.getAuthorities() );
results.put( user.getUsername(),
createUserDetails( user.getUsername(), user, combinedAuthorities ) );
} else
{
results.put( user.getUsername(), user );
}
}
return new ArrayList<ShabaUser>( results.values() );
}
}
I realize this is a lot of code, but hopefully you can see what was accomplished here. The actual RowMapper implementation is actually meant to house all the "dirty work" for extracting your object from row information.
我意识到这是很多代码,但希望你能看到这里完成了什么。实际的 RowMapper 实现实际上是为了容纳从行信息中提取对象的所有“脏工作”。
So long as your database is setup correctly and you make it so NOT NULL is on required columns, you will never run into the problem of pulling out a row that is empty. Though I suppose it wouldn't hurt to check for a null response from your ResultSet, you'll still just end up throwing an exception anyways if the column should of had a value.
只要您的数据库设置正确,并且在所需的列上设置为 NOT NULL,您就永远不会遇到拉出空行的问题。虽然我认为检查 ResultSet 中的空响应不会有什么坏处,但如果该列应该有一个值,您仍然最终会抛出异常。