douhong9210
douhong9210
2012-11-30 15:56

JPA和Hibernate Search的方法是什么?

已采纳

I have been searching around trying to find information about the approaches that JPA and Hibernate Search use towards querying data. There is a vast amount of data but most, if not all, contain very high level terminology. I am struggling to understand the differences between both of them. It would be great if someone can point me to something that explains both things in a more simple manner. I come from a Java (but never used databases with Java before) and PHP background (Used databases with PHP).

Cheers

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

2条回答

  • dongxiong1941 dongxiong1941 9年前

    JPA is a standard API to access relational databases. It's an ORM: object-relational mapper. It allows fetching/saving object graphs fom the database, instead of rows and columns.

    Hibernate is an implementation of the JPA API.

    Hibernate Search plugs into Hibernate in order to be able to execute full-text queries over the objects (or parts of the objects) that are persisted in the database. The goal is to be able to execute google-like queries, instead of (or in addition to) traditional SQL queries.

    Hibernate Search uses Lucene behind the scene.

    点赞 评论 复制链接分享
  • duanfu1873 duanfu1873 9年前

    Well, they're both basically fancy wrappers/abstractors on top of SQL. The abstraction goes on multiple levels:

    • first off, direct SQL queries are (almost) completely hidden away, and a higher level (but still similar to SQL in synthax) language is exposed by both frameworks. This is mainly so that your application will be independent from the various quirks of SQL as implemented by different data base vendors. Think JQuery DOM manipulation API over standard (and browser-specific) pure-Javascript. This language abstraction is called HQL (Hibernate Query Language) in Hibernate and JPQL (Java Persistence Query Language) in JPA. They are both very similar, and in fact I think JPQL has been heavily inspired by HQL. Here's a basic example:

    SQL query such as

    SELECT * FROM Persons
    

    can be expressed in JPQL as:

    SELECT p FROM Person p
    

    and in HQL:

    FROM Person p
    

    Obviously there's more to it than that, and due to the fact that the frameworks, as their global name implies, try to map relational data to objects, their high-level query languages work on objects. What's important I think, to understand from the get go before delving further in the details is the fact that whatever query code you write with either JPA or Hibernate, it will be translated to SQL specific to the current database and executed against it. And Hibernate (both it by itself and its JPA implementation) has a nice feature which can log all the generated SQL . Just add the "hibernate.show_sql" (and maybe also "hibernate.format_sql") config params to true in your Hibernate config. For example for a Hibernate-JPA project, you need to add them to your persistence unit declaration, in your persistence.xml file, something like this:

    <persistence>
    
        <persistence-unit name="some_name">
            <provider>org.hibernate.ejb.HibernatePersistence</provider>
            <properties>
                <!-...->
                <property name="hibernate.show_sql" value="true" />
                <property name="hibernate.format_sql" value="true" />
            </properties>
        </persistence-unit>
    </persistence>
    

    Try activating this feature and play around with either JPQL or HQL and see what actually happends at the SQL level. This may give you a better idea of how the higher level APIs work.

    • currently Hibernate as well as JPA(as of version 2) offer yet another abstraction API for querying your data, called Criteria API. The basic idea here is that it ditches the SQL-like syntax (and paradigm) completely in favor of a completely Object-Oriented query API. Here's a quick JPA example :

      CriteriaQuery cq = cb.createQuery(Person.class);

      Root<Person> fromPerson = cq.from(Person.class);
      CriteriaQuery<Person> selectFromPerson = cq.select(fromPerson);
      

    Yep, it looks weird but it has its uses (imagine trying to dynamically create a query based on some run time arguments which may or may not be set, etc)

    Again, both pure-Hibernate and Hibernate JPA have very similar implementations of this API. Ang also, the queries made this way translate down to SQL that you can log and study.

    As per your question regarding JPA and Hibernate and which is which, here's the story:

    First there was Hibernate. A stand alone 3rd party framework, which offered a way to map SQL data to Java classes and Objects. Then the Java EE guys thought this is a good idea, and made their own version of this, named JPA. Since these guys adhere to the philosophy of only making specs and allowing 3rd parties to make actual implementation of those specs, JPA all by itself is just a bunch of interfaces and a long document detailing how they should work (check it out here for JPA 2.0). So it happens then after all this was done, one of those potential 3rd parties who decided to implement the JPA specs was the Hibernate guys. And since JPA specs are very similar to the already existing (and fully implemented) Hibernate framework they decided to build it along side Hibernate. Thus in the Hibernate Framework you have both the original Hibernate API and implementation (which has nothing to do with JPA specs) and the JPA implementation. You can even use them both at the same times, though that's really not a good practice.

    Now, the Oracle Java guys, after finishing the specs, also made an implementation of those themselves. They tend to do this with most of their specs APIs. This implementation is called EclipseLink and you can check it out here . Theoretically, your JPA project should work exactly the same if you switch your Hibernate-JPA implementation libraries to EclipseLink-JPA implementation libraries. In practice there are small differences.

    点赞 评论 复制链接分享