【问题标题】:How to query a property of type List<String>in JPA如何在 JPA 中查询 List<String> 类型的属性
【发布时间】:2010-12-30 21:22:40
【问题描述】:

假设我们有这个带有 JPA 注释的类,其属性类型为 List。此代码目前运行良好。

@Entity
public class Family {
    ...
    @CollectionOfElements(targetElement=java.lang.String.class)
    @JoinTable(name = "elements_family",
        joinColumns = @JoinColumn(name = "idFamily")
    )
    @Column(name = "element", nullable = false)
    private List<String> elements;
    ...
}

有没有办法查询包含元素“yyy”的家庭列表?也就是说,类似于:

Query query = getEntityManager().createQuery("select f FROM Family f WHERE element = :element");
query.setParameter("element", "yyy");
return query.getResultList();

【问题讨论】:

    标签: java hibernate jpa jpql


    【解决方案1】:
    List<Family> found = getHibernateTemplate().find(
    "from Family as f join f.elements as e where e = ?",
    new Object[]{"yyy"});
    

    【讨论】:

      【解决方案2】:

      请注意,您使用的是 Hibernate 特定功能 CollectionOfElements。这不是严格意义上的 JPA。您可以使用 HQL 特定的 elements 函数来执行此操作:

      select f from Family f WHERE :element in elements(f.elements)
      

      这是一个工作示例:

      import org.hibernate.annotations.CollectionOfElements;
      
      import javax.persistence.Column;
      import javax.persistence.Entity;
      import javax.persistence.EntityManager;
      import javax.persistence.EntityManagerFactory;
      import javax.persistence.EntityTransaction;
      import javax.persistence.Id;
      import javax.persistence.JoinColumn;
      import javax.persistence.JoinTable;
      import javax.persistence.Persistence;
      import javax.persistence.Query;
      import java.util.Arrays;
      import java.util.List;
      
          @Entity
          public class Family {
              @Id
              int id;
      
              String name;
      
              @CollectionOfElements(targetElement = java.lang.String.class)
              @JoinTable(name = "elements_family",
                      joinColumns = @JoinColumn(name = "idFamily")
              )
              @Column(name = "element", nullable = false)
              public List<String> elements;
      
              public static void main(String[] args) throws Exception {
                  EntityManagerFactory emf = 
                      Persistence.createEntityManagerFactory("mysql");
                  EntityManager em = emf.createEntityManager();
                  try {
      
                      Family f1 = new Family();
                      f1.id = 1;
                      f1.name = "Happy";
      
                      f1.elements = Arrays.asList("foo", "bar", "yyy", "zzz");
      
                      Family f2 = new Family();
                      f1.id = 2;
                      f2.name = "Disfunctional";
                      f2.elements = Arrays.asList("foo", "bar", "yyy", "xxx");
      
                      EntityTransaction tx = em.getTransaction();
                      tx.begin();
                      em.persist(f1);
                      em.persist(f2);
                      tx.commit();
                      Query query = em.createQuery(
                         "select f from Family f WHERE :element in elements(f.elements)");
                      query.setParameter("element", "bar");
                      List list = query.getResultList();
                      assert list.size() == 2;
      
                  } finally {
                      em.close();
                      emf.close();
                  }
              }
          }
      

      为了完整起见,persistence.xml

      <persistence-unit name="mysql" transaction-type="RESOURCE_LOCAL">
          <class>jpa.Family</class>
          <properties>
              <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
              <property name="hibernate.connection.driver_class" 
                                value="com.mysql.jdbc.Driver"/>
              <property name="hibernate.connection.url" value="jdbc:mysql://localhost/test"/>
              <property name="hibernate.connection.username" value="test"/>
              <property name="hibernate.connection.password" value="test"/>
              <property name="hibernate.show_sql" value="true"/>
              <property name="hibernate.format_sql" value="true"/>
              <property name="hibernate.max_fetch_depth" value="3"/>
              <property name="hibernate.bytecode.use_reflection_optimizer" value="true"/>
              <property name="hibernate.archive.autodetection" value="true"/>
              <property name="hibernate.cache.use_second_level_cache" value="true"/>
              <property name="hibernate.generate_statistics" value="true"/>
              <property name="hibernate.hbm2ddl.auto" value="create"/>
          </properties>
      </persistence-unit>
      

      【讨论】:

        【解决方案3】:

        JPQL 中的 MEMBER OF 子句:

        Query query = getEntityManager().createQuery("select f FROM Family f WHERE :element MEMBER OF f.element"); 
        query.setParameter("element", "yyy"); 
        return query.getResultList();
        

        【讨论】:

          猜你喜欢
          • 2021-03-24
          • 1970-01-01
          • 2018-04-02
          • 2015-08-31
          • 2014-12-04
          • 2012-11-01
          • 1970-01-01
          • 2014-02-02
          • 1970-01-01
          相关资源
          最近更新 更多