Hibernate 对于 Web 应用程序来说更安全吗?

2024-03-30

我有疑问是否Hibernate对于 Web 应用程序(JSP、Servlet、Hibernate、MySQL)来说是安全的,它将获得“不同用户”“一次”的数千个访问。

我担心的原因如下。

想象一下,我有一个供学校学生使用的网络应用程序。他们有自己的个人资料,并会维护自己的学生课程、分数等。现在,肯定会有超过 1 个用户始终在线,并拥有自己的个人资料。这意味着如果用户A对其数学成绩进行了编辑,这将在用户中完成A的个人资料。在所有用户中永远不会被替换A, B和'C'的个人资料同时在线。

Servlets都是多线程来提供上述支持。它与纯 JDBC 一起工作得非常好。怎么样?Hibernate ?

我也上传了我的HibernateUtil供你参考。就我而言,我将其称为SessionFactoryBuilder

public class SessionFactoryBuilder
{
    private static SessionFactoryBuilder instance;
    private static SessionFactory sessionFactory;

    private SessionFactoryBuilder()
    {
        buildConfig();
        System.out.println("hehehehe");
    }

    private static void buildConfig()
    {
        Configuration configuration = new Configuration().configure();
            StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties());
            sessionFactory = configuration.buildSessionFactory(builder.build());
    }

    public static SessionFactoryBuilder getInstance()
    {
         if(instance == null)
         {
            instance = new SessionFactoryBuilder();

         }
      return instance;
    }

    public SessionFactory getSessionFactory()
    {
        return sessionFactory;
    }

}

1)在 Hibernate 中存在一个单个 SessionFactory 对象每个应用程序。
SessionFactory的内部状态是不可变的, 所以它是线程安全的。多个线程可以同时访问它以获取 Session 实例。

下面的代码描述了通过实用程序类获取 SessionFactory 实例的标准方法。

import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

/**
 * Hibernate Utility class with a method to get Session Factory object.
 */
public class HibernateUtil {
private static final SessionFactory sessionFactory;//Once created, its properties cannot be changed

static {
    try {
        // Create the SessionFactory from standard (hibernate.cfg.xml) config file.

        sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();

    } catch (Throwable ex) {

        // Log the exception.
        System.err.println("Initial SessionFactory creation failed." + ex);
        throw new ExceptionInInitializerError(ex);
    }
}

public static SessionFactory getSessionFactory() {

    return sessionFactory;

}
}

2)休眠Session是java应用层和hibernate之间的接口。这是用于执行数据库操作的核心接口。 会话的生命周期受逻辑事务的开始和结束的限制。

Hibernate Session 对象不是线程安全的,每个线程都应该获取自己的会话实例,并在工作完成后关闭它。

这并不意味着实现者是线程安全的。相反,每个线程/事务应该从 SessionFactory 获取自己的实例。

A typical transaction should use the following idiom:

 Session sess = factory.openSession();
 Transaction tx;
 try {
     tx = sess.beginTransaction();
     //do some work
     ...
     tx.commit();
     }
 catch (Exception e) {
    if (tx!=null) tx.rollback();
    throw e;
 }
 finally {
      sess.close();
 }

如果会话抛出异常,则必须回滚事务并丢弃会话。异常发生后Session的内部状态可能与数据库不一致。

2.1)下面列出了两种广泛用于获取 Hibernate Session 对象的方法。

  1. 开放会话//用这个来多线程环境
  2. 获取当前会话//用这个来单线程环境

Hibernate会话工厂getCurrentSession() 方法返回绑定到上下文的会话。但要使其工作,我们需要在 hibernate 配置文件中对其进行配置。由于这个会话对象属于hibernate上下文,所以我们不需要关闭它。一旦 SessionFactory 关闭,该会话对象也将关闭。

<property name="hibernate.current_session_context_class">thread</property>

Hibernate会话工厂打开会话()方法总是打开一个新会话。我们应该close一旦我们完成了所有的数据库操作,这个会话对象。
我们应该在多线程环境中为每个请求打开一个新会话。


2.2) 还有一种使用 openStatelessSession() 创建 Hibernate Session 对象的方法,它为您提供了一个 hibernate Stateless Session。

它是一个面向命令的 API,用于对数据库执行批量操作。
无状态会话不实现一级缓存,也不与任何二级缓存交互,也不实现事务性后写或自动脏检查,也不将操作级联到关联的实例。无状态会话会忽略集合。通过无状态会话执行的操作绕过 Hibernate 的事件模型和拦截器。由于缺乏一级缓存,无状态会话容易受到数据别名效应的影响。

对于某些类型的事务,无状态会话的执行速度可能比有状态会话稍快。(例如:批处理/批量更新)

StatelessSession session = sessionFactory.openStatelessSession();
Transaction tx = session.beginTransaction();

ScrollableResults customers = session.getNamedQuery("GetCustomers")
.scroll(ScrollMode.FORWARD_ONLY);
while ( customers.next() ) {
Customer customer = (Customer) customers.get(0);
customer.updateStuff(...);
session.update(customer);
}

tx.commit();
session.close();

在此代码示例中,查询返回的 Customer 实例立即分离。它们从不与任何持久性上下文相关联。

StatelessSession接口定义的insert()、update()和delete()操作被认为是直接的数据库行级操作。它们分别导致立即执行 SQL INSERT、UPDATE 或 DELETE。

无状态会话不是线程安全的,使用无状态会话时可能发生的异常是“org.hibernate.AssertionFailure:可能对会话进行非线程安全访问”


3)您的学生记录项目是一个多线程应用程序,因此在使用 hibernate 时需要小心。尝试通过打开新会话、使用事务、提交和回滚以及在需要时关闭会话来使用最佳编程实践。

我个人在我们的项目中使用了 hibernate,我们有数百万用户通过 hibernate 作为后端 API 访问数据库。我们在多线程环境中从未遇到过此类问题,因为我们使用了 hibernate 的最佳编程实践。即使数据库发生任何异常,整个事务也会回滚。

因此,与 JDBC 相比,可以以更高的成功率实现数据库事务的 ACID 属性(原子性、一致性、隔离性、持久性)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Hibernate 对于 Web 应用程序来说更安全吗? 的相关文章

  • 如何获取之前的URL?

    我需要调用我的网络应用程序的 URL 例如 如果有一个从 stackoverflow com 到我的网站 foo com 的链接 我需要 Web 应用程序 托管 bean 中的 stackoverflow 链接 感谢所有帮助 谢谢 并不总是
  • jQuery AJAX 调用 Java 方法

    使用 jQuery AJAX 我们可以调用特定的 JAVA 方法 例如从 Action 类 该 Java 方法返回的数据将用于填充一些 HTML 代码 请告诉我是否可以使用 jQuery 轻松完成此操作 就像在 DWR 中一样 此外 对于
  • 没有 Spring 的自定义 Prometheus 指标

    我需要为 Web 应用程序提供自定义指标 问题是我不能使用 Spring 但我必须使用 jax rs 端点 要求非常简单 想象一下 您有一个包含键值对的映射 其中键是指标名称 值是一个简单的整数 它是一个计数器 代码会是这样的 public
  • 无法创建请求的服务[org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]-MySQL

    我是 Hibernate 的新手 我目前正在使用 Spring boot 框架并尝试通过 hibernate 创建数据库表 我知道以前也问过同样的问题 但我似乎无法根据我的环境找出如何修复错误 休眠配置文件
  • 帮助将图像从 Servlet 获取到 JSP 页面 [重复]

    这个问题在这里已经有答案了 我目前必须生成一个显示字符串文本的图像 我需要在 Servlet 上制作此图像 然后以某种方式将图像传递到 JSP 页面 以便它可以显示它 我试图避免保存图像 而是以某种方式将图像流式传输到 JSP 自从我开始寻
  • jdbc mysql loginTimeout 不起作用

    有人可以解释一下为什么下面的程序在 3 秒后超时 因为我将其设置为在 3 秒后超时 12秒 我特意关闭了mysql服务器来测试mysql服务器无法访问的这种场景 import java sql Connection import java
  • Hibernate 的 PersistentSet 不使用 hashCode/equals 的自定义实现

    所以我有一本实体书 public class Book private String id private String name private String description private Image coverImage pr
  • mysql排序和排名语句

    我需要一些 mysql 语句的帮助 我的表 1 有 7 列 表 2 有 8 列 额外的列名为排名 我的语句应该是这样的 从表 1 中选择全部 然后按 用户数 排序 将其插入表 2 中并排名开始 1 2 3 等 table 1 usernam
  • Spring Boot Data JPA 从存储过程接收多个输出参数

    我尝试通过 Spring Boot Data JPA v2 2 6 调用具有多个输出参数的存储过程 但收到错误 DEBUG http nio 8080 exec 1 org hibernate engine jdbc spi SqlStat
  • Java ResultSet 如何检查是否有结果

    结果集 http java sun com j2se 1 4 2 docs api java sql ResultSet html没有 hasNext 方法 我想检查 resultSet 是否有任何值 这是正确的方法吗 if resultS
  • 快速将列的副本添加到 MySQL 表

    我需要一种快速的方法来复制表中的 DATETIME 列并为其指定一个新名称 我的表中有一个名为 myDate 的列 名为 myResults 我需要一个查询来在名为 newDate 的表中创建一个新列 该列的数据与 myDate 列完全相同
  • tomcat 中受密码保护的应用程序

    我正在使用 JSP Servlet 开发一个Web应用程序 并且我使用了Tomcat 7 0 33 as a web container 所以我的要求是tomcat中的每个应用程序都会password像受保护的manager applica
  • 如何在谷歌地图android上显示多个标记

    我想在谷歌地图android上显示带有多个标记的位置 问题是当我运行我的应用程序时 它只显示一个位置 标记 这是我的代码 public class koordinatTask extends AsyncTask
  • SQL 最近日期

    我需要在 php 中获取诸如 2010 04 27 之类的日期作为字符串 并在表中找到最近的 5 个日期 表中的日期保存为日期类型 您可以使用DATEDIFF http dev mysql com doc refman 5 1 en dat
  • 关键字“table”附近的语法不正确,无法提取结果集

    我使用 SQL Server 创建了一个项目 其中包含以下文件 UserDAO java public class UserDAO private static SessionFactory sessionFactory static se
  • java.io.Serialized 在 C/C++ 中的等价物是什么?

    C C 的等价物是什么java io Serialized https docs oracle com javase 7 docs api java io Serializable html 有对序列化库的引用 用 C 序列化数据结构 ht
  • Eclipse 启动时崩溃;退出代码=13

    I am trying to work with Eclipse Helios on my x64 machine Im pretty sure now that this problem could occur with any ecli
  • Android 中的处理程序与异步调用

    目前我正在使用处理程序来调用 Web 服务方法以使其在后台运行 问题是它需要更多的时间来给出响应 在性能方面似乎更昂贵 现在我计划使用异步调用 哪一个是最好的 Android 中的处理程序和异步调用有什么区别 请帮我想出一个最好的解决方案
  • 如何使用mockito模拟构建器

    我有一个建造者 class Builder private String name private String address public Builder setName String name this name name retur
  • 双枢轴快速排序和快速排序有什么区别?

    我以前从未见过双枢轴快速排序 是快速排序的升级版吗 双枢轴快速排序和快速排序有什么区别 我在 Java 文档中找到了这个 排序算法是双枢轴快速排序 作者 弗拉基米尔 雅罗斯拉夫斯基 乔恩 本特利和约书亚 布洛赫 这个算法 在许多数据集上提供

随机推荐