最近我正在研究改进代码的一些可能性,并对其进行了一些更改。我安装了hibernate配置以使用二级缓存,但是这种改进的结果还不够好。我期待我的数据库查询很快就会出现。当我在实现之后做了一些研究之后,时间比我在代码中修改之前的时间要大。即使我启用了缓存查询,我的结果也不会改变。我启用查询缓存后看到的是更糟糕的时间结果。我能看到的另一件事是,如果我的表与另一个表有某种关系,搜索时间会增加很多。
的HibernateUtil
free()
员工
package com.journaldev.hibernate.util;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
public class HibernateUtil {
private static SessionFactory sessionFactory;
private static SessionFactory buildSessionFactory() {
try {
// Create the SessionFactory from hibernate.cfg.xml
Configuration configuration = new Configuration();
configuration.configure("hibernate.cfg.xml");
System.out.println("Hibernate Configuration loaded");
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
System.out.println("Hibernate serviceRegistry created");
SessionFactory sessionFactoryLocal = configuration.buildSessionFactory(serviceRegistry);
return sessionFactoryLocal;
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
ex.printStackTrace();
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
if (sessionFactory == null) {
sessionFactory = buildSessionFactory();
}
return sessionFactory;
}}
ADRESS
package com.journaldev.hibernate.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
@Entity
@Table(name = "EMPLOYEE")
@Cache(usage=CacheConcurrencyStrategy.READ_ONLY, region="employee")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "emp_id")
private long id;
@Column(name = "emp_name")
private String name;
@Column(name = "emp_salary")
private double salary;
public Employee(String name) {
this.name = name;
}
public Employee() {
}}
员工关系地址
package com.journaldev.hibernate.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
@Entity
@Table(name = "ADDRESS")
@Cache(usage=CacheConcurrencyStrategy.READ_ONLY, region="employee")
public class Address {
@Id
@GeneratedValue
private long id;
@Column(name = "address_line1")
private String addressLine1;
@Column(name = "zipcode")
private String zipcode;
@Column(name = "city")
private String city;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getAddressLine1() {
return addressLine1;
}
public void setAddressLine1(String addressLine1) {
this.addressLine1 = addressLine1;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
Class teste
package com.journaldev.hibernate.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.Cascade;
@Entity
@Table(name = "EMPLOYEE")
@Cache(usage=CacheConcurrencyStrategy.READ_ONLY, region="employee")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "emp_id")
private long id;
@Column(name = "emp_name")
private String name;
@Column(name = "emp_salary")
private double salary;
@OneToOne(mappedBy = "employee")
@Cascade(value = org.hibernate.annotations.CascadeType.ALL)
private Address address;
public Employee(String name) {
this.name = name;
}
public Employee() {
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
Hibernate.cfg
package com.journaldev.hibernate.main;
import org.hibernate.Session;
import com.journaldev.hibernate.model.Employee;
import com.journaldev.hibernate.util.HibernateUtil;
import java.util.Date;
public class HibernateEHCacheMain {
public static void main(String[] args) {
//insert10000();
// System.out.println("Temp Dir:" + System.getProperty("java.io.tmpdir"));
long init1 = new Date().getTime();
list10000WithCache();
long end1 = new Date().getTime();
long result1 = end1 - init1;
long init2 = new Date().getTime();
list10000WithCache();
long end2 = new Date().getTime();
long result2 = end2 - init2;
long init3 = new Date().getTime();
list10000WithCache();
//list10000WithoutCache();
long end3 = new Date().getTime();
long result3 = end3 - init3;
System.err.println("Result 1 : " + result1 + "\nResult 2 :" + result2 + "\nResult 3 :" + result3);
System.exit(1);
}
private static void insert10000() {
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
for (int i = 0; i < 10000; i++) {
session.save(new Employee(i + ""));
if (i % 20 == 0) {
session.flush();
session.clear();
}
}
session.getTransaction().commit();
session.close();
}
private static void list10000WithoutCache() {
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
session.createQuery("from Employee").list();
session.getTransaction().commit();
session.close();
}
private static void list10000WithCache() {
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
session.createQuery("from Employee").setCacheable(true).list();
session.getTransaction().commit();
session.close();
}
}
myehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration SYSTEM "classpath://org/hibernate/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">pass</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost/mydb</property>
<property name="hibernate.connection.username">user</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.default_batch_fetch_size">20</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
<!-- For singleton factory -->
<!-- <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</property>
-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- enable second level cache and query cache -->
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.use_query_cache">true</property>
<property name="net.sf.ehcache.configurationResourceName">/myehcache.xml</property>
<mapping class="com.journaldev.hibernate.model.Employee" />
<mapping class="com.journaldev.hibernate.model.Address" />
</session-factory>
</hibernate-configuration>
答案 0 :(得分:0)
查询缓存的工作原理是什么?
查询缓存用于缓存查询结果。打开查询缓存时,将根据组合查询和参数存储查询结果。每次触发查询时,缓存管理器都会检查参数和查询的组合。如果在缓存中找到结果,则返回它们,否则启动数据库事务。
为什么不应使用查询缓存?
正如您所看到的,如果查询具有多个参数,则缓存查询不是一个好主意,因为单个参数可以采用多个值。对于这些组合中的每一种,结果存储在存储器中。这可能导致大量内存使用。
启用查询二级缓存存在很多陷阱。请完成此link。
我在配置中没有看到任何问题。您需要在sessionfactory上启用统计信息以查找二级缓存是否正常工作。
统计数据统计= sessionFactory.getStatistics(); statistics.setStatisticsEnabled(真);
您可以查看以下值
statistics.getEntityFetchCount()
statistics.getSecondLevelCacheHitCount()
statistics.getSecondLevelCachePutCount()
statistics.getSecondLevelCacheMissCount()
使用此post获取有关使用统计信息进行二级缓存的准确说明。