网站开发工程师职责,工会网站建设管理工作总结,防伪码查询网站怎么做的,江苏优化网站哪家好从JPA 2.0版开始#xff0c; EntityManager提供了方法getCriteriaBuilder()来动态构建选择查询#xff0c;而无需使用Java持久性查询语言#xff08;JPQL#xff09;进行字符串连接。 在2.1版中#xff0c;此CriteriaBuilder提供了两个新方法createCriteriaDelete()和crea… 从JPA 2.0版开始 EntityManager提供了方法getCriteriaBuilder()来动态构建选择查询而无需使用Java持久性查询语言JPQL进行字符串连接。 在2.1版中此CriteriaBuilder提供了两个新方法createCriteriaDelete()和createCriteriaUpdate() 使我们可以使用条件API制定删除和更新查询的方法。 出于说明目的让我们对两个实体Person和Geek使用简单的继承用例 Entity
Table(name T_PERSON)
Inheritance(strategy InheritanceType.JOINED)
public class Person {IdGeneratedValueprivate Long id;Column(name FIRST_NAME)private String firstName;Column(name LAST_NAME)private String lastName;...
}Entity
Table(name T_GEEK)
Access(AccessType.PROPERTY)
public class Geek extends Person {private String favouriteProgrammingLanguage;...
} 要从我们的数据库中删除所有喜欢Java作为其编程语言的怪胎我们可以使用EntityManager的新createCriteriaDelete()方法利用以下代码 EntityTransaction transaction null;
try {transaction entityManager.getTransaction();transaction.begin();CriteriaBuilder builder entityManager.getCriteriaBuilder();CriteriaDeleteGeek delete builder.createCriteriaDelete(Geek.class);RootGeek geekRoot delete.from(Geek.class);delete.where(builder.equal(geekRoot.get(favouriteProgrammingLanguage), Java));int numberOfRowsUpdated entityManager.createQuery(delete).executeUpdate();LOGGER.info(Deleted numberOfRowsUpdated rows.);transaction.commit();
} catch (Exception e) {if (transaction ! null transaction.isActive()) {transaction.rollback();}
} 与纯SQL一样我们可以使用from()方法指定要针对其发出删除查询的表并使用where()声明谓词。 通过这种方式标准API允许以动态方式定义批量删除操作而无需使用过多的字符串连接。 但是SQL是如何创建的呢 首先ORM提供程序必须注意我们正在使用策略JOINED从继承层次结构中删除这意味着我们有两个表T_PERSON和T_GEEK 其中第二个表存储对父表的引用。 Hibernate版本4.3.8.Final创建以下SQL语句 insert
intoHT_T_GEEKselectgeek0_.id as id fromT_GEEK geek0_ inner joinT_PERSON geek0_1_ on geek0_.idgeek0_1_.id wheregeek0_.FAV_PROG_LANG?;delete
fromT_GEEK
where(id) IN (selectid fromHT_T_GEEK);delete
fromT_PERSON
where(id) IN (selectid fromHT_T_GEEK)delete
fromHT_T_GEEK; 如我们所见Hibernate使用与我们的搜索条件匹配的极客/人员的ID填充了一个临时表。 然后它将删除极客表中的所有行然后删除人员表中的所有行。 最后临时表被清除。 删除语句的顺序很明确因为表T_GEEK在T_PERSON表的id列上具有外键约束。 因此子表中的行必须在父表中的行之前删除。 本文介绍了Hibernate创建临时表的原因。 概括起来潜在的问题是查询限制了仅在子表中存在的列上要删除的行。 但是子表中的行必须在父表中的相应行之前删除。 删除子表中的行即所有具有FAV_PROG_LANGJava的怪胎后由于已经删除了怪胎行因此无法随后删除所有对应的人员。 解决该问题的方法是临时表该临时表首先收集应删除的所有行ID。 知道所有ID后可以使用此信息先从怪胎表中删除行然后从人员表中删除行。 上面生成的SQL语句当然独立于标准API的用法。 使用JPQL方法会导致生成相同的SQL EntityTransaction transaction null;
try {transaction entityManager.getTransaction();transaction.begin();int update entityManager.createQuery(delete from Geek g where g.favouriteProgrammingLanguage :lang).setParameter(lang, Java).executeUpdate();LOGGER.info(Deleted update rows.);transaction.commit();
} catch (Exception e) {if (transaction ! null transaction.isActive()) {transaction.rollback();}
} 当我们将继承策略从JOINED更改为SINGLE_TABLE 生成的SQL语句也更改为单个此处的鉴别DTYPE列为DTYPE delete
fromT_PERSON
whereDTYPEGeek and FAV_PROG_LANG?结论 用于删除和更新的标准API的新增功能使您可以构造SQL语句而无需任何字符串连接。 但是请注意从继承层次结构中进行批量删除可能会迫使基础ORM使用临时表以便组装必须事先删除的行列表。 翻译自: https://www.javacodegeeks.com/2015/02/jpa-2-1-criteria-deleteupdate-temporary-tables-hibernate.html