当前位置: 首页 > 面试题库 >

Hibernate中不必要的查询-MySQL

金赤岩
2023-03-14
问题内容

我正在使用 spring / hibernate / mysql ,目前在 spring-hibernate.xml中 使用以下设置

我经常看到 “ select @@ session.tx_read_only” “ select @@
session.tx_isolation”
查询主要在选择实际数据的语句之后发送到数据库。

这些查询中的每一个都会增加20-25毫秒的时间,而在Oauth登录上,我会针对数据库运行70个查询。我该如何摆脱它们?

我尝试了statelessSessions,查询消失了,只能将查询数量减少到应用程序查询,但是我读到,使用statelessSessions不会提供任何一级缓存,并且也容易受到数据混叠的影响。

如何避免多次运行“ select @@ session.tx_read_only”和select @@
session.tx_isolation。(我使用通用Dao访问数据库,下面提供了摘录)我正在使用findById,findAll,getNamedQueryAndNamedParam方法…

spring-hibernate.xml

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="com.mysql.jdbc.Driver" />
    <property name="jdbcUrl" value="${JDBC_CON_STRING}" />
    <property name="user" value="${USER_NAME}" />
    <property name="password" value="${USER_PASSWORD}" />
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan" value="com.model" />
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.format_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">false</prop>
            <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
            <prop key="hibernate.cache.use_query_cache">true</prop>
            <prop key="hibernate.cache.use_second_level_cache">true</prop>
            <prop key="hibernate.cache.provider_configuration_file_resource_path">ehcach.xml</prop>
            <prop key="hibernate.auto_close_session">true</prop>
    </property>
    <property name="mappingResources">
        <list>
            <value>named-queries.xml</value>
            <value>native-named-queries.xml</value>
        </list>
            </property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
<property name="dataSource" ref="dataSource" />
</bean>

<tx:annotation-driven transaction-manager="transactionManager" />

<bean id="testClassDao" class="com.dao.GenericHibernateDao">
    <property name="clazz" value="com.model.TestClass" />
</bean>

GenericHibernateDao.java

@Repository
@Scope("prototype")
public class GenericHibernateDao<T, PK extends Serializable> implements GenericDao<T, PK> {

private Class<T> clazz;

@Autowired
private SessionFactory sessionFactory;

public void setClazz(final Class<T> clazzToSet) {
    this.clazz = clazzToSet;
}

protected Session getSession() {
    return sessionFactory.getCurrentSession();
}

protected Session getOpenSession() {
    return sessionFactory.openSession();
}

@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
public T findById(PK id) {
    Object obj = null;
    obj = getSession().get(clazz, id);
    //obj = getStatelessSession().get(clazz, id);
    return (T) obj;
}

@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
public List<T> findAll() {

    String queryString = "from " + clazz.getName();
    Query query = getSession().createQuery(queryString);
    query.setCacheable(true);
    List<T> list = query.list();
    return list;
}

@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
public List<T> getNamedQuery(String queryName) {
    Query query = getSession().getNamedQuery(queryName);
    //Query query = getStatelessSession().getNamedQuery(queryName);
    query.setCacheable(true);
    List<T> results = query.list();
    return results;
}

@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
public List<T> getNamedQueryAndNamedParam(String queryName, String paramName, Object value) {
    Query query = getSession().getNamedQuery(queryName).setString(paramName, value.toString());
    query.setCacheable(true);
    List<T> results = query.list();
    return results;
}
@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
public PK save(T persistenceObject) {
    Serializable save = getSession().save(persistenceObject);
    return (PK) save;
}

@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
public void saveOrUpdate(T persistenceObject) {
    getSession().saveOrUpdate(persistenceObject);
}

public void saveOrUpdateBulk(Collection<T> persistenceObject) {
    Session session = getOpenSession();
    Transaction tx = session.beginTransaction();
    int i = 0;
    for (Iterator<T> iterator = persistenceObject.iterator(); iterator.hasNext();) {
        i++;
        session.saveOrUpdate(iterator.next());
        if (i % 100 == 0) {
            session.flush();
            session.clear();
        }
    }
    tx.commit();
    session.close();
}

@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
public boolean delete(PK id) {
    Object findById = findById(id);
    if (findById != null) {
        getSession().delete(findById);
        return true;
    }
    return false;
}
}

问题答案:

AFAIK要删除这些多余的查询,请删除@Transactional注释的所有修饰符。将隔离级别限制为的代价READ_COMMITED是Hibernate需要执行额外的查询以确定数据库是否处于脏状态。对于90%的情况,这些修饰符是不必要的。Hibernate非常擅长确保您的数据干净,而无需尝试添加这些限制。

如果绝对需要确保隔离度为READ_COMMITTED,则您不能对多余的查询做任何事情。

StatelessSession出于您指出的原因,转移到公正来摆脱这些查询是一个坏主意。确实,使用a的唯一有效理由StatelessSession是对大批量的插入数据进行了插入,而您知道这些数据不会在插入过程中被读取。



 类似资料:
  • 问题内容: 我正在使用hibernate和c3p0 connectionpool插入,更新和删除许多分离的对象。问题在于,hibernate不会批处理语句,而是会 在每个session.persist / insert / update / delete(object)之间。分析sql- connection看起来像这样: select @@ session.tx_rad_only总是返回“ 0”

  • 我今天的问题是。我需要在我的脚本中转义PDO吗? 整个脚本可在中找到。https://github.com/joshuahiwat/crud/blob/master/control/query_connector.class.php 有人能解释一下为什么我现在需要逃跑,或者为什么不需要。 我很想收到你的来信,非常感谢!

  • 我有一个复合密钥的实体。订阅和源具有多对多的关系。 我正在使用Spring数据存储库来处理它。 当我尝试使用方法saveAll时,它会抛出 “com.mysql.jdbc.exceptions.jdbc4.mysqlsyntaxerrorexception:未知列'subscripti0_.subscription_id'” 同时尝试在保存后返回值。 Hibernate生成以下查询: 所以,现在我

  • 我在使用zkoss和hibernate时遇到了一个问题 我有两个模型一个是少年信息另一个是学校测量 在学校里,我建立了一种多人的关系 当我进入 SessionFactory SessionFactory=新配置()。configure()。buildSessionFactory(); 会话会话=会话工厂。openSession();一场beginTransaction();列表结果1=会话。cre

  • 问题内容: 这个简单的查询 给这个堆栈跟踪 如果我做 我没有收到错误,但我只需要recNo 有任何想法吗 ? 问题答案: 您忘记了选择: