我有一张学生表,想要删除班上的所有学生。
所以我的SQL查询看起来像:
delete from student where classId = 333
如何使用带有标准的休眠来执行此操作?
我需要这个,所以我可以放入我的一个基类,供从它扩展的任何DAO对象使用。所以我可以在所有DAO对象中使用它。
目前我已经创建了一个将在Student对象中使用的泛型方法 - 调用使用条件获取列表的find方法,然后在一个事务下执行批量删除,如下所示:
public boolean deleteByCriteria(Object deleteObject) {
List deleteObjectList = find(deleteObject);
if (deleteObjectList == null)
return false;
return deleteAll(deleteObjectList);
}
public boolean deleteAll(List deleteObjectList) {
if (logger.isDebugEnabled()) {
logger.debug("Entered BaseSchoolRollBookDAO -> delete");
logger.debug("Object for batch deletion [" + deleteObjectList + "]");
}
boolean result = false;
Transaction tx = null;
// Get CurrentSession from HibernateUtils
Session session = HibernateUtils.getSession();
// Start transaction
tx = session.beginTransaction();
// Create new Criteria to be passed
try {
int flushCount = 0;
for (Object deleteObject : deleteObjectList) {
session.delete(deleteObject);
flushCount++;
if (flushCount % 20 == 0) {
session.flush();
session.clear();
}
}
tx.commit();
result = true;
} catch (HibernateException e) {
logger.fatal("Exception in executing batch Delete query", e);
if (tx != null && tx.isActive())
tx.rollback();
}
return result;
}
答案 0 :(得分:69)
对于删除,使用最佳选项的HQL,我认为,标准的主要目的仅用于检索数据。
这个是Criteria
Student student = (Student ) session.createCriteria(Student.class)
.add(Restrictions.eq("classId", classId)).uniqueResult();
session.delete(student);
这个是简单的HQL查询:
String hql = "delete from Student where classId= :classId";
session.createQuery(hql).setString("classId", classId).executeUpdate();
答案 1 :(得分:8)
您可以通过以下简单的休眠方式轻松实现,
Session session=getSession();
String hql = "delete from Student where classId= :id";
session.createQuery(hql).setLong("id", new Integer(id)).executeUpdate();
了解详情refer
答案 2 :(得分:4)
这是最好的方式,比@Jama Asatillayev的答案更好。 因为您不必首先检索持久对象。
Product product = new Product();
product.setId(37);
session.delete(product);
hibernate将运行:
Hibernate: delete from PRODUCT where PRODUCT_ID=?
答案 3 :(得分:3)
您应该将您的hibernate版本升级到实现JPA 2.1的版本(Hibernate在版本4.3.11上启动JPA 2.1.Final - Hibernate Downloads)
升级后,您可以使用 CriteriaDelete 来执行您想要的操作。 这是一个小例子: Example
答案 4 :(得分:1)
您可以在条件
中使用条件public Integer deleteByFieldIn(String Field, Iterable<?> values) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaDelete<T> delete = cb.createCriteriaDelete(getDomainClass());
Root<T> e = delete.from(getDomainClass());
delete.where(cb.in(e.get(Field)).value(values));
return entityManager.createQuery(delete).executeUpdate();
}
并且您可以通过替换为等于
来使用相同的条件public Integer deleteById(String id) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaDelete<T> delete = cb.createCriteriaDelete(getDomainClass());
Root<T> e = delete.from(getDomainClass());
delete.where(cb.equal(e.get("id"), id));
return entityManager.createQuery(delete).executeUpdate();
}
答案 5 :(得分:0)
/**
*
* @param objects
*/
public static void deleteAll(List<?> objects) {
try {
HibernateEntityManager em = JPA.em().unwrap(HibernateEntityManager.class);
Session session = em.getSession();
for (Object o : objects) {
session.delete(o);
}
} catch (Exception e) {
Logger.error("CommonHibernateBD_deleteAll error: " + e);
e.printStackTrace();
}
}
答案 6 :(得分:0)
我知道我参加聚会很晚,但是如果您碰巧使用JPA 2.1,则可以这样做-
https://thoughts-on-java.org/criteria-updatedelete-easy-way-to/
public void deleteOrder(Double amount) {
CriteriaBuilder cb = this.em.getCriteriaBuilder();
// create delete
CriteriaDelete<Order> delete = cb.
createCriteriaDelete(Order.class);
// set the root class
Root e = delete.from(Order.class);
// set where clause
delete.where(cb.lessThanOrEqualTo(e.get("amount"), amount));
// perform update
this.em.createQuery(delete).executeUpdate();
}
答案 7 :(得分:0)
要删除,必须使用CriteriaDelete
查询。 CriteriaBuilder
确保正确使用查询是安全的。将元数据类Student_
添加到您的方法中,以避免HQL
,JPQL
或NativeQuery
特有的错误。
...
private EntityManager em;
...
public void deleteByIdUser(int classId) {
try {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaDelete<Student> deleteQuery = builder.createCriteriaDelete(Student.class);
Root<Student> studentTable = deleteQuery.from(Student.class);
Path<Long> classIdPath = userRoleTable.get(Student_.classId);
Predicate classIdPredicate = builder.equal(classIdPath, classId);
deleteQuery.where(classIdPredicate);
em.createQuery(deleteQuery).executeUpdate();
} catch (Exception e) {
...
}
}
此信息必须添加到pom才能为您的实体生成元数据类。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
这很冗长,但避免了多余的RuntimeExceptions
。
答案 8 :(得分:-1)
首先你需要一个带输入的表单,输入的值是你在modelmap中建模的模型,而不是 使 删除 在一些链接。 比得到id参数,用 @requestparam(&#34; id&#34;)字符串id
知道我们得到了对象的id 然后删除id e.g。
@RequestMapping(value="delsubloc",method=RequestMethod.GET)
public String DeleteLoc(@RequestParam("id")Long id) {
PplLocDtlDAO dtl = new PplLocDtlDAO();
PplLocDtl loc = new PplLocDtl();
loc.setLocDtlId((long)id);
dtl.delete(loc);
return "redirect:/lokasi";
}