Ответ 1
Я не знаю, достаточно ли грааля, чтобы сказать, возможно ли это в нем. Я попытался создать поля вставки SQL, указав свойства класса и составляя его динамически, но он вышел из строя.
Вы можете создать аннотацию для определения положения этого поля в CSV:
import java.lang.annotation.*
@Retention(RetentionPolicy.RUNTIME) @interface CSV { int position() }
class Product {
@CSV(position=1) String description
@CSV(position=3) BigDecimal price
@CSV(position=4) Integer type
@CSV(position=2) boolean soldout
}
Если вам нужно несколько сопоставлений (например, для поддержки старых CSV, например), вам следует рассмотреть структуру карты или XML, которые будут отделены от объекта.
Затем вам нужно итерировать поля для составления запроса:
def csv = '''rice;10.0;3;false
beet;12.0;2;false
mango;22.0;2;true'''
def properties = Product.declaredFields
.findAll { it.declaredAnnotations }
.sort { it.declaredAnnotations[0].position() }
def templateQuery = "INSERT INTO product(#fields) VALUES (#values)"
csv.eachLine { line ->
def fields = line.split( /;/ )
def sqlFields = [:]
fields.eachWithIndex { field, i ->
sqlFields[properties[i].name] = field
}
println templateQuery
.replace('#fields', sqlFields.keySet().join(","))
.replace('#values', sqlFields.values().join(","))
}
Какие принты:
INSERT INTO product(description,price,type,soldout) VALUES (rice,10.0,3,false)
INSERT INTO product(description,price,type,soldout) VALUES (beet,12.0,2,false)
INSERT INTO product(description,price,type,soldout) VALUES (mango,22.0,2,true)
Он довольно сырой и нуждается в некоторой полировке, например, цитатах и некоторых материалах против SQL-инъекций, но он работает, скорее, как доказательство концепции.
В более старой системе, в которой я работал, мы использовали шов jboss и те части, которые мы работали с пакетом jpa, т.е. ручная очистка, когда все persist()
были выполнены. Вы уверены, что нет ничего подобного в grails для использования с gorm?
Эта ссылка показывает сообщение в блоге об использовании пакетного обновления в grails, используя withTransaction
, в то время как регулярное использование сеанса clear:
List <Person> batch =[]
(0..50000).each{
Person person= new Person(....)
batch.add(person)
println "Created:::::"+it
if(batch.size()>1000){
Person.withTransaction{
for(Person p in batch){
p.save()
}
}
batch.clear()
}
session = sessionFactory.getCurrentSession()
session.clear()
}
Вы уверены, что это не сработает? Если нет, то аннотация может быть решением.
Также есть проблема с названием столбца, из-за разницы между флагом java camel и подчеркиванием в db. Парень за этим переводом в спящем режиме - это ImprovedNamingStrategy. Может быть, вы можете что-то получить от него. Или добавьте имя столбца в аннотацию @CSV
. Похоже на переработку JPA: -).
Существует также log4jdbc, но я думаю, что это не решит вашу проблему: вам нужно прокрасться в hibernate sql поколение.