我正在使用Jersey
和Hibernate
创建Dropwizard
网络服务。
我想要求一种正确有效的方法来使用它们来连接和使用数据库。
我已经定义了数据库本身。我想问一下添加记录和查询数据库的正确方法。
关于查询数据库,现在我在注释@NamedQueries
中得到了一些简单的JPQL查询,这是表示数据库表的类的一部分。例如:
@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();
}
}
这也是向DB添加记录的正确有效方法吗?
答案 0 :(得分:1)
当我想查询时,我正在做这样的事情:
public Person getPersonByEmail(String email){
Person personByName = (Person) namedQuery("Person.findByEmail").setParameter("email", email).uniqueResult();
return personByName;
}
这是查询数据库的正确有效方法吗?我应该堆叠 像@NamedQueries注释那样的查询?
另一种方法是使用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 Persistence 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)
有助于创建一个好的设计,因为它显然更容易阅读和修改查询的位置,而不是实体的根。登记/>
没有间接性来读取它的全局性,也看看如何在查询中设置参数
相反,在类的根目录中修改JPQL
查询可能看起来很像并且具有非常接近的名称,这很容易出错。
JPQL
的唯一真正优势是在编译时,可能会检测到查询中的语法错误,因此会快速停止构建。
编辑:问题的第二部分
关于添加到数据库,我现在这样做:
NamedQuery
这也是向DB添加记录的正确有效方法吗?
几乎正确。您应该登录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();
}
}
以进行调试,如果回滚失败,您还应该记录并抛出异常。
catch HibernateException