web-dev-qa-db-ja.com

Java Spring-RowMapperResultSet-整数/ null値

Java SE 8 Spring 4.1.6-RELEASEアプリケーションがあります。ここで _org.springframework.jdbc.core.RowMapper<T>_ インターフェースを実装していますが、-についていくつか質問がありました。 _Java.sql.ResultSet_ その T mapRow(ResultSet rs, int rowNum) メソッドで渡されるインターフェース。

ResultSetクラスを調べると、列の値を取り戻すための一連のメソッドが表示されます。

╔==============╦=====================╦======= ================================================== ================================================== ================================================= 
║戻り値の型║メソッド║戻り値(javadoc、se 8)║
╠==============╬========== ===========╬====================================== ================================================== ================================================== ==================╣
║文字列║getString║列の値。値がSQLNULLの場合、返される値はnull║
║ブール値║getBoolean║列値。値がSQLNULLの場合、返される値はfalse║
║バイト║getByte║列の値です。値がSQLNULLの場合、返される値は0║
║short║getShort║列値です。値がSQLNULLの場合、返される値は0║
║int║getInt║列の値です。値がSQLNULLの場合、返される値は0║
║long║getLong║列値です。値がSQLNULLの場合、返される値は0║
║float║getFloat║列の値です。値がSQLNULLの場合、返される値は0║
║double║getDouble║列の値です。値がSQLNULLの場合、返される値は0║
║BigDecimal║getBigDecimal║列の値です。値がSQLNULLの場合、返される値はnull║
║byte[]║getBytes║列の値。値がSQLNULLの場合、返される値はnull║
║日付║getDate║列の値。値がSQLNULLの場合、返される値はnull║
║時間║getTime║列の値。値がSQLNULLの場合、返される値はnull║
║タイムスタンプ║getTimestamp║列の値。値がSQLNULLの場合、返される値はnullです║
║InputStream║getAsciiStream║a Java 1バイトのストリームとしてデータベース列の値を配信する入力ストリーム= ASCII文字;値がSQLNULLの場合、返される値はnullです║
║リーダー║getCharacterStream║列の値を含むJava.io.Readerオブジェクト;値の場合がSQLNULLの場合、返される値はJavaプログラミング言語║
║InputStream║getBinaryStream║aJava入力ストリームで解釈されないバイトのストリームとしてのデータベース列値。値がSQLNULLの場合、返される値はnullです║
║<T> T║getObject║列値を保持するタイプのインスタンス║
 ╚===== =========╩========================================= ================================================== ================================================== =======================================╝

一般的な期待/実践は次のように呼びますか?

_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);
_

など、すべてのプリミティブ型について?他のすべては_SQL NULL_のインスタンスに対してnullを返します。

もしそうなら、型付きオブジェクトメソッドが存在するときに、さまざまな型のすべてのメソッドを持つことの意味は何ですか?

また、各アプローチの長所/短所は何ですか?

  1. getInt(String columnLabel)の使用:

    _Integer resultingActionId = rs.getInt("RESULTING_ACTION_ID");
    if (rs.wasNull) {
        resultingActionId = null
    }_
  2. getObject(String columnLabel)を使用してIntegerにキャストする:

    Integer resultingActionId = (Integer) rs.getObject("RESULTING_ACTION_ID");
  3. getObject(String columnLabel, Class type)の使用:

    Integer resultingActionId = rs.getObject("RESULTING_ACTION_ID", Integer.class);

たとえば、私は _org.springframework.jdbc.core.JdbcTemplate_ が以前持っていたことに気づきました queryForLong、 queryForInt、など、単一の行クエリから単一の値を取得し、型付きのqueryForObjectメソッドを優先してそれらすべてを置き換えるためのメソッド。

ありがとう!

10
anonymous

Java.sql.ResultSet を見ると、それほど明示的である必要はないことがわかります。実際には、getObjectメソッドを使用できる接続用のtypeMapperがない限り、機能しません( Java.sql.ResultSet.getObject )。

それがあなたに役立つかどうかはわかりませんが、私は自分のニーズに最適な自分の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() );
    }
}

これはたくさんのコードだと思いますが、ここで何が達成されたかがわかるといいのですが。実際のRowMapper実装は、実際には、行情報からオブジェクトを抽出するためのすべての「ダーティワーク」を格納することを目的としています。

データベースが正しくセットアップされていて、必要な列にNOT NULLが含まれるように設定している限り、空の行を引き出すという問題が発生することはありません。 ResultSetからのnull応答をチェックしても問題はないと思いますが、列に値が必要な場合は、とにかく例外をスローすることになります。

1
aaiezza