关于hibernate:Java持久化框架Hibernate与Mybatis

Java长久化框架:Hibernate与MybatisHibernate和Mybatis是两个Java长久化框架,用于将Java对象映射到关系型数据库中。在开发Web应用程序时,Java开发人员常常应用这些框架来解决数据长久化的事物。这篇文章将具体介绍Hibernate和Mybatis的特点、优劣势以及如何抉择哪个框架适宜您的我的项目。 1. HibernateHibernate是一个开源的对象关系映射框架,它提供了一种主动将Java对象映射到数据库表中的办法。与传统的JDBC相比,Hibernate大大简化了数据库操作,并且使得代码更加易于保护和了解。 特点 Hibernate实现了JPA(Java Persistence API)标准,因而它能够与任何实现JPA标准的ORM框架无缝集成。Hibernate应用了Hibernate Query Language(HQL),它是一种灵便的查询语言,容许您以面向对象的形式查询数据库。Hibernate反对多种数据库,包含MySQL、Oracle、PostgreSQL等,并且能够轻松地切换数据库。Hibernate还提供了二级缓存和查问缓存,这能够大大提高应用程序的性能。劣势 易于应用:Hibernate提供了非常简单的API,开发人员不须要编写简单的SQL语句来执行CRUD操作。易于保护:Hibernate使得代码更加易于保护和了解,大大降低了开发人员的工作量。易于扩大:Hibernate提供了丰盛的API,能够轻松扩大应用程序。劣势 性能:Hibernate的性能比Mybatis略差。在解决大量数据时,可能会呈现性能问题。然而,应用缓存和优化查问能够进步性能。复杂性:Hibernate的复杂性比Mybatis更高。初学者须要破费一些工夫学习框架的基本概念和操作。2. MybatisMybatis是另一个Java长久化框架,它通过XML或正文来映射Java对象和数据库记录。与Hibernate相比,Mybatis更重视SQL管制,并提供了更好的灵活性和可定制性。 特点 灵活性:Mybatis容许您齐全管制SQL查问过程,包含手写SQL查问语句、参数映射和后果映射。这使得Mybatis非常灵活。可定制性:Mybatis容许您自定义类型转换器、插件等,以满足非凡需要。易于学习:Mybatis的学习曲线比Hibernate更加平滑。初学者能够很快上手并开始编写查问。劣势 性能:Mybatis比Hibernate更快。它通过手写SQL语句和提供缓存来进步性能,特地是在解决大量数据时。灵活性:Mybatis非常灵活,容许您齐全管制SQL查问过程,并提供了很好的扩展性。劣势 复杂性:Mybatis须要开发人员编写简单的SQL语句,这对于初学者来说可能有些艰难。维护性:因为开发人员须要手写SQL语句,因而代码可能会变得简短和难以保护。3. 如何抉择在抉择Hibernate或Mybatis时,须要依据我的项目的理论需要进行评估。如果您的我的项目须要高度的可定制性和灵活性,并且解决大量数据,那么Mybatis可能更适宜您。如果您须要疾速地开发应用程序并放弃较低的保护老本,则Hibernate可能更适宜您。总之,两个框架各有优缺点,须要依据您的需要做出抉择。 论断Hibernate和Mybatis都是十分有用的Java ORM框架,能够帮忙开发人员更轻松地治理数据库操作。在抉择哪个框架时,请思考我的项目的理论需要,并依据其长处和毛病做出抉择。无论您抉择哪个框架,都须要破费一些工夫学习它的基本概念和操作,以便正确应用它们来开发高质量的应用程序。

May 21, 2023 · 1 min · jiezi

关于hibernate:jpa之hibernate和jackson踩坑记录

在做的我的项目采纳的是spring jpa,底层默认应用的是orm是hibernate,通过hibernate查问进去的实体对象实际上都是代理对象,在序列化的时候,咱们可能会遇到懒加载导致jackson无奈正确解析对象的问题,这个能够通过导入maven包 <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-hibernate5</artifactId></dependency>而后加载进objectMapper上下文 @Beanpublic Jackson2ObjectMapperBuilderCustomizer builderCustomizer() { return builder -> { //jackson序列化 和 hibernate懒加载 builder.modulesToInstall(hibernate5Module()); };}private static Hibernate5Module hibernate5Module() { Hibernate5Module hibernate5Module = new Hibernate5Module(); hibernate5Module.configure(REPLACE_PERSISTENT_COLLECTIONS, true); //hibernate5Module.configure(FORCE_LAZY_LOADING, true); return hibernate5Module;}这样在序列化的时候就会判断之前是否存在数据了,如果是懒加载则会序列化为null。 我在反序列化的时候会报failed to lazily initialize a collection, could not initialize proxy...,起初看了一下序列化后的json,发现有些提早加载的Collection类型的会解析成org.hibernate.collection.internal.PersistentBag(hibernate的代理对象),而不是咱们个别json的汇合模式。导致反序列化的时候,会生成PersistentBag对象,这时候jackson操作PersistentBag,会导致hibernate检测到数据变动,从而触发它的一些操作而报下面的错。 而后我就排查,为啥序列化的时候会转成PersistentBag对象呢?能够看看Hibernate5Module里的代码,该模块会加载两个 context.addSerializers(new HibernateSerializers(_mapping, _moduleFeatures));context.addBeanSerializerModifier(new HibernateSerializerModifier(_moduleFeatures, _sessionFactory));//序列化处理器,咱们之前的解决懒加载原理也是通过这两个解决的,而后我在HibernateSerializerModifier里看到了PersistentCollectionSerializer,对于汇合类型的解析解决,其中次要有个判断办法protected boolean usesLazyLoading(BeanProperty property) { if (property != null) { // As per [Issue#36] ElementCollection ec = property.getAnnotation(ElementCollection.class); if (ec != null) { return (ec.fetch() == FetchType.LAZY); } OneToMany ann1 = property.getAnnotation(OneToMany.class); if (ann1 != null) { return (ann1.fetch() == FetchType.LAZY); } OneToOne ann2 = property.getAnnotation(OneToOne.class); if (ann2 != null) { return (ann2.fetch() == FetchType.LAZY); } ManyToOne ann3 = property.getAnnotation(ManyToOne.class); if (ann3 != null) { return (ann3.fetch() == FetchType.LAZY); } ManyToMany ann4 = property.getAnnotation(ManyToMany.class); if (ann4 != null) { return (ann4.fetch() == FetchType.LAZY); } // As per [Issue#53] return !Feature.REQUIRE_EXPLICIT_LAZY_LOADING_MARKER.enabledIn(_features); } return false;}发现我关联字段上应用的是@ManyToMany(fetch = FetchType.EAGER),因为我之前为了解决懒加载就加上的,当初能够去掉了,问题也失去了解决。 ...

November 13, 2021 · 1 min · jiezi

关于hibernate:jpa之hibernate和jackson踩坑记录

在做的我的项目采纳的是spring jpa,底层默认应用的是orm是hibernate,通过hibernate查问进去的实体对象实际上都是代理对象,在序列化的时候,咱们可能会遇到懒加载导致jackson无奈正确解析对象的问题,这个能够通过导入maven包 <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-hibernate5</artifactId></dependency>而后加载进objectMapper上下文 @Beanpublic Jackson2ObjectMapperBuilderCustomizer builderCustomizer() { return builder -> { //jackson序列化 和 hibernate懒加载 builder.modulesToInstall(hibernate5Module()); };}private static Hibernate5Module hibernate5Module() { Hibernate5Module hibernate5Module = new Hibernate5Module(); hibernate5Module.configure(REPLACE_PERSISTENT_COLLECTIONS, true); //hibernate5Module.configure(FORCE_LAZY_LOADING, true); return hibernate5Module;}这样在序列化的时候就会判断之前是否存在数据了,如果是懒加载则会序列化为null。 我在反序列化的时候会报failed to lazily initialize a collection, could not initialize proxy...,起初看了一下序列化后的json,发现有些提早加载的Collection类型的会解析成org.hibernate.collection.internal.PersistentBag(hibernate的代理对象),而不是咱们个别json的汇合模式。导致反序列化的时候,会生成PersistentBag对象,这时候jackson操作PersistentBag,会导致hibernate检测到数据变动,从而触发它的一些操作而报下面的错。 而后我就排查,为啥序列化的时候会转成PersistentBag对象呢?能够看看Hibernate5Module里的代码,该模块会加载两个 context.addSerializers(new HibernateSerializers(_mapping, _moduleFeatures));context.addBeanSerializerModifier(new HibernateSerializerModifier(_moduleFeatures, _sessionFactory));//序列化处理器,咱们之前的解决懒加载原理也是通过这两个解决的,而后我在HibernateSerializerModifier里看到了PersistentCollectionSerializer,对于汇合类型的解析解决,其中次要有个判断办法protected boolean usesLazyLoading(BeanProperty property) { if (property != null) { // As per [Issue#36] ElementCollection ec = property.getAnnotation(ElementCollection.class); if (ec != null) { return (ec.fetch() == FetchType.LAZY); } OneToMany ann1 = property.getAnnotation(OneToMany.class); if (ann1 != null) { return (ann1.fetch() == FetchType.LAZY); } OneToOne ann2 = property.getAnnotation(OneToOne.class); if (ann2 != null) { return (ann2.fetch() == FetchType.LAZY); } ManyToOne ann3 = property.getAnnotation(ManyToOne.class); if (ann3 != null) { return (ann3.fetch() == FetchType.LAZY); } ManyToMany ann4 = property.getAnnotation(ManyToMany.class); if (ann4 != null) { return (ann4.fetch() == FetchType.LAZY); } // As per [Issue#53] return !Feature.REQUIRE_EXPLICIT_LAZY_LOADING_MARKER.enabledIn(_features); } return false;}发现我关联字段上应用的是@ManyToMany(fetch = FetchType.EAGER),因为我之前为了解决懒加载就加上的,当初能够去掉了,问题也失去了解决。 ...

November 13, 2021 · 1 min · jiezi

关于hibernate:java开发框架之Hibernate入门学习

Hibernate框架Hibernate框架简化了java应用程序与数据库交互的开发。 Hibernate是一个开源,轻量级的ORM(对象关系映射)工具。ORM工具简化了数据创立,数据处理和数据拜访。它是将对象java培训映射到数据库中存储的数据(表)的编程技术。ORM工具外部应用JDBC API与数据库进行交互。Hibernate框架的优缺点Hibernate框架有很多长处:开源和轻量级: Hibernate框架是依据LGPL许可证和轻量级的开源工具。疾速性能: Hibernate框架的性能很快,因为缓存在Hibernate框架外部应用。 hibernate框架中有两种类型的缓存:一级缓存和二级缓存。一级缓存默认是启用的。数据库独立查问: HQL(Hibernate查询语言)是面向对象的SQL版本。 它生成数据库独立查问。 所以你不须要编写数据库特定的查问语句。 在Hibernate之前,如果我的项目更改了数据库,咱们须要更改SQL查问,从而导致保护变得非常复杂。主动创立表: Hibernate框架提供了主动创立数据库表的性能。 因而,无需手动在数据库中创立表。简化简单连贯: 在hibernate框架中可轻松获取多个表中的数据。提供查问统计和数据库状态: Hibernate反对查问缓存,并提供无关查问和数据库状态的统计信息。毛病:不适宜须要应用数据库的特定优化机制的状况不适宜大规模的批量数据处理与MyBatis的比拟绝对于MyBatis的“SQL-Mapping”的ORM实现,Hibernate的ORM实现更加欠缺,提供了对象状态治理、级联操作等性能齐全面向对象,语句与数据库无关,开发者无需关注SQL的生成,开发简略,便于批改,数据库移植性好因为间接应用SQL,MyBatis应用自由度较高应用Hibernate步骤应用Hibernate APIHibernate的三大状态小结一下

October 28, 2021 · 1 min · jiezi

关于hibernate:JPA开发利器fastjpa使用介绍

介绍一款JPA开发利器fastjpa,它提供了对SpringBoot框架中对于对JPA的操作的二次封装 ,提供了面向对象的形式来操作JPQL/HQL,旨在缩小sql语句编写,疾速进步开发效率,使代码书写显的更加优雅和减少可读性 工具个性:面向对象形式的更新、删除和查问操作查问指定列名和函数列分组查问和过滤列表查问和过滤表连贯查问和过滤反对子查问分页查问和过滤装置<dependency> <groupId>com.github.paganini2008.springworld</groupId> <artifactId>fastjpa-spring-boot-starter</artifactId> <version>2.0.2</version></dependency>fastjpa-spring-boot-starter 依赖spring-boot-starter-data-jpa, 本质上是对JPA Criteria查问API(QBC)的再封装,并设计成流式格调的API(有点相似python的orm框架sqlalchemy) ,使得JPA面向对象查问的API不再难用 fastjpa 外围接口:EntityDaoModelJpaQueryJpaPageFilterColumnFieldJpaGroupByJpaSortJpaPageResultSetJpaQueryResultSetJpaUpdateJpaDelete大家有趣味的话,能够钻研其源码上面通过几个示例来演示一下fastjpa的几个外围接口的用法比方,当初有3个实体,用户,订单,商品 用户实体@Getter@Setter@Entity@Table(name = "demo_user")public class User { @Id @Column(name = "id", nullable = false, unique = true) private Long id; @Column(name = "name", nullable = false, length = 45) private String name; @Column(name = "phone", nullable = false, length = 45) private String phone; @Column(name = "vip", nullable = true) @org.hibernate.annotations.Type(type = "yes_no") private Boolean vip;}商品实体@Getter@Setter@Entity@Table(name = "demo_product")public class Product { @Id @Column(name = "id", nullable = false, unique = true) private Long id; @Column(name = "name", nullable = false, length = 45) private String name; @Column(name = "price", nullable = false, precision = 11, scale = 2) private BigDecimal price; @Column(name = "origin", nullable = true, length = 225) private String origin;}订单实体@Getter@Setter@Entity@Table(name = "demo_order")public class Order { @Id @Column(name = "id", nullable = false, unique = true) private Long id; @Column(name = "discount", nullable = true) private Float discount; @Column(name = "price", nullable = false, precision = 11, scale = 2) private BigDecimal price; @OneToOne(targetEntity = Product.class) @JoinColumn(nullable = false, name = "product_id", foreignKey = @ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT)) private Product product; @ManyToOne(targetEntity = User.class) @JoinColumn(nullable = false, name = "user_id", foreignKey = @ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT)) private User user; @Temporal(TemporalType.TIMESTAMP) @Column(name = "create_time", columnDefinition = "timestamp null ") private Date createTime;}而后定义对应的Dao,须要继承fastjpa提供的EntityDao,但如果你不想应用fastjpa, 间接继承JpaRepositoryImplementation就行了 ...

August 8, 2021 · 8 min · jiezi

关于hibernate:Hibernate的升级Query用法

一、基本概念1、Configuration:     概述: Configuration类负责管理Hibernate的配置信息。启动Hibernate、创立SessionFactory对象。       (1)  Hibernate运行的底层配置信息:数据库的URL、用户名、明码、JDBC驱动类,数据库Dialect,数据库连接池等。       (2)  Hibernate对象关系映射文件(*.hbm.xml) 。    Hibernate配置的两种办法:      (1)属性文件( (hibernate.properties)                  调用代码:Configuration cfg = new Configuration();     (2)XML文件(hibernate.cfg.xml) 。                 调用代码:Configuration cfg = new Configuration().configure();                 configrure()办法默认读hibernate.cfg.xml 2.SessionFactory:    概述:应用程序从SessionFactory(会话工厂)里取得Session(会话)实例。它在多个利用线程间进行共享。       (1) SessionFactory是线程平安的(Thread-Safe),能够让多个执行线程同时存取SessionFactory而不会有数据共享的问题。      (2) 会话工厂缓存了生成的SQL语句和Hibernate在运行时应用的映射元数据。      (3) 须要留神的是SessionFactory是重量级的,因为个别状况下,一个我的项目通常只须要一个SessionFactory就够(单例模式),当须要操作多个数据库时,能够为每个数据库指定一个SessionFactory。   调用代码: SessionFactory sessionFactory =cfg.buildSessionFactory(); ...

June 14, 2021 · 3 min · jiezi