相信很多伙伴和我一样,之前接触的JDBC->mybatis。至于hibernate只知道它是全自动的,而mybatis是半自动的。比较熟悉的或者用的比较多的可能是SSM,而SSH则接触比较少。最近几天将重新较细致认识一下hibernate。Let’s go~~
一、hibernate和mybatis区别:
二、我的第一个hibernate-demo:
2.1 准备数据库文件:
2.2 导入相关依赖:
2.3 创建相关实体类:
2.4 配置hibernate.cfg.xml文件:
2.5 创建实体类映射:
2.6 测试:
2.7 测试中可能遇到的问题和解决措施:
一、hibernate和mybatis区别:
- hibernate是全自动的,而mybatis是半自动的;hibernate完全可以通过对象关系模型实现对数据库的操作,拥有完整的JavaBean对象与数据库的映射结构来自动生成sql。而mybatis仅有基本的字段映射,对象数据以及对象后实际关系仍然需要通过手写sql来实现和管理
- hibernate数据库移植性远大于mybatis;hibernate通过强大的映射结构和hql语言,大大降低了对象与数据库(Oracle、mysql等)的耦合性,而mybatis由于需要手写SQL,因此与数据库的耦合性直接取决于程序员写SQL的方法,如果SQL不具通用性而用了很多某数据库特性的SQL语句的话,移植性也会随之降低很多,成本很高
- hibernate拥有完整的日志系统,mybatis则欠缺一些;hibernate日志系统非常健全,涉及广泛,包括:SQL记录、关系异常、优化警告、缓存提示、脏数据警告等;而mybatis则除了基本记录功能外,功能薄弱很多
- mybatis相比于hibernate关心很多细节;hibernate配置要比mybatis复杂得多,学习成本也比mybatis高,但也正因为mybatis使用简单,才导致他要比hibernate关心很多的技术细节,mybatis由于不用考虑很多细节,开发模式上与传统的jdbc区别很小,因此很容易上手开发项目,但忽略细节导致bug较多,因而开发出相对稳定的软件很慢,而开发出软件却很快。hibernate则正好相反。但是如果使用hibernate很熟练的话,实际开发效率四号不差于甚至超越mybatis
- SQL直接优化上,mybatis要比hibernate方便很多;由于mybatis的SQL都是写在xml里,因此优化SQL比hibernate方便很多。二hibernate的SQL很多都是自动生成的,无法直接维护SQL;虽有hql,单功能还是不及SQL强大,见到报表等便要需求时,hql也歇菜,也就是说hql有局限性,hibernate虽然也支持原生的SQL,但是开发模式上却与orm不同,需要转换思维,因此使用上不是很方便,总之写SQL的灵活度上hibernate不及mybatis
二、我的第一个hibernate-demo:
2.1 准备数据库文件:
customer表 | orders表 |
/* Source Server : MySQL Target Server Type : MYSQL Date: 2022-11-12 11:47:54 SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- ---------------------------- | /* Source Server : MySQL Target Server Type : MYSQL Date: 2022-11-12 11:45:16 SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- ---------------------------- |
2.2 导入相关依赖:
导入lombok、mysql-connector-java、hibernate-core依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.6.9.Final</version>
</dependency>
2.3 创建相关实体类:
Customer:
package com.xgsm.entity;
import lombok.Data;
import java.util.List;
@Data
public class Customer {
private Integer id;
private String name;
// 在Customer中添加与Orders表的关系(一对多)
private List<Orders> orders;
}
Orders:
package com.xgsm.entity;
import lombok.Data;
@Data
public class Orders {
private Integer id;
private String name;
private Integer cid;
// 在Orders中添加与Customer的关系(一对一)
private Customer customer;
}
2.4 配置hibernate.cfg.xml文件:
在hibernate.cgf.xml中配置数据源以及配置连接池等信息
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!--Session-factory:针对单个数据库映射经过编译的内存镜像文件,将数据库转换成一个java可以识别的镜像文件-->
<!-- 构造Session-factory非常消耗资源,所以通常一个工程只需要创建一个Session-factory-->
<session-factory>
<!--连接字符串-->
<property name="connection.url">jdbc:mysql://localhost:3306/hibernate?useUnicode=true</property>
<!--连接数据库的用户名-->
<property name="connection.username">root</property>
<!--数据库用户密码-->
<property name="connection.password">990501</property>
<!--数据库驱动-->
<property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<!--C3P0连接池,每次不够的时候增10-->
<property name="hibernate.c3p0.acquire_increment">10</property>
<!--释放资源时间的限制,单位是s-->
<property name="hibernate.c3p0.idle_test_period">10000</property>
<!--设置超时时间-->
<property name="hibernate.c3p0.timeout">5000</property>
<!--设置最大连接数-->
<property name="hibernate.c3p0.max_size">30</property>
<!--设置最小连接数-->
<property name="hibernate.c3p0.min_size">5</property>
<!--设置缓存Statement对象的数量-->
<property name="hibernate.c3p0.max_statements">10</property>
<!--设置数据库方言-->
<property name="dialect">org.hibernate.dialect.MySQL8Dialect</property>
<!--显示执行的SQL语句-->
<property name="show_sql">true</property>
<!--格式化SQL语句-->
<property name="format_sql">true</property>
<!--是否自动生成数据表-->
<property name="hibernate.hbm2ddl.auto"/>
<!--设置Hibernate自动管理上下文的策略-->
<property name="current_session_context_class">thread</property>
<!--在启动时删除并重新创建数据库-->
<property name="hbm2ddl.auto">create</property>
<!--注册实体类映射关系-->
<mapping resource="com/xgsm/entity/Customer.hbm.xml"/>
</session-factory>
</hibernate-configuration>
2.5 创建实体类映射:
直接在entity(实体)包下创建映射实体类文件即可,具体配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!-- name=类名称,table==表名称 -->
<class name="com.xgsm.entity.Customer" table="customer">
<comment>顾客表</comment>
<id name="id" type="java.lang.Integer">
<column name="id" length="10">
<comment>主键</comment>
</column>
<!-- generator标签设置主键生成策略 ,identity为自增,assigned为主键由外部程序负责生成 -->
<generator class="identity"></generator>
</id>
<property name="name" type="java.lang.String">
<!--unique-key="AUTH_ROLE_USER_UNIQUE_KEY",那么在数据库表中对应的N个字段会组成“组合唯一约束” -->
<column name="name">
<comment>姓名</comment>
</column>
</property>
</class>
</hibernate-mapping>
2.6 测试:
创建test测试类,向数据库中添加一个数据。
import com.xgsm.entity.Customer;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Test {
public static void main(String[] args) {
// 创建Configuration,读取hibernate.cfg.xml
Configuration configuration = new Configuration().configure();
// 获取SessionFactory
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 获取session
Session session = sessionFactory.openSession();
Customer customer = new Customer();
customer.setName("wahaha");
session.save(customer);
session.beginTransaction().commit();
session.close();
}
}
运行结果如下:
2.7 测试中可能遇到的问题和解决措施:
上面的测试过程还是蛮顺利的,没有遇到什么bug。但是对于初学者来说有几个需要避免的错误,在这里总结一下,后续如果有其他的bug,再进行收集。
1、如果我们将实体类映射文件,放在实体类中,我们需要在pom.xml中设置一下,让maven能够读取到entity包下的文件,要不然会报错。具体实例如下:“Exception in thread "main" org.hibernate.boot.MappingNotFoundException: Mapping (RESOURCE) not found : com/xgsm/entity/Customer.hbm.xml : origin(com/xgsm/entity/Customer.hbm.xml)”
解决措施:在maven中配置一下,让maven能够扫描到
<!-- 设置可以读取java目录下的xml文件-->
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
2、在创建好实体映射文件后,没有注入到‘hibernate.cfg.xml’中,导致找不到实体类文件“Unknown entity: com.xgsm.entity.Customer”
解决措施:在‘hibernate.cfg.xml’文件中注册实体类映射关系
<!--注册实体类映射关系-->
<mapping resource="com/xgsm/entity/Customer.hbm.xml"/>
3、在hibernate.cfg.xml文件中设置数据库方言的时候,要根据自己mysql的版本去设置,要不然会报错,所以要注意。