2

ライブラリを使用して DB から POJO (State.java) を作成したいと思いApache DBUtilsます。ただし、Bean プロパティの名前が DB 列名と正確に一致しないため、一部のプロパティは未入力のままです。

さて、グーグルでこれについていくつかの調査を行ったところ、これは次の方法で達成できることがわかりました。

  1. SQLクエリを書いているときの列のエイリアシング(いくつかの大きなテーブルに複数の結合があり、多くのエイリアシングが必要になるため、私は好まない)
  2. BeanProcessor の使用 (どこにも本当に良い例が見つかりませんでした)

BeanProcessor列名をプロパティにマップする方法の良い例を誰か提供できますか? 私が提供した例を微調整すると、さらに良くなります。

DB テーブル

CREATE TABLE public.states (
  state_id INTEGER DEFAULT nextval('states_seq'::regclass) NOT NULL,
  state_cd VARCHAR(2) NOT NULL,
  name VARCHAR(100) NOT NULL,
  tax_pct NUMERIC(10,2) DEFAULT 0.00 NOT NULL,
  active CHAR(1) DEFAULT 'Y'::bpchar NOT NULL,
) 

状態.java

  public class State implements Serializable {

    private int stateId;
    private String stateCode;
    private String name;
    private BigDecimal taxPct = new BigDecimal(0);
    private Date expiryDate;
    private String createdBy;
    private Date createdOn;
    private String active;

    //getters and setters here
}

Main.java

    public class Main {

    public static void main(String[] args) {
        String url = "jdbc:postgresql://gsi-547576.gsiccorp.net:5432/istore-db";
        String driver = "org.postgresql.Driver";
        String user = "postgres";
        String pwd = "postgres";
        Connection conn = null;
        List<State> states = null;

        try {
            DbUtils.loadDriver(driver);
            conn = DriverManager.getConnection(url, user, pwd);

            states = (List<State>) new QueryRunner().query(conn, "select * from states a where a.active='Y'", new BeanListHandler(State.class);

            System.out.println("states::  " + states);

        } catch (SQLException ex) {
            ex.printStackTrace();
        } finally {
            DbUtils.closeQuietly(conn);
        }
    }

}
4

5 に答える 5

7
Map<String,String> mapColumnsToProperties = new HashMap<>();
//mapping you database to entity here;
mapColumnsToProperties.put("database_column","entity_property");
BeanProcessor beanProcessor = new BeanProcessor(mapColumnsToProperties);
RowProcessor rowProcessor = new BasicRowProcessor( beanProcessor); 
ResultSetHandler<List<Entity>> resultSetHandler = new BeanListHandler<Entity>(Entity.class,rowProcessor);
List<Entity> entityLists = queryRunner.query(findListSQL, resultSetHandler);    
于 2016-12-21T07:32:04.750 に答える
2

私は中国出身です。私の英語はあまり上手ではありません。しかし、この問題は私の解決策です。dbutils はオープン ソースであるため、ソース コードを変更し、maven を使用して自分だけの jar を作成できます。BeanProcessor クラスを変更するだけで、次のchangeColumnNameような名前のメソッドを追加できます。

public  String changeColumnName(String columnName){
        if(columnName == null){
            return null;
        }
        if(columnName.contains("_")){
            char[] cs = columnName.toCharArray();
            int flag = -1;
            for(int index=0;index<columnName.toCharArray().length;index++){
                if(cs[index] == '_'){
                    flag = index;
                    break;
                }
            }
            columnName = columnName.substring(0, flag) + columnName.substring(flag+1,flag+2).toUpperCase() + columnName.substring(flag+2);
            return changeColumnName(columnName);
        }else{
            return columnName;
        }
    }

そしてメソッドで

protected int[] mapColumnsToProperties(ResultSetMetaData rsmd,
        PropertyDescriptor[] props) throws SQLException {

    int cols = rsmd.getColumnCount();
    int[] columnToProperty = new int[cols + 1];
    Arrays.fill(columnToProperty, PROPERTY_NOT_FOUND);

    for (int col = 1; col <= cols; col++) {
        String columnName = rsmd.getColumnLabel(col);
        if (null == columnName || 0 == columnName.length()) {
          columnName = rsmd.getColumnName(col);
        }
        String propertyName = columnToPropertyOverrides.get(columnName);
        if (propertyName == null) {
            propertyName = changeColumnName(columnName);//add here
        }
        for (int i = 0; i < props.length; i++) {

            if (propertyName.equalsIgnoreCase(props[i].getName())) {
                columnToProperty[col] = i;
                break;
            }
        }
    }

    return columnToProperty;
}

それは問題を解決することができます.私と議論することを歓迎します.私のGoogleメールはguomin.bai@gmail.comです

于 2016-08-26T06:41:39.313 に答える
1

BeanProcessor の Java ドキュメントを見ると、次のようになります。

protected int[] mapColumnsToProperties(ResultSetMetaData rsmd, PropertyDescriptor[] props) が SQLException をスローします

返された配列内の位置は、列番号を表します。各位置に格納されている値は、列名に一致する Bean プロパティの PropertyDescriptor[] 内のインデックスを表します。列の Bean プロパティが見つからない場合、位置は PROPERTY_NOT_FOUND に設定されます。パラメータ: rsmd - 列情報を含む ResultSetMetaData。props - Bean プロパティ記述子。戻り値: 列インデックスからプロパティ インデックスへのマッピングを含む int[]。JDBC 列のインデックスは 1 から始まるため、0 番目の要素は無意味です。

次のように、メソッドを拡張しBeanProcessorてオーバーライドするクラスを作成する必要があるようです。mapColumnsToProperties

public class StateBeanProcessor extends BeanProcessor {

    @Override
    protected  int[] mapColumnsToProperties(ResultSetMetaData rsmd, PropertyDescriptor[] props) throws SQLException {
          int[] mapping = super.mapColumnsToProperties(rsmd, props);
          /*Map database columns to fields in the order in which they appear
            1st column in the DB will be mapped to 1st field in the Java
            class and so on.. */
          for(int i=0;i<mapping.length;++i) {
             mapping[i]=i;
          }
      }
  }

次に、上記の StateBeanProcessor を次のようにコードにプラグインできます。

states = (List<State>) new QueryRunner().query(conn, "select * from states", new BeanListHandler(State.class,new BasicRowProcessor(new StateBeanProcessor())));

免責事項 :このコードはテストしていません。これは、カスタム フィールド マッピングを作成するために組み合わせることができる断片を示すことを目的としています。問題が見つかった場合は、私にお知らせください。調査いたします。

于 2015-04-24T14:24:27.163 に答える