DBUtils не удается заполнить поля Java-компонента

#java #mysql #javabeans #apache-commons-dbutils

#java #mysql #javabeans #apache-commons-dbutils

Вопрос:

У меня есть таблица mysql, подобная этой:

 CREATE TABLE `sezione_menu` (
 `id_sezione_menu` int(11) unsigned NOT NULL AUTO_INCREMENT,
 `nome` varchar(256) NOT NULL DEFAULT '',
 `ordine` int(11) DEFAULT NULL,
    PRIMARY KEY (`id_sezione_menu`)
 )ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
  

Я использую apache dbutils для запроса к моей базе данных с помощью этих методов:

 public static List<SezioneMenu> getSezioniMenu() {
    String sql = "SELECT * FROM sezione_menu";  
    try {
        QueryRunner qr = new QueryRunner(createDataSource());
        ResultSetHandler rsh = new BeanListHandler(SezioneMenu.class);
        List<SezioneMenu> sezioni = (List<SezioneMenu>)qr.query(sql, rsh);
        return sezioni;
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return null;  
}

private static DataSource createDataSource() {
        BasicDataSource d = new BasicDataSource();
        d.setDriverClassName(DRIVER);
        d.setUsername(USERNAME);
        d.setPassword(PASSWORD);
        d.setUrl(DB_URL);
        return d;
    }
  

Теперь, если я запускаю свое приложение, оно не выдает исключение, но некоторые поля (не все!) моего Java bean SezioneMenu пусты (целочисленное поле равно нулю, а строковое поле равно пустой строке).
Это происходит также с другими таблицами и компонентами.
Я использовал этот метод в прошлом в другой конфигурации системы без проблем.

Комментарии:

1. Когда вы пишете свои запросы и bean-компоненты, вы гарантируете, что либо поля в вашем bean имеют те же имена, что и столбцы вашей базы данных, либо переименовываете свои столбцы в соответствии с тем, что находится в bean? Вы не сказали, какие поля не заполнены, но я подозреваю, что это может быть первое поле, которое у вас может быть, например, названо в camelCase в коде Java при использовании подчеркивания в инструкции SQL.

2. Вы должны поделиться SezioneMenu.class java-код для проверки правильного имени вашего поля или нет?

Ответ №1:

Вы можете исправить это двумя способами:

Согласно dbutils doc,

  1. Измените имена столбцов в SQL, чтобы они соответствовали именам Java: выберите social_sec# в качестве socialSecurityNumber от person
  2. Создайте подкласс BeanProcessor и переопределите метод mapColumnsToProperties(), чтобы удалить символы-нарушители.

Если вы сохраняете класс, подобный этому

 public class SezioneMenuBean implements Serializable {

    private int idSezioneMenu;

    private String nome;

    private int ordine;

    public SezioneMenuBean() {
    }

    // Getters and setters for bean values

}
  

В соответствии с первым решением напишите свои запросы примерно так SELECT id_sezione_menu AS idSezioneMenu, name, ordine FROM sezione_menu .

Или

На основе второго решения, которое вы можете использовать, GenerousBeanProcessor которое является подклассом BeanProcessor , оно игнорирует подчеркивание и чувствительность к регистру в имени столбца. Вам не нужно реализовывать свой собственный пользовательский BeanProcessor

GenerousBeanProcessor доступно с версии 1.6 commons-dbutils.

Использование:

 // TODO initialize
QueryRunner queryRunner = null;

ResultSetHandler<List<SezioneMenuBean>> resultSetHandler =
                new BeanListHandler<SezioneMenuBean>(SezioneMenuBean.class, new BasicRowProcessor(new GenerousBeanProcessor()));

// best practice is specifying only required columns in the query
// SELECT id_sezione_menu, name, ordine FROM sezione_menu
final List<SezioneMenuBean> sezioneMenuBeans = queryRunner.query("SELECT * FROM sezione_menu", resultSetHandler);

for (SezioneMenuBean sezioneMenuBean : sezioneMenuBeans) {
    System.out.println(sezioneMenuBean.getIdSezioneMenu());
}
  

Ответ №2:

Я столкнулся с той же проблемой, что BeanHandler / BeanHandlerList возвращал null или 0 для столбцов базы данных.

Как упоминалось @aelfric5578 в комментарии, я обновил класс Bean с теми же именами, что и Database, DBUtils вернул значения правильно.

Определение BeanClass подобным образом решит вашу проблему.

 открытый класс SezioneMenuBean{

 int id_sezione_menu;
 Строковый номер;
 int ordine;

 общедоступный РазделeMenuBean(){
 }

 // Средства получения и установки значений компонента

 }