从hibernate db获取数据需要很长时间

时间:2016-11-12 11:26:39

标签: java hibernate rest jpa

如何提升表现?当从stackoverflow或gituhb rest api请求数据时,获取响应需要几毫秒,但对于我的小应用程序,每个请求需要3-5秒。

示例:

@XmlRootElement
@Entity
@Table(name = "customers")
public class Customer extends Model {

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;

@Column(name = "name")
private String name;

@Column(name = "email")
private String email;

@ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.ALL})
@JoinColumn(name = "address_id")
private Address address;

@OneToMany(fetch = FetchType.LAZY, mappedBy = "customer")
private List<Booking> bookings;

/**
 * Constructor.
 *
 */
public Customer() {}

/**
 * Constructor.
 *
 * @param email Email of the customer.
 * @param address Address of the customer.
 * @param name Name of the customer.
 */
public Customer(String email, Address address, String name) {
    this.email = email;
    this.address = address;
    this.name = name;
}

/**
 * Set the id of the customer.
 *
 */
public void setId(int id) {
    this. id = id;
}

/**
 * Get the id of the customer.
 *
 * @return Id of the customer.
 */
public int getId() {
    return id;
}

/**
 * Get the name of the customer.
 *
 * @return Name of the customer.
 */
public String getName() {
    return name;
}

/**
 * Set the name of the customer.
 *
 * @param name New name of the customer.
 */
public void setName(String name) {
    this.name = name;
}

/**
 * Get the email of the customer
 *
 * @return Email of the customer.
 */
public String getEmail() {
    return email;
}

/**
 * Set the email of the customer
 *
 * @param email New email of the customer.
 */
public void setEmail(String email) {
    this.email = email;
}

/**
 * Get the address of the customer
 *
 * @return Address of the customer.
 */
public Address getAddress() {
    return address;
}

/**
 * Set the address of the customer
 *
 * @param address New address of the customer.
 */
public void setAddress(Address address) {
    this.address = address;
}

/**
 * Get the bookings of the customer.
 *
 * @return List of bookings.
 */
@XmlTransient
public List<Booking> getBookings() {
    return bookings;
}

/**
 * Set the bookings of the customer.
 *
 * @param bookings List of bookings.
 */
public void setBookings(List<Booking> bookings) {
    this.bookings = bookings;
}

/**
 * Get all customers from the database.
 *
 * @return List of customers.
 */
public static List<Customer> all() {
    return (List<Customer>) Database.all(Customer.class);
}

/**
 * Find a customer by the id.
 *
 * @param id Id of the customer.
 * @return The customer object. Returns null if no customers were found.
 */
public static Customer find(int id) {
    return (Customer) Database.find(Customer.class, id);
}

/**
 * Check if a given customer id already exists.
 *
 * @param id Id of the customer.
 * @return Boolean.
 */
public static boolean exists(int id) {
    return Database.exists(Customer.class, id);
}

/**
 * Find customers by a specific column value.
 *
 * @param column Column of the database table.
 * @param value Value of the column.
 * @return List of customers.
 */
public static List<Customer> where(String column, String value) {
    return (List<Customer>) Database.where(Customer.class, column, value);
}

}

数据库类:

public class Database {

/**
 * Get all objects of a model from the database.
 *
 * @param model Class type of the model.
 * @return List of all model objects.
 */
public static List<? extends Model> all(Class<? extends Model> model) {
    EntityManager entityManager = HibernateUtil.getEntityManagerFactory().createEntityManager();
    List<Model> list = (List<Model>) entityManager.createQuery("from " + model.getName(), model).getResultList();
    entityManager.close();
    return list;
}

/**
 * Find a model object by the id.
 *
 * @param model Class type of the model.
 * @param id Id of the model object.
 * @return The model object. Returns null if no objects were found.
 */
public static Model find(Class<? extends Model> model, int id) {
    EntityManager entityManager = HibernateUtil.getEntityManagerFactory().createEntityManager();
    Model m = entityManager.find(model, id);
    entityManager.close();
    return m;
}

/**
 * Check if a given model object id already exists.
 *
 * @param model Class type of the model.
 * @param id Id of the model object.
 * @return Boolean.
 */
public static boolean exists(Class<? extends Model> model, int id) {
    return Database.find(model, id) != null;
}

/**
 * Find model objects by a specific column value.
 *
 * @param model Class type of the model.
 * @param column Column of the database table.
 * @param value Value of the column.
 * @return List of model objects.
 */
public static List<? extends Model> where(Class<? extends Model> model, String column, String value) {
    EntityManager entityManager = HibernateUtil.getEntityManagerFactory().createEntityManager();
    Query query = entityManager.createQuery("from " + model.getName() + " where " + column + "=:value");
    return (List<? extends Model>) query.setParameter("value", value).getResultList();
}
}

HibernateUtil类:

public class HibernateUtil {

private static EntityManagerFactory entityManagerFactory;

static {

    entityManagerFactory = Persistence.createEntityManagerFactory("com.travelagency.jpa");

}

/**
 * Get the EntityManager Factory object.
 *
 * @return EntityManagerFactory object.
 */
public static EntityManagerFactory getEntityManagerFactory() {
    return entityManagerFactory;
}
}

谢谢

2 个答案:

答案 0 :(得分:1)

你的主要问题是你使用Hibernate就好像它是ActiveRecord框架一样,这是错误的。但作为一个快速解决方案,您不需要每次都重新创建EntityManager。这就是你需要这么久的事情。只创建一次,不要关闭它。

答案 1 :(得分:1)

从你的代码我可以看到你没有对你所做的查询应用任何分页。这基本上意味着您将整个表加载到内存中。我不确定你的表有多大,但分页可能是一个解决方案。

int offset = 0;
int limit = 10;

Query query = entityManager.createQuery("from " + model.getName() + " where " + column + "=:value");
query.setFirstResult(offset);
query.setMaxResults(limit);