hibernate jpa

你好!你好吗? 今天我们将讨论不建议使用JPA / Hibernate的情况。 在JPA领域之外,我们还有哪些选择?

我们将谈论的是:

  • JPA /Hibernate问题
  • 解决一些JPA /Hibernate问题的方法
  • 选择此处描述的框架的标准
  • Spring JDBC模板
  • MyBatis
  • 索莫拉
  • sql2o
  • 看看:jOOQ和Avaje
  • 原始的JDBC方法值得吗?
  • 如何选择正确的框架?
  • 最后的想法

我使用本文中提到的框架在github中创建了4个CRUD,您将在每个页面的开头找到URL。

我并不是认为JPA一文不值的激进主义者,但我确实相信我们需要针对每种情况选择正确的框架。 如果您不知道我写了一本JPA书(仅葡萄牙语),并且我认为JPA是解决所有问题的灵丹妙药。

JPA /Hibernate问题

有时候,JPA弊大于利。 在下面,您将看到JPA /Hibernate问题,在下一页中,您将看到一些针对这些问题的解决方案:

  • 复合密钥:我认为,这是JPA开发人员最大的麻烦。 当我们映射一个组合键时,当我们需要持久化或在数据库中找到一个对象时,这给项目增加了巨大的复杂性。 当您使用组合键时,可能会发生一些问题,其中一些问题可能是实现错误。
  • 旧版数据库:当需要调用StoredProcedures或Functions时,数据库中包含许多业务规则的项目可能会成为问题。
  • 工件大小:如果您使用的是Hibernate实现,那么工件大小会增加很多。 Hibernate使用了大量依赖项,这些依赖项会增加生成的jar / war / ear的大小。 如果开发人员需要在Internet带宽较低(或上传速度较慢)的多个远程服务器中进行部署,则工件大小可能会成为问题。 想象一个项目,在每个新版本中,有必要在全国范围内更新10个客户服务器。 上载速度慢,文件损坏和Internet丢失等问题可能会导致开发人员/运营团队浪费更多时间。
  • 生成SQL:JPA的优势之一是数据库的可移植性,但是要使用此可移植性的优势,您需要使用JPQL / HQL 语言 。 当生成的查询性能较差并且不使用为优化查询而创建的表索引时,此优点可能成为不利条件。
  • 复杂查询:这些项目使用数据库资源(例如SUM,MAX,MIN,COUNT,HAVING等)进行多个具有高度复杂性的查询。如果将这些资源结合使用,JPA性能可能会下降并且不使用表索引,否则您将无法使用可以解决此问题的特定数据库资源。
  • 框架复杂性:使用JPA创建CRUD非常简单,但是当我们开始使用实体关系,继承,缓存,PersistenceUnit操作,具有多个实体的PersistenceContext等时,就会出现问题。没有开发人员的开发团队具有良好的JPA经验使用JPA“ 规则 ”将浪费很多时间。
  • 处理缓慢且占用大量RAM内存:在某些情况下,JPA会在报表处理中失去性能,插入很多实体或长时间打开的事务存在问题。

阅读完以上所有问题后,您可能会想:“ JPA在做任何事情方面都擅长吗?”。 JPA具有很多优点,在此不再赘述,因为这不是后期主题,JPA是一种在很多情况下都适用的工具。 JPA的一些优点是:数据库可移植性,节省大量开发时间,使创建查询更容易,缓存优化,庞大的社区支持等。

在下一页中,我们将为上述问题提供一些解决方案,这些解决方案可以帮助您避免庞大的持久性框架重构。 我们将看到一些技巧来解决或解决此处描述的问题。

解决一些JPA /Hibernate问题的方法

如果要考虑删除项目的JPA,则需要小心。

我不是那种认为应该在找到解决方案之前删除整个框架的开发人员。 有时候,最好选择一种不那么介入的方法。

复合键

不幸的是,没有很好的解决方案。 如果可能,请避免使用业务规则不需要的带有复合键的表。 我已经看到开发人员在可以应用简单键的情况下使用复合键,而不必要地将复合键复杂性添加到了项目中。

旧版数据库

最新的JPA版本(2.1)支持StoredProcedures和Functions,有了此新资源,将更易于与数据库进行通信。 如果无法升级JPA版本,我认为JPA不是您的最佳解决方案。

您可以使用某些供应商资源,例如Hibernate,但是您将失去数据库和实现的可移植性。

神器尺寸

解决此问题的一个简单方法是更改​​JPA实现。 除了使用Hibernate实现之外,还可以使用Eclipsellink,OpenJPA或Batoo。 如果项目使用的是Hibernate批注/资源,则可能会出现问题。 实现更改将需要一些代码重构。

生成SQL和复杂查询

解决这些问题的方法是使用名为NativeQuery的资源。 使用此资源,您可以拥有简化的查询或优化SQL,但是您将牺牲数据库的可移植性。

您可以将查询放在一个文件中,例如SEARCH_STUDENTS_ORACLE或SEARCH_STUDENTS_MYSQL,在生产环境中,可以访问正确的文件。 这种方法的问题在于,必须为每个数据库编写相同的查询。 如果需要编辑SEARCH_STUDENTS查询,则需要编辑oracle和mysql文件。

如果您的项目只有一个数据库供应商,则NativeQuery资源不会有问题。

这种混合方法(同一项目中的JPQL和NativeQuery)的优点是可以利用其他JPA优点。

处理速度慢,内存容量大

可以通过优化查询(使用NativeQuery),查询分页和小事务来解决此问题。
避免将EJB与PersistenceContext Extended一起使用,这种上下文将消耗更多的内存和服务器处理能力。

也有可能从数据库中获取一个实体作为“ 只读 ”实体,例如:将仅在报表中使用的实体。 要恢复处于打开状态的“ 只读 ”状态的实体,请看下面的代码:

String query = "select uai from Student uai";
EntityManager entityManager = entityManagerFactory.createEntityManager();
TypedQuery<Student> typedQuery = entityManager.createQuery(query, Student.class);
List<Student> resultList = typedQuery.getResultList();

请注意,在上面的代码中没有打开的事务,所有返回的实体都将被分离(不受JPA监视)。 如果使用的是EJB,则将事务标记为NOT_SUPPORTED,或者可以使用@Transactional(readOnly = true)。

复杂

我想说,解决这个问题只有一种解决方案:学习。 有必要阅读书籍,博客,杂志或JPA材料的任何其他可靠来源。 在JPA中,更多的研究等于更少的疑问。

我不是一个开发人员,它相信JPA是解决每个问题的唯一且最佳的解决方案,但是有时候JPA并不是使用工具的最佳方法。

在决定更改持久性框架时,您必须小心,通常会影响许多类,并且需要大量的重构。 此重构可能会导致一些错误。 需要与项目经理讨论这种重构并列出所有正面和负面影响。

在接下来的四页中,我们将看到可以在我们的项目中使用的4个持久性框架,但是在看到这些框架之前,我将展示如何选择每个框架。

选择此处描述的框架的标准

也许您会想到:“为什么X不在这里?”。 下面,我将列出用于选择此处显示的框架的标准:

  • 可以在多个研究来源中找到:我们可以在论坛中找到谈论框架的人,但是要在多个论坛中找到相同的框架却很难。 选择了引用最多的框架。
  • 由不同来源引用 :在论坛中找到的某些框架仅由其提交者指示。 一些论坛不允许使用“自我商品”,但某些框架所有者仍在这样做。
  • 最近更新时间2013年1月5日 :我搜索了过去一年中已更新的框架。
  • 快速的Hello World :某些框架在15分钟至20分钟的时间内无法完成Hello World,并且存在一些错误。 对于这篇文章中的教程,我在每个框架上工作了7分钟:从下载开始算起,直到第一个数据库插入。

这里将显示的框架具有良好的方法并且易于使用。 为了制作一个真实的CRUD场景,我们有一个如下的持久性模型:

  • 名称与列名称不同的属性:socialSecurityNumber-> social_security_number
  • 日期属性
  • 一个ENUM属性

在课堂上有了这个特性,我们将看到一些问题以及框架如何解决它。

Spring JDBC模板

我们可以找到用于访问数据库数据的最著名的框架之一是Spring JDBC模板。 该项目的代码可以在这里找到: https : //github.com/uaihebert/SpringJdbcTemplateCrud

Sprint JDBC模板使用如下的本机查询:

如上图所示,查询具有数据库语法(我将使用MySQL)。 当我们使用本机SQL查询时,可以轻松地使用所有数据库资源。

我们需要一个对象JDBC模板的实例(用于执行查询),并且要创建JDBC模板对象,我们需要设置一个数据源:

我们现在可以获取数据源(感谢Spring注入)并创建我们的JDBCTemplate:

PS .:上面的所有XML代码和JDBCTemplate实例化都可以被Spring注入和代码引导替换,只需对Spring功能进行一些研究即可。 我不喜欢的一件事是ID恢复的INSERT语句,它很冗长:

使用KeyHolder类,我们可以在数据库中恢复生成的ID,不幸的是,我们需要大量的代码才能完成该操作。 其他CRUD功能更易于使用,如下所示:

注意,由于使用RowMapper,执行SQL查询非常简单,并且会生成一个填充的对象。 RowMapper是JDBC模板用来简化使用数据库中数据填充类的引擎

看看下面的RowMapper代码:

关于RowMapper的最好的消息是它可以在项目的任何查询中使用。 负责编写将填充类数据的逻辑的开发人员。 要完成此页面,请在下面的数据库DELETE和数据库UPDATE语句中查看:

关于Spring JDBC模板,我们可以说:

  • 拥有良好的支持 :在Internet上进行的任何搜索都将导致包含提示和错误修复的多个页面。
  • 许多公司都在使用它 :全世界有几个项目在使用它
  • 对于同一项目,请小心使用不同的数据库:对于使用不同数据库运行的项目,本机SQL可能会成为问题。 需要重写几个查询以适应所有项目数据库。
  • 框架知识 :很好地了解Spring基础知识,如何配置和使用它。

对于那些不知道Spring有几个模块的人,在您的项目中可以仅使用JDBC Template模块。 您可以保留项目的所有其他模块/框架,并仅添加运行JDBC模板所需的模块/框架。

MyBatis

MyBatis(以iBatis名称创建)是一个非常好的框架,许多开发人员都在使用它。 有很多功能,但是我们在这篇文章中只会看到一些。 该页面的代码可以在这里找到: https : //github.com/uaihebert/MyBatisCrud

要使用MyBatis运行项目,您将需要实例化会话工厂。 这很容易,文档说明该工厂可以是静态的:

当使用MyBatis运行项目时,只需要实例化一次Factory,这就是为什么它使用静态代码。 配置XML(mybatis.xml)非常简单,其代码可以在下面找到:

映射器(上面XML中的一个属性)将保存有关项目查询以及如何将数据库结果转换为Java对象的信息。 可以用XML或接口创建映射器。 让我们看下面在文件crud_query.xml中找到的Mapper:

请注意,该文件很容易理解。 找到的第一个配置是ResultMap ,它指示查询结果类型,并且结果类配置为“ uai.model.Customer ”。 在该类中,我们有一个具有不同名称的数据库表列的属性,因此我们需要向ResultMap添加配置。 所有查询都需要一个MyBatis会话将使用的ID。 在文件的开头,可能会看到一个声明的名称空间 ,它用作Java包,该包将包装所有查询和XML文件中的ResultMap 。 我们也可以使用Interface + Annotation代替XML。 在crud_query.xml文件中找到的Mapper可以转换为以下接口:

在接口中只编写了Read方法,以使代码更小,但是所有CRUD方法都可以在接口中编写。 首先让我们看看如何执行XML文件中的查询:

对象的解析是自动的,该方法易于阅读。 要运行查询,只需使用上面在crud_query.xml代码中看到的“ 名称空间+查询ID ”组合。 如果开发人员希望使用接口方法,则可以执行以下操作:

使用接口查询模式,我们可以得到干净的代码,并且开发人员无需实例化Interface,MyBatis的会话类即可完成工作。 如果要更新,删除或在数据库中插入记录,则代码很简单:

关于MyBatis,我们可以说:

  • 优秀的文档 :每当我有疑问时,只要阅读其站点文档就可以回答
  • 灵活性 :允许XML或Interfaces + Annotations,该框架为开发人员提供了极大的灵活性。 请注意,如果选择接口方法,数据库的可移植性将更加困难,那么使用部署工件而不是接口来选择要发送的XML更容易。
  • 集成 :与Guice和Spring集成
  • 动态查询 :允许在运行时中创建查询,例如JPA条件。 可以在查询中添加“ IF”来确定将在查询中使用哪个属性
  • 事务 :如果您的项目未使用Spring的Guice,则需要手动控制事务

索莫拉

Sormula是一个ORM开源框架,非常类似于JPA / Hibernate。 此页面中项目的代码可以在以下位置找到: https : //github.com/uaihebert/SormulaCrud

Sormula有一个名为Database的类,它的工作方式类似于JPA EntityManagerFactoryDatabase类就像数据库和模型类之间的桥梁。 为了执行SQL动作,我们将使用Table类,该类的工作方式类似于JPA EntityManager ,但是键入了Table类。 要以代码运行Sormula,您将需要创建一个数据库实例:


要创建数据库实例,我们需要的是Java连接。 从数据库读取数据非常容易,如下所示:


您只需要创建一个数据库实例和一个实例即可执行各种SQL操作。 我们如何映射与数据库表列名称不同的类属性名称? 看下面:

我们可以使用批注在我们的类中进行数据库映射,非常类似于JPA样式。 要更新,删除或创建数据库中的数据,您可以执行以下操作:


关于Sormula,我们可以这样说:

  • 拥有良好的文档
  • 易于设置
  • 在maven存储库中找不到它,如果需要,它将使附加源代码更加困难
  • 有很多检查过的异常,您需要对调用的动作进行try / catch

sql2o

该框架可与本机SQL一起使用,并使将数据库数据转换为Java对象更加容易。 此页面中项目的代码可在以下位置找到: https : //github.com/uaihebert/sql2oCrud sql2o具有一个非常易于创建的Connection类:


请注意,我们有一个静态Sql2o对象,它将像Connection工厂一样工作。 要读取数据库数据,我们将执行以下操作:


请注意,我们已编写了本机SQL,但已命名参数。 我们没有使用像'?1'这样的位置参数,而是给像':id'这样的参数命名。 可以说,命名参数的优点是我们不会在具有多个参数的查询中迷失; 当我们忘记传递某些参数时,错误消息将告诉我们缺少的参数名称。

我们可以在查询中告知具有不同名称的列的名称,无需创建Mapper / RowMapper。 使用查询中定义的返回类型,我们将不需要手动实例化该对象,sql2o将为我们完成该操作。 如果要更新,删除或在数据库中插入数据,可以执行以下操作:


这是一个“非常易于使用”的框架。 关于sql2o,我们可以这样说:

  • 易于处理标量查询 :SUM,COUNT函数的返回值易于处理
  • 查询中的命名参数 :使用许多参数将易于处理SQL
  • 绑定函数 :bind是一个将通过给定对象自动填充数据库查询参数的函数,不幸的是,由于枚举问题,该函数不适用于该项目。 我没有调查问题,但是我认为这很容易处理

OO

jOOQ它是一个由很多人指示的框架,该框架的用户在很多站点/论坛中都赞扬它。 不幸的是,jOOQ在我的PC上无法工作,因为我的数据库太旧了,写这篇文章时(在飞机上)我无法下载其他数据库。

我注意到,要使用jOOQ,您将需要基于模型生成几个jOOQ类。 jOOQ在站点上有一个很好的文档,其中详细介绍了如何生成这些类。

jOOQ对于使用免费数据库(例如:MySQL,Postgre等)的用户免费。对于使用付费数据库(例如,Oracle,SQL Server等)的用户,需要jOOQ付费版本。

  • www.jooq.org/

阿瓦耶

是在多个博客/论坛中引用的框架。 它与ORM概念一起使用,并且很容易执行数据库CRUD操作。

我发现的问题:

  • 没有足够详细的文档 :其Hello World不太详细
  • 配置 :它具有必需的属性配置文件,其中包含许多配置,对于那些只想做一个Hello World的人来说确实很无聊
  • 需要增强器:增强是一种用于优化类字节码的方法,但是一开始很难设置,并且必须在Hello World之前进行
  • www.avaje.org

原始的JDBC方法值得吗?

JDBC的优点是:

  • 最佳性能 :在持久层和数据库之间,我们将没有任何框架。 我们可以使用原始JDBC获得最佳性能
  • 控制SQL :书面SQL是将在数据库中执行SQL,没有框架会编辑/更新/生成查询SQL
  • 本机资源 :我们可以毫无问题地访问所有本机数据库资源,例如:函数,存储过程,提示等

缺点是:

  • 详细代码 :收到数据库查询结果后,我们需要手动实例化并填充对象,并调用所有必需的“设置”方法。 如果我们具有一对多的类关系,则此代码将变得更糟。 在另一个片刻之内找到片刻很容易。
  • 易碎代码 :如果数据库表列更改其名称,则必须编辑使用该列的所有项目查询。 一些项目使用带有列名的常量来完成此任务,例如Customer.NAME_COLUMN ,通过这种方法,表列名的更新会更容易。 如果将列从数据库中删除,即使您具有列常量,所有项目查询都将被更新。
  • 复杂的可移植性 :如果您的项目使用多个数据库,则必须为每个供应商编写几乎所有查询。 对于任何查询中的任何更新,都必须更新每个供应商查询,这可能需要开发人员花费大量时间。

我只能看到一个因素,几乎可以让我立即选择原始的JDBC方法:

  • 性能 :如果您的项目需要每分钟处理数千个事务,需要可伸缩且内存使用率低,这是最佳选择。 通常,中型/大型项目具有所有这些高性能要求。 也可以为项目提供混合解决方案。 大多数项目存储库(DAO)将使用框架,而只有一小部分将使用JDBC

我非常喜欢JDBC,我已经工作过并且仍在使用它。 我只是要求您不要认为JDBC是解决每个问题的灵丹妙药。

如果您知道此处没有列出的其他优点/缺点,请告诉我,我将在此添加您的功劳。

如何选择正确的框架?

如果要为其他项目更改JPA,或者仅在寻找其他持久性框架,我们必须小心。 如果第3页中的解决方案不能解决您的问题,最好的解决方案是更改持久性框架。 在更改持久性框架之前,您应该考虑什么?

  • 文档 :该框架是否有据可查? 很容易理解它是如何工作的,它可以回答您的大多数疑问吗?
  • 社区 :框架是否具有活跃的用户社区? 有论坛吗?
  • 维护/修复错误 :框架是否正在接受提交以修复错误或接受新功能? 是否正在创建修订版本? 哪个频率?
  • 寻找一个了解这个框架的开发人员有多难 ? 我认为这是要考虑的最重要的问题。 您可以将世界上最好的框架添加到您的项目中,但是如果没有开发人员知道如何操作框架,框架将无用。 如果您需要聘请高级开发人员,找到一名开发人员会有多难? 如果您紧急需要雇用一个知道未知框架的人员,这可能会非常困难。

最后的想法

我会再说一遍:我不认为JPA可以/不应该应用于世界上每个项目中的每种情况。 我认为JPA像其他任何框架一样都有缺点,因此没有用。

如果您的框架未在此处列出,我不希望您受到冒犯,也许我用来查找持久性框架的研究用语并没有带我进入您的框架。

希望这篇文章对您有所帮助。 如果您有任何重复/问题,请将其发布。 再见!

翻译自: https://www.javacodegeeks.com/2014/09/jpa-hibernate-alternatives-what-can-i-use-if-jpa-or-hibernate-is-not-good-enough-for-my-project.html

hibernate jpa

hibernate jpa_JPAHibernate替代方案。 如果JPA或Hibernate对于我的项目而言不够好,该怎么办?...相关推荐

  1. jpa和hibernate_从JPA到Hibernate的旧版和增强型标识符生成器

    jpa和hibernate JPA标识符生成器 JPA定义了以下标识符策略: 战略 描述 汽车 持久性提供程序选择基础数据库支持的最合适的标识符策略 身份 标识符由数据库IDENTITY列分配 序列 ...

  2. 从JPA到Hibernate的旧版和增强型标识符生成器

    JPA标识符生成器 JPA定义了以下标识符策略: 战略 描述 汽车 持久性提供程序选择基础数据库支持的最合适的标识符策略 身份 标识符由数据库IDENTITY列分配 序列 持久性提供程序使用数据库序列 ...

  3. JPA和Hibernate的关系

    转载自:https://www.cnblogs.com/amoyzhu/p/5937717.html JPA Java Persistence API,是Java EE 5的标准ORM接口,也是ejb ...

  4. JPA和Hibernate的关系(转)

    JPA Java Persistence API,是Java EE 5的标准ORM接口,也是ejb3规范的一部分. Hibernate,当今很流行的ORM框架,是JPA的一个实现,但是其功能是JPA的 ...

  5. 一步步实现:JPA的基本增删改查CRUD(jpa基于hibernate)

    1.创建一个JPA工程 首先,创建一个JPA工程(若不知道JPA创建或出现at least one user library must be selected等错误,请参考http://blog.cs ...

  6. SpringData Jpa、Hibernate、Jpa 三者之间的关系

    JPA规范与ORM框架之间的关系是怎样的呢? JPA规范本质上就是一种ORM规范,注意不是ORM框架--因为JPA并未提供ORM实现,它只是制订了一些规范,提供了一些编程的API接口,但具体实现则由服 ...

  7. java jpa hibernate_java - JPA和Hibernate - Criteria与JPQL或HQL

    java - JPA和Hibernate - Criteria与JPQL或HQL 使用Criteria或HQL有哪些优缺点? Criteria API是一种很好的面向对象的方式来表达Hibernate ...

  8. hibernate与jpa_将JPA Hibernate与OptaPlanner集成

    hibernate与jpa 我们一直在改进OptaPlanner与JEE其余部分的集成,因此更容易构建可以正常工作的最终用户应用程序. 让我们看一下改进的JPA Hibernate集成. 基础 JPA ...

  9. jpa和hibernate_使用JPA和Hibernate有效删除数据

    jpa和hibernate 您可能会遇到必须对关系数据库中存储的大量数据集执行批量删除的情况. 如果您将JPA与Hibernate一起用作基础OR映射器,则可以尝试通过以下方式调用EntityMana ...

最新文章

  1. Xamarin Essentials教程发送邮件Email
  2. python项目面试_Python面试中最常见的25个问题-结束
  3. linux上查看gitlab日志,如何查看Gitlab的版本?
  4. Pig 0.12.1安装和使用
  5. FileSystemResource 和ClassPathResource 有何区别?
  6. mysql解决select * from 表名 (where + 约束条件为空)
  7. Web development mistakes
  8. RSS(Really Simple Syndication)简易信息聚合
  9. 利用Geotools来转换影像的坐标系[转]
  10. 学点 C 语言(22): 数据类型 - 多维数组与指针
  11. mysql用户创建、授权
  12. 史上MySQL安装配置教程最细,一步一图解
  13. 字符串按照ASCII排序
  14. zookeeper羊群效应
  15. Python开发基础(一)基本数据类型
  16. svchost.exe占网速的解决办法
  17. java程序员月薪一万很难?(要到什么程度)
  18. 华为智慧屏V55升级鸿蒙2,华为智慧屏将作为第一批升级鸿蒙 OS 2.0 系统的终端产品...
  19. 电子设计竞赛(6)-逆变电路
  20. 阿里“中供系”前世今生:马云麾下最神秘的子弟兵

热门文章

  1. C. Minimum Grid Path(思维)
  2. 牛客网暑期ACM多校训练营(第一场)
  3. SpringCloud Gateway配置自定义路由404坑
  4. 三个好用的并发工具类
  5. 两个月拿到N个offer,看看我是如何做到的
  6. Java多线程:实现方式Thread与Runnable
  7. 05-传统开发模式DAO
  8. 如何将HBuilder中的项目Push至Gitee中!
  9. 2020蓝桥杯省赛---java---B---6(成绩分析)
  10. JDBC连接数据库教程,postgreSQL