天道酬勤,学无止境

使用条件休眠更新单列(hibernate update single column using criteria)

问题

我有一个包含 mamy 列的表,我想更新该行的一列或几列而不影响剩余的列,我可以编写查询:

update table as t set t.a=:a set t.b=:b where t.id=1

但是看到我不知道会选择更新哪些列,而且我认为每个场景都编写每个查询不是一个好主意。 好吧,我必须为每个场景编写查询,但我正在寻找一种更好的方法来动态更新表。 我认为标准将是一个不错的选择。 但问题是我不知道如何编写标准更新特定列。 我的代码现在可以更新该列,但它会将其他列设置为 null 或空。

在不更改其他列的情况下更新特定列的好方法是什么?

回答1

Hibernate 支持两种基本的方式来更新表的列。

第一个是自然的,通过将实体加载到session ,在运行时更改它,将更改刷新(更新)回数据库。 这是一个标准的ORM 风格。

第二个主要面向非常高效的 SQL UPDATE语句。 此处记录为:

15.4. DML 风格的操作

从文档中引用:

... 但是,Hibernate 提供了通过 Hibernate 查询语言执行的批量 SQL 样式 DML 语句执行的方法...

它不提供用于条件查询的 API,但它可以与 HQL == 一起使用我们的域模型。

我们可以在我们映射的实体之上创建一个 WHERE 子句,并只要求更新我们选择的几列。 有一些限制(不支持 JOIN)但可以通过子查询来解决...

这是文档的一个片段:

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

String hqlUpdate = "update Customer c set c.name = :newName where c.name = :oldName";
// or String hqlUpdate = "update Customer set name = :newName where name = :oldName";
int updatedEntities = session.createQuery( hqlUpdate )
        .setString( "newName", newName )
        .setString( "oldName", oldName )
        .executeUpdate();
tx.commit();
session.close();

另请检查此 Q&Q:Hibernate 使用条件执行更新

回答2

使用 JPA,您可以这样做。

CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaUpdate<User> criteria = builder.createCriteriaUpdate(User.class);
Root<User> root = criteria.from(User.class);
criteria.set(root.get("fname"), user.getName());
criteria.set(root.get("lname"), user.getlastName());
criteria.where(builder.equal(root.get("id"), user.getId()));
session.createQuery(criteria).executeUpdate();
回答3

.setString( "newName", newName ) -- 已弃用,新方法如下!

int updatedEntities1 = session.createQuery( hqlUpdate )
                    .setParameter("column_name", value)
                    .executeUpdate();

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 休眠条件查询以获取特定列(Hibernate Criteria Query to get specific columns)
    问题 我在代码中使用了条件查询。 它总是触发select * from ... 相反,我想忽略查询中的一列(字段),因为该字段具有以字节为单位存储的大量数据。 这会导致性能问题。 有人可以对此提出想法吗? 一些更新 我在查询中添加了一个投影,它创建了一个查询,例如... select this_.TEMPLATE_ID as y0_, this_.TEMPLATE_NAME as y1_, this_.CREATE_DATE as y2_, this_.UPDATE_DATE as y3_, this_.STATUS_CODE as y4_, this_.USER_ID as y5_, this_.UPDATED_BY as y6_, this_.CATEGORY_ID as y7_, this_.PRACTICE_ID as y8_ from templates this_ inner join user user1_ on this_.USER_ID=user1_.USER_ID inner join template_categories category2_ on this_.CATEGORY_ID=category2_.CATEGORY_ID where y4_=? and y8_=? and y5_ in ( ?, ? ) order by y1_ asc limit
  • 在休眠条件查询中选择“所有列”和“分组依据”(select “all columns” with “group by” in hibernate criteria queries)
    问题 我想使用“group by”编写一个条件查询并希望返回所有列。 平面sql是这样的: select * from Tab group by client_name order by creation_time; 我知道它将有count(distinct client_name)行数。 我当前的查询似乎没有给出正确的结果如下: Criteria criteria = getSession(requestType).createCriteria(Tab.class); criteria.setProjection(Projections.projectionList().add(Projections.groupProperty("client_name"))); criteria.addOrder(Order.asc("creationTime")); 此查询仅返回"client_name" 。 我不想手动放置所有列名。 一定有办法,有什么办法? 回答1 我想你误解了一些东西。 如果在 SQL 中使用GROUP BY ,则需要按所有选定的列进行分组。 这同样适用于休眠-如果你groupProperty的Projection ,你告诉Hibernate的是该列是一组列。 如果没有引用其他列/字段,Hibernate 会假设您不需要它们,因为它们也需要分组。 退后一步:你想做什么?
  • 如何使用Hibernate选择列?(How do you select a column using Hibernate?)
    问题 我想使用Hibernate选择单列而不是整个对象。 到目前为止,我有这个: List<String> firstname = null; firstname = getSession().createCriteria(People.class).list(); 我的问题是上述代码将整个People表返回为一个对象,而不仅仅是“ firstname”。 我不确定如何指定仅返回“名字”而不是整个对象。 回答1 您可以像这样设置投影: .setProjection(Projections.property("firstname")) 有了这个,您只能得到名字的回报。 我在相同情况下在堆栈上找到了另一个链接。 希望这也将对您有所帮助。如何使用休眠条件仅返回对象的一个​​元素,而不返回整个对象? 回答2 如果您需要查询2列或更多列并从查询中获取值,则可以使用以下方法: .... crit.setProjection(Projections.property("firstname")); crit.setProjection(Projections.property("lastname")); List result = crit.list(); ... for (Iterator it = result.iterator(); it.hasNext(); ) { Object[]
  • 带有两列的子查询的休眠条件查询(Hibernate criteria query with subquery joining two columns)
    问题 我有一个名为“ Quote”的表,该表在休眠状态下映射,该表具有一个整数ID和一个日期的复合键以及几个其他列。 我想编写一个使用DetachedCriteria的条件查询,以获取日期最大的每个ID的行。 在SQL中,我可能会写一个查询 SELECT * FROM Quote q1 INNER JOIN (SELECT id, max(date) as maxdate FROM Quote GROUP BY id, date) q2 ON q1.id = q2.id AND q1.date = q2.maxdate 在休眠状态下,我认为可以像这样为“ group by”子查询创建一个DetachedCriteria(其中Quote是映射表的类,而Qid是键的复合ID类,具有属性id和日期,可以通过Quote类的“ qid”属性): DetachedCriteria maxDateQry = DetachedCriteria.forClass(Quote.class); maxDateQry.setProjection( Projections.projectionList() .add(Projections.max("qid.date", "maxdate")) .add(Projections.groupProperty("qid.id"))); 但是
  • 在休眠条件中使用 mysql“按案例排序”(using mysql “order by case” in hibernate criteria)
    问题 我使用的是 Hibernate 4.3.1 final,Mysql 5.5,我想在一些连接的实体上使用“按案例排序”的顺序逻辑。 我希望实现的纯 sql 表示如下所示: select adv.id, adv.published_date from advert as adv join account as act on act.id = adv.act_id join account_status as aas on aas.id = act.current_aas_id order by case aas.status when 'pending' THEN 1 when 'approved' THEN 1 else 2 end, adv.published_date; 这会在停用帐户的广告之前对待定和已批准帐户的广告进行排序。 我已经设法使用休眠条件完成所有选择查询,但我不确定如何使用该 api 指定按 case 语句排序。 我找到了这个帖子: http://blog.tremend.ro/2008/06/10/how-to-order-by-a-custom-sql-formulaexpression-when-using-hibernate-criteria-api/ 但我需要按案例的顺序引用加入的实体类,我不知道该怎么做。 非常感谢任何帮助或建议。 回答1
  • 我可以使用休眠条件调用存储过程吗?(Can I call a stored procedure with hibernate criteria?)
    问题 我可以使用 Hibernate 标准来调用存储过程吗? 回答1 请参阅参考文档中的使用存储过程进行查询。 映射查询就是这样调用的。 List employment = sess.getNamedQuery("BigSP") .list(); 映射查询可以返回实体。 <sql-query name="BigSP" callable="true"> <return alias="emp" class="Employment"> <return-property name="employee" column="EMPLOYEE"/> <return-property name="employer" column="EMPLOYER"/> <return-property name="startDate" column="STARTDATE"/> <return-property name="endDate" column="ENDDATE"/> <return-property name="regionCode" column="REGIONCODE"/> <return-property name="id" column="EID"/> <return-property name="salary"> <return-column name="VALUE"/> <return
  • 休眠:获取太多行(Hibernate: getting too many rows)
    问题 我在使用Hibernate从数据库获取行时遇到问题。 当我只想获得一行时,我收到20。当我想从表中获得约1.5k行的所有行时,我正好接收15.2k行。 该表的实体类具有复合主键。 这是我获取所有行的代码: Criteria criteria = getSession().createCriteria(type); criteria.setCacheable(true).setCacheRegion(BaseEntity.PACKAGE); criteria.list(); 这是我的Entity类: @javax.persistence.Entity @Table(name = "my_table") public class My extends MyEntity<MyPK> { @EmbeddedId private MyPK id; @Column(name = "text", nullable = false) protected String text; @ManyToOne @JoinColumn(name = "property", nullable = false, insertable = false, updatable = false) protected Option option; @Override public MyPK getId() {
  • 休眠查询语言或使用条件?(hibernate query language or using criteria?)
    问题 任何使用条件/ hql / sql告诉我查询的人。 要求是用户输入电子邮件或用户名查询从表user返回用户的密码。 回答1 如果您正在做的只是获取一个字段,那么您可能只想使用hql(或者可能是sql)。 如果您符合条件,我相信您将撤回整个对象,只是为了最终使用一个字段。 编辑:这是一个非常广泛的问题。 这是一个教程 回答2 Criteria API非常适合动态查询生成,在此我会优先考虑。 您可以执行以下操作: Criteria criteria = session.createCriteria(User.class) .setProjection(Projections.property("password")); if (email != null) { criteria.add(Expression.eq("email", email)); } if (username != null) { criteria.add(Expression.eq("username", username)); } String password = (String) criteria.uniqueResult(); 请注意,我有点推断,但您不应在数据库中存储明文密码,也不应通过电子邮件发送密码(从本质上讲是不安全的)。 实际上,密码恢复的常见过程是通过邮件发送寿命有限的链接
  • 使用条件查询限制加入休眠搜索查询(Join hibernate search query with criteria query restriction)
    问题 我想知道您如何将以下两个查询连接在一起。 标准条件查询 Criteria result1 = session.createCriteria(Store.class).add(Restrictions.eq("department.name", category)); 和全文搜索 QueryBuilder queryBuilder = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(Store.class).get(); Query luceneQuery = queryBuilder.keyword().onFields("productTitle").matching(keyword).createQuery(); // wrap Lucene query in a javax.persistence.Query org.hibernate.Query fullTextQuery = fullTextSession.createFullTextQuery(luceneQuery, Store.class); fullTextQuery.setMaxResults(15); fullTextQuery.setFirstResult(0); 我通过 URL 加一个关键字参数传入附加参数
  • 使用 SINGLE_TABLE 继承策略运行条件时,“调用 getter of”时发生 IllegalArgumentException(“IllegalArgumentException occurred calling getter of” while running criteria with SINGLE_TABLE Inheritance strategy)
    问题 我在尝试使用用简单限制装饰的休眠条件列出数据库中的对象时遇到此错误 Criteria criteria = session.createCriteria(Licence.class); criteria.add(Restrictions.eq("gym", gym.getId())); List<Licence> list = criteria.list(); 我有两个类: Licence与Gym有关联。 这两个类正在扩展DataModel ,它用于管理有关数据编辑的信息 - (创建和设置,谁和何时)。 这两个类具有@Inheritance(strategy = InheritanceType.SINGLE_TABLE)也很重要。 执照 @Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) public class Licence extends DataModel implements Serializable { private Gym gym; private String licenceType; private String keyCode; private Date expireDate; private ELicenceExpiry expired; public Licence() { }
  • 休眠顺序为null(Hibernate order by with nulls last)
    问题 在按列对desc排序时,与PostgreSQL DB一起使用的Hibernate会将空值设置为大于非空值。 SQL99标准提供了关键字“ NULLS LAST”来声明应将空值设置为低于非空值。 使用Hibernate的Criteria API是否可以实现“ NULLS LAST”行为? 回答1 鉴于HHH-465尚未修复,并且由于史蒂夫·埃伯索尔(Steve Ebersole)给出的原因而不会在近期内修复,您最好的选择是全局或专门使用附加到该问题的CustomNullsFirstInterceptor来更改SQL语句。 我在下面将其发布给读者(Emilio Dolce的积分): public class CustomNullsFirstInterceptor extends EmptyInterceptor { private static final long serialVersionUID = -3156853534261313031L; private static final String ORDER_BY_TOKEN = "order by"; public String onPrepareStatement(String sql) { int orderByStart = sql.toLowerCase().indexOf(ORDER_BY_TOKEN); if
  • 休眠条件:左外连接,两个表均受限制(Hibernate Criteria: Left Outer Join with restrictions on both tables)
    问题 我正在做LEFT OUTER JOIN,但是我只能在第一个表上应用限制。 ti是否也可以应用于第二个表? 这是我的代码: Criteria criteria = this.crudService .initializeCriteria(Applicant.class).setFetchMode("products", FetchMode.JOIN);. 此工程(申请人具有applicantName属性): criteria.add(Restrictions.eq("applicantName", "Markos") 这些都不起作用(产品具有productName属性) criteria.add(Restrictions.eq("productName", "product1") criteria.add(Restrictions.eq(“ products.productName”,“ product1”)//产品:属性的名称criteria.add(Restrictions.eq(“ Product.productName”,“ product1”)//产品:数据库表的名称 这是我收到的异常消息(如果我理解正确的话),申请人中不存在productName属性: EJB Exception: ; nested exception is: org.hibernate
  • 使用条件查询检索多态休眠对象(Retrieving Polymorphic Hibernate Objects Using a Criteria Query)
    问题 在我的模型中,我有一个抽象的“用户”类,以及多个子类,例如申请人、招聘经理和面试官。 它们在一个表中,我有一个 DAO 来管理它们。 用户: @Entity @Table(name="User") @Inheritance(strategy=InheritanceType.SINGLE_TABLE) @DiscriminatorColumn( name="role", discriminatorType=DiscriminatorType.STRING ) public abstract class User extends BaseObject implements Identifiable<Long> ... 招聘经理(例如): @Entity @DiscriminatorValue("HIRING_MANAGER") public class HiringManager extends User ... 现在,如果我想获得所有与部门无关的招聘经理,我该怎么做? 我想它看起来像这样: DetachedCriteria c = DetachedCriteria.forClass(User.class); c.add(Restrictions.eq("role", "HIRING_MANAGER")); c.add(Restrictions.isNull(
  • 休眠条件:是否可以使用条件访问数据库视图?(Hibernate Criteria: Is it possible to access a database view with criteria?)
    问题 我有一个标准,我正在尝试将其加入数据库视图。 我想知道是否有可能,如果有的话该怎么做? 据我了解, createAlias和createCriteria仅加入根标准的子对象。 我阅读了detachedCriteria ,但似乎需要在数据库实体上创建这些实体,而视图不是。 HQL 等价物将是这样的 select * from root_criteria rc where rc.id in (select view.id from DATABASE_VW view where view.field is not null) 提前致谢 回答1 您可以尝试 XML 映射来创建指向数据库视图的实体类。 实体中的每个字段都将映射到从视图中选择的字段。 文档摘录: Hibernate 映射的视图和基表之间没有区别。 这在数据库级别是透明的,尽管某些 DBMS 不正确支持视图,尤其是更新时。 子选择(可选):将不可变的只读实体映射到数据库子选择。 如果您想要一个视图而不是一个基表,这很有用。 下面是示例配置,请相应地修改它。 <class name="MappedClassName" mutable="false"> <subselect> select view.id as viewId from DATABASE_VW view </subselect> ... </class> 回答2
  • 休眠删除查询(Hibernate Delete query)
    问题 当我尝试从数据库中删除条目时,使用 session.delete(object) 然后我可以执行以下操作: 1)如果该行存在于数据库中,则将执行两个SQL查询:一个选择,然后一个删除 2)如果数据库中不存在该行,则仅执行选择查询 但是同样,更新不是这种情况。 无论是否存在数据库行,都只会执行更新查询。 请让我知道为什么这种行为用于删除操作。 这不是性能问题,因为遇到了两个查询而不是一个查询? 编辑: 我正在使用休眠3.2.5 样例代码: SessionFactory sessionFactory = new Configuration().configure("student.cfg.xml").buildSessionFactory(); Session session = sessionFactory.openSession(); Student student = new Student(); student.setFirstName("AAA"); student.setLastName("BBB"); student.setCity("CCC"); student.setState("DDD"); student.setCountry("EEE"); student.setId("FFF"); session.delete(student); session
  • 复杂的休眠投影(Complex Hibernate Projections)
    问题 我想问一下,我有可能为多于一层的深度创建查询投影和标准吗? 我有 2 个模型类: @Entity @Table(name = "person") public class Person implements Serializable { @Id @GeneratedValue private int personID; private double valueDouble; private int valueInt; private String name; @OneToOne(cascade = {CascadeType.ALL}, orphanRemoval = true) @JoinColumn(name="wifeId") private Wife wife; /* * Setter Getter */ } @Entity @Table(name = "wife") public class Wife implements Serializable { @Id @GeneratedValue @Column(name="wifeId") private int id; @Column(name="name") private String name; @Column(name="age") private int age; /* * Setter Getter */
  • 休眠与iBATIS的比较(Hibernate Vs iBATIS [closed])
    问题 关闭。 此问题不符合堆栈溢出准则。 它当前不接受答案。 想要改善这个问题吗? 更新问题,使它成为Stack Overflow的主题。 3年前关闭。 改善这个问题 对于我们的新产品重新设计,我们正在从Java中选择最佳框架。 由于考虑采用模型的数据库不可知方法,因此我们正在研究iBATIS或Hibernate在Struts + Spring之间的选项。 请提出最佳建议,因为两者都可以提供持久性。 回答1 iBATIS和Hibernate是完全不同的野兽。 我倾向于这样看待它:如果您的视图以对象为中心,则Hibernate会更好地工作。 但是,如果您认为以数据库为中心,那么iBATIS是一个更强大的选择。 如果您完全控制模式,并且对吞吐量没有极高的要求,那么Hibernate可以很好地工作。 对象模型使得代码相当方便,但是却付出了巨大的复杂性。 如果您要处理“传统”数据库架构,需要编写相当复杂的SQL查询,那么iBATIS可能会更好地工作。 HQL(休眠查询语言)是您必须学习的另一种语言,即使那样,您仍然可能会发现仍然需要编写SQL的情况。 而且,您有机会花半天的时间弄清楚XML,属性,注释等的正确组合,以使Hibernate生成高效的SQL查询。 对于此问题,没有通用的“ A优于B”答案。 回答2 考虑一下您要实现的目标。 通常,命令查询响应隔离模型适用于复杂域。
  • 使用休眠条件的左连接(Left join using hibernate criteria)
    问题 我有两个实体: Issue和Issue_Tracker 。 我正在使用休眠 3.6。 SELECT `issues`.`issue_id`, `issues`.`issue_raised_date`, `issues`.`issue_description`, `issue_tracker`.`tracker_status` FROM `issues` LEFT JOIN `issue_tracker` ON `issues`.`issue_id` = `issue_tracker`.`issue_id` WHERE `issues`.`status`="Escalate To" 如何使用 Hibernate Criteria 实现这一点,最重要的是,我必须使用它进行分页。 和My Dao如下显示jqgrid中的Issue列表 公共列表 showHelpDeskIssues(DetachedCriteria dc, int from, int size) { Session session = HibernateUtil.getSessionFactory().getCurrentSession(); try { Criteria criteria = dc.getExecutableCriteria(session); criteria.setFirstResult
  • 休眠-更新表中的主键“ id”列(Hibernate - update the primary key 'id' column in the table)
    问题 在我的Java应用程序中,我正在使用hibernate .hbm文件访问数据库。 是否可以更新表中的主键“ id”列; 我的.hbm文件中的“ id”列如下所示: <hibernate-mapping package="org.jems.user.model"> <class name="Student_Details" table="t_student"> <id name="id" type="int" column="id"> <generator class="increment"/> </id> <property name="name" column="name" type="string" unique="true" not-null="true" /> <property name="description" column="description" type="string" /> <property name="comments" column="comments" type="string" /> <property name="active" column="isActive" type="boolean" not-null="true" /> </class> </hibernate-mapping> 回答1 试试这个: String hql=
  • 在这种情况下如何使用 DISTINCT 创建休眠条件(How to create hibernate criteria with DISTINCT in this case)
    问题 我正在使用休眠条件来创建 postgres 查询: criteria.addOrder(Order.asc(property).ignoreCase()).setProjection( Projections.distinct(Projections.property("name"))); 它生成类似于下面的 sql: select DISTINCT name from table1 order by lower( name) asc; 当这个 sql 被执行时,会出现以下错误: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list 我知道这违反了 postgres 规则,但是当我查看错误时,我发现我们不应该在 order by 子句中使用任何函数。 如果使用它,那么我们需要有两个解决方法: 使用嵌套选择如下: select name from (select distinct name from table1) as aliasname order by lower(name) asc; 在 select 和 order by 子句中使用 lower 函数。 select DISTINCT lower(name) from table1 order by lower(name)