Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Чтение данных из xml и запись их в БД


Автор: Grelloo 29.6.2006, 15:19
Ситуация следующая:
Ко мне приходит xml, я распарсиваю его и получаю
property, value, type
Пример: property = "Name", value = "Dima", type = "String"
Создаю массивы этих данных property[], value[], type[] и засовываю в ArrayList. Далее эти массивы разбираю с помощью PreparedStatement и засовываю в БД
     
Код

   String sql = "insert into "+table+" (";
        try {
        for(int i=0; i<list.size(); i++){
            sql = sql + property[i] + ", ";
        }
        sql = sql.substring(0, sql.length()-2) + ") values (";
        for(int i=0; i<list.size(); i++){
            sql = sql + "?, ";
        }
        sql = sql.substring(0, sql.length()-2) + ")";
        System.out.println(sql);
        PreparedStatement ps = c.prepareStatement(sql);
        for(int i=0; i<list.size(); i++){
            System.out.print(data[i] + " ");
            ps.setObject(i+1, data[i]);
        }
            int p = ps.executeUpdate();


Это работает, но хотелось бы чего-то менее грамоздкого  

Автор: powerOn 29.6.2006, 15:56
Ты используешь PreparedStatement, так зачем же несколько раз его создавать? PreparedStatement - это преварительно компилируемый запрос, создай его один раз:

Код

PreparedStatement ps = c.prepareStatement("insert into ? (?,?) values (?,?)");


а в цикле только значения подставляй. К примеру:

Код

PreparedStatement ps = c.prepareStatement("insert into ? (?, ?) values (?, ?)");

ps.setString(1, tableName);
ps.setString(2, prorertyColunm);
ps.setString(3, valueColunm);

for(int i = 0 ; i < recordCount; i++) {
     ps.setString(4, property[i]);
     ps.setString(5, value[i]);
     ps.executeUpdate();
}


так можно избавиться от грамозких операций со сложением строк.

  

Автор: batigoal 29.6.2006, 16:08
Grelloo, 
Цитата(MoonCat @  29.6.2006,  16:56 Найти цитируемый пост)
так можно избавиться от грамозких операций со сложением строк.

...которые, к тому же, очень вредны, потому что их планы не кешируются на уровне БД. 

Автор: Grelloo 29.6.2006, 16:29
Property должны быть в качестве названий столбцов и их чило заранее неизвестно, а здесь
Код

ps.setString(2, prorertyColunm);
ps.setString(3, valueColunm);

совсем другие столбцы property и values
База выглядит следующим образом
property1 property2 .. propertyN
value 1     value2      .. valueN
value 1     value2      .. valueN 

Автор: batigoal 29.6.2006, 16:33
Тогда PreparedStatement для тебя бесполезен. Либо вставляй в пустые колонки null'ы. 

Автор: Grelloo 29.6.2006, 16:45
У меня массивы property[] и value[] заполнены значениями и не содержат null. Каждому poperty соответствует свой value. Почему же я не могу использовать PreparedStatment? 

Автор: batigoal 29.6.2006, 16:56
Цитата(Grelloo @  29.6.2006,  17:45 Найти цитируемый пост)
Почему же я не могу использовать PreparedStatment?  

Можешь, просто это не даст тебе прироста в случае динамических запросов. 

Автор: powerOn 29.6.2006, 16:57
Цитата(Grelloo @  29.6.2006,  17:29 Найти цитируемый пост)
совсем другие столбцы property и values
База выглядит следующим образом
property1 property2 .. propertyN
value 1     value2      .. valueN
value 1     value2      .. valueN  


У тебя таблица не нормальзованна, её лучше на 2 разбить.

На :

propertyName, Value, ObjID

и :
ObjID, ObjName


где ObjName - объект который обладает определенными свойствами из превой таблицы. 

Автор: Grelloo 29.6.2006, 17:15
Так, мне кажется я не совсем полность изложил свою задачу и поэтому происходит непонимание.
Как я уже говорил приходит файл xml и из него вытаскивается property и value, которые являются первым уровнем от корневого элемента. То есть имеется следующая структура (это описание класса засунутого в xml):
Код

<root>
  <object>
     <property1>value1<property1>
     <property2>value2<property1>
     .......
     <propertyN>valueN</propertyN>
  </object>
<root>

Теперь зная propery и value надо создать одну строку в базе данных, где каждому property соответствует свое value. Причем primary key задается сразу и является одним из property. 

Автор: powerOn 29.6.2006, 17:30
Сколько таких xml файлов? (Сколько обектов?)
Число свойств фиксированно или нет? Они могут быть пустыми? 

Автор: Grelloo 30.6.2006, 09:58
В каждом xml файле может содеражться несколько тегов <object>, причем у каждого object свой класс
Код

<object class = "class1">
</object>
<object class = "class2">
</object>

В зависимости от атрибута class выбирается parser class (с помощью HashMap), который будет обрабатывать данный тег <object>
Код

class1 ParserClass1
class2 ParserClass2

Кажый ParserClass заранее знает все property, которые ему придут. Соответственно если property пустое, то присваивается значение null.  

Автор: powerOn 30.6.2006, 10:25
Я так понимаю, что у тебя есть несколько объектов, каждый из которых обладает пременным числом свойств (в зависимости от класса), некоторые из которых могут быть пустыми. (?) Так чем тебе не подходит такая структура БД:

2 таблицы, в первой: 
1) id (счетчик) объекта 
2) имя класса. 

Во второй: 
1) id объетка (из первой таблицы)
2) имя свойства и 
3) значение свойства. 

Связь между записями по идентификатору объекта. 
ИМХО, так нормализованней будет. К тому же и Java код заметно упростится. Если свойство какого либо равно null, то и записи о нем просто нет. Единственный недостаток - все записи будут строками, даже числа. 
 

Автор: Grelloo 30.6.2006, 10:35
Нет у меня для каждого class будет своя таблица в БД. Как мне лучше организовать PreparedStatement для этого случая? 

Автор: powerOn 30.6.2006, 10:48
Цитата(Grelloo @  30.6.2006,  11:35 Найти цитируемый пост)
Нет у меня для каждого class будет своя таблица в БД. Как мне лучше организовать PreparedStatement для этого случая?  


для каждой таблицы свой "заточенный" PreparedStatement. Сколько таблиц (сколько возможных запросов на добавление) - столько PreparedStatement. Либо как в ты делал - сложение строк для формирования запроса, но тогда все плюсы PreparedStatement пропадут и скорости в выполнении запросов ты не получишь. Задесь можно смело использовать просто Statement.

P.S.: ... либо 2 простых запроса в PreparedStatement на добавление любого объекта, при моей организации БД.

 

Автор: Grelloo 30.6.2006, 15:33
Все-таки как-то странно получается: если заранее неизвестно сколько будет столбцов в таблице, то подготовить PreparedStatment достаточно сложно, т. к. приходится явно указывать все символы "?". Может есть другие варианты? 

Автор: Larrr 2.7.2006, 19:59
Попробуй глянь http://www-128.ibm.com/developerworks/java/library/j-lucene/ - на первый взгляд это может быть то, что тебе нужно, уже готовое ;) 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)