我对 grails 的了解还不足以说明其中是否有可能。我尝试通过列出类属性并动态组合它来生成 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 seam 并在我们使用 jpa 批处理的那些散装东西上,即在所有persist()
完成后手动冲洗。你确定grails上没有类似的东西可以与gorm一起使用吗?
此链接显示了在 grails 中使用批量更新的博客文章,withTransaction
同时使用了定期应用会话清除:
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的驼峰式大小写和db中的下划线之间的差异,列命名也存在问题。在休眠状态下,该翻译背后的人是ImprovementNamingStrategy。也许你可以从他那里得到一些东西。@CSV
或者在注释中添加列名。听起来像回收 JPA :-)。
还有log4jdbc,但我认为它不会解决您的问题:您需要潜入休眠 sql 生成。