Hibernate jpql查询正确用法
Hibernate jpql query correct usage
我正在使用 Hibernate
和 Dropwizard
创建一个 Jersey
网络服务。
我想寻求一种正确有效的方法来使用它们来连接和使用数据库。
我已经定义了数据库本身。我想问一下正确的添加记录和查询数据库的方法
关于查询数据库,现在我在注释 @NamedQueries
中得到了一些简单的 JPQL 查询,它是代表数据库 table 的 class 的一部分。例如:
@XmlRootElement
@Entity(name = "Persons")
@Table(name = "Persons")
@NamedQueries(
{
@NamedQuery(name = "Person.findAll", query = "select p from Persons p"),
@NamedQuery(name = "Person.findByEmail", query = "select p from Persons p " + "where p.personEmail like :email")
})
public class Person implements Serializable
{ ... }
当我想查询时,我正在做这样的事情:
public Person getPersonByEmail(String email)
{
Person personByName = (Person) namedQuery("Person.findByEmail").setParameter("email", email).uniqueResult();
return personByName;
}
这是查询数据库的正确有效方法吗?我应该在 @NamedQueries
注释中堆叠这样的查询吗?
关于数据库的添加,我目前是这样处理的:
public void insertPersonToDB()
{
Session session = sessionFactory.openSession();
Transaction tx = null;
try
{
tx = session.beginTransaction();
Person pers = new Person("param1","param2");
short personID = (short) session.save(pers);
tx.commit();
}
catch (HibernateException e)
{
if (tx != null) tx.rollback();
e.printStackTrace();
}
finally
{
session.close();
}
}
这也是向数据库添加记录的正确有效方法吗?
When I want to query I am doing something like this:
public Person getPersonByEmail(String email){
Person personByName = (Person) namedQuery("Person.findByEmail").setParameter("email", email).uniqueResult();
return personByName;
}
Is this a correct and effective way of querying the DB? should I stack
queries like that in the @NamedQueries annotation?
另一种方法是使用 createQuery(jpqlQuery)
:
public Person getPersonByEmail(String email){
Person personByName = (Person) em.createQuery(
"select p from Persons p where p.personEmail like :email").
setParameter("email", email).getSingleResult();
return personByName;
}
我们有时会调用 createQuery()
动态查询创建的查询,因为未编译。
您也可以使用 Criteria
(用于创建查询的完整对象方式),但它编写起来更复杂,因此它对于 "true" 动态查询非常有用,其中查询的某些子句在运行时添加(添加例如条件或连接)。
通常,如果您的请求不需要以动态方式创建(在运行时添加 SQL 子句),通常建议您使用 @NameQuery
而不是 createQuery(java.lang.String jpqlString)
因为被认为性能更高。就个人而言,我认为这是一个虚假的好建议。
比如Pro EJB 3:Java持久化API,你说Named queries are a way of organising your static queries in a manner that is more readable, maintainable as well as performant.
对于性能,它是理论上的。
指的是从HQL翻译成SQL。
使用 NamedQuery
,您确定它执行了一次。
但是对于 createQuery(java.lang.String jpqlString)
,如果你做好这些事情,有效性能是相同或几乎相同的。
首先,将 HQL 查询转换为 SQL 如果将其与将查询传输到数据库、执行查询并检索结果(sql 映射到对象的成本进行比较,则几乎没有任何意义映射)
其次,大多数查询引擎(例如 Hibernate)将缓存翻译后的 SQL,但如果您按不应该的方式构建查询:用于设置查询参数的字符串连接。
剩下的,createQuery(java.lang.String jpqlString)
有助于创建良好的设计,因为从调用它的地方读取和修改查询显然比从实体的根目录更容易。
没有间接阅读它的全局性,也没有看到如何在查询中设置参数。
相反,在 class 的根目录下修改许多其他 JPQL
查询中的一个 JPQL
查询很容易出错。[=30] =]
NamedQuery
的唯一真正优势是在编译时,可以检测到查询中的语法错误,从而快速停止构建。
编辑:问题的第二部分
关于添加到数据库中,我现在是这样做的:
public void insertPersonToDB()
{
Session session = sessionFactory.openSession();
Transaction tx = null;
try
{
tx = session.beginTransaction();
Person pers = new Person("param1","param2");
short personID = (short) session.save(pers);
tx.commit();
}
catch (HibernateException e)
{
if (tx != null) tx.rollback();
e.printStackTrace();
}
finally
{
session.close();
}
}
Is this also a correct and effective way of adding records to the DB?
几乎正确。您应该登录 catch HibernateException
进行调试,如果回滚失败,您还应该登录并抛出异常。
public void insertPersonToDB()
{
Session session = sessionFactory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Person pers = new Person("param1","param2");
short personID = (short) session.save(pers);
tx.commit();
}
catch (HibernateException e){
try {
if (tx != null) {
tx.rollback();
logger.error(e);
}
} catch(Exception e2) {
logger.error(e2);
throw new RunTimeException("rollback failed", e2);
}
}
}
finally{
session.close();
}
}
我正在使用 Hibernate
和 Dropwizard
创建一个 Jersey
网络服务。
我想寻求一种正确有效的方法来使用它们来连接和使用数据库。
我已经定义了数据库本身。我想问一下正确的添加记录和查询数据库的方法
关于查询数据库,现在我在注释 @NamedQueries
中得到了一些简单的 JPQL 查询,它是代表数据库 table 的 class 的一部分。例如:
@XmlRootElement
@Entity(name = "Persons")
@Table(name = "Persons")
@NamedQueries(
{
@NamedQuery(name = "Person.findAll", query = "select p from Persons p"),
@NamedQuery(name = "Person.findByEmail", query = "select p from Persons p " + "where p.personEmail like :email")
})
public class Person implements Serializable
{ ... }
当我想查询时,我正在做这样的事情:
public Person getPersonByEmail(String email)
{
Person personByName = (Person) namedQuery("Person.findByEmail").setParameter("email", email).uniqueResult();
return personByName;
}
这是查询数据库的正确有效方法吗?我应该在 @NamedQueries
注释中堆叠这样的查询吗?
关于数据库的添加,我目前是这样处理的:
public void insertPersonToDB()
{
Session session = sessionFactory.openSession();
Transaction tx = null;
try
{
tx = session.beginTransaction();
Person pers = new Person("param1","param2");
short personID = (short) session.save(pers);
tx.commit();
}
catch (HibernateException e)
{
if (tx != null) tx.rollback();
e.printStackTrace();
}
finally
{
session.close();
}
}
这也是向数据库添加记录的正确有效方法吗?
When I want to query I am doing something like this:
public Person getPersonByEmail(String email){
Person personByName = (Person) namedQuery("Person.findByEmail").setParameter("email", email).uniqueResult();
return personByName;
}
Is this a correct and effective way of querying the DB? should I stack queries like that in the @NamedQueries annotation?
另一种方法是使用 createQuery(jpqlQuery)
:
public Person getPersonByEmail(String email){
Person personByName = (Person) em.createQuery(
"select p from Persons p where p.personEmail like :email").
setParameter("email", email).getSingleResult();
return personByName;
}
我们有时会调用 createQuery()
动态查询创建的查询,因为未编译。
您也可以使用 Criteria
(用于创建查询的完整对象方式),但它编写起来更复杂,因此它对于 "true" 动态查询非常有用,其中查询的某些子句在运行时添加(添加例如条件或连接)。
通常,如果您的请求不需要以动态方式创建(在运行时添加 SQL 子句),通常建议您使用 @NameQuery
而不是 createQuery(java.lang.String jpqlString)
因为被认为性能更高。就个人而言,我认为这是一个虚假的好建议。
比如Pro EJB 3:Java持久化API,你说Named queries are a way of organising your static queries in a manner that is more readable, maintainable as well as performant.
对于性能,它是理论上的。
指的是从HQL翻译成SQL。
使用 NamedQuery
,您确定它执行了一次。
但是对于 createQuery(java.lang.String jpqlString)
,如果你做好这些事情,有效性能是相同或几乎相同的。
首先,将 HQL 查询转换为 SQL 如果将其与将查询传输到数据库、执行查询并检索结果(sql 映射到对象的成本进行比较,则几乎没有任何意义映射)
其次,大多数查询引擎(例如 Hibernate)将缓存翻译后的 SQL,但如果您按不应该的方式构建查询:用于设置查询参数的字符串连接。
剩下的,createQuery(java.lang.String jpqlString)
有助于创建良好的设计,因为从调用它的地方读取和修改查询显然比从实体的根目录更容易。
没有间接阅读它的全局性,也没有看到如何在查询中设置参数。
相反,在 class 的根目录下修改许多其他 JPQL
查询中的一个 JPQL
查询很容易出错。[=30] =]
NamedQuery
的唯一真正优势是在编译时,可以检测到查询中的语法错误,从而快速停止构建。
编辑:问题的第二部分
关于添加到数据库中,我现在是这样做的:
public void insertPersonToDB()
{
Session session = sessionFactory.openSession();
Transaction tx = null;
try
{
tx = session.beginTransaction();
Person pers = new Person("param1","param2");
short personID = (short) session.save(pers);
tx.commit();
}
catch (HibernateException e)
{
if (tx != null) tx.rollback();
e.printStackTrace();
}
finally
{
session.close();
}
}
Is this also a correct and effective way of adding records to the DB?
几乎正确。您应该登录 catch HibernateException
进行调试,如果回滚失败,您还应该登录并抛出异常。
public void insertPersonToDB()
{
Session session = sessionFactory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Person pers = new Person("param1","param2");
short personID = (short) session.save(pers);
tx.commit();
}
catch (HibernateException e){
try {
if (tx != null) {
tx.rollback();
logger.error(e);
}
} catch(Exception e2) {
logger.error(e2);
throw new RunTimeException("rollback failed", e2);
}
}
}
finally{
session.close();
}
}