hibernate
Hibernate是一款重量级的持久层框架,目前市面上的我很少见还有项目在开发时候使用他,之所以要学习这个,因为公司最近有一个系统升级的项目,之前的老系统用到了Hibernate。
同样还是老套路,学习一个新技术或者新知识,首先去他的官网看
【官网】:https://hibernate.org/orm/ 【官方教程】:https://hibernate.org/orm/documentation/getting-started/ 【github地址】:https://github.com/hibernate
目前hibernate已经更新到了6的版本,这里使用的5的版本
注意: Hibernate5.1;5.2官方推荐使用JDK1.8以及JDBC4
文章目录
一、Hibernate与JPA的关系
本章主要讲解的是 JPA的一些注解
二、JPA的基础入门
需求:同样是一个Customer的类,与之前不同的是,这次采用JPA的注解开发,省去了原有的实体映射的XML文件配置
【Customer实体类】
@Entity
@Table(name = "t_customer_jpa")
public class Customer implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "name")
private String name;
@Column(name = "gender")
private String gender;
// getter、setter...
}
注解说明:
-
@Entity注解:
标识一个实体类的JavaBean对象,每个持久化POJO类都是一个实体Bean,
-
@Table注解:
实体Bean指定对应数据库表,解决数据库表面与实体类不对应的关系
-
@Column注解:
实体类中的属性字段与数据库表中的字段名对应匹配
-
@Transient:
表示该字段不被持久化到数据库
-
@Id注解:
标识该字段是一个主键字段
-
@GeneratedValue注解:
组建的生成策略,其中的策略和之前介绍的一样,使用GenerationType
生成
【核心配置文件hibernate.cfg.xml】
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!--连接数据库的相关参数-->
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_db?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property>
<!-- DB 方言 -->
<property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
<!--hibernate扩展参数-->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<!--<property name="hibernate.hbm2ddl.auto">create</property><!–每次操作Hibernate都是创建一个新的–>-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!--让Session管理ThreadLocal-->
<property name="current_session_context_class">thread</property>
<!--使用注解的 配置-->
<mapping class="com.wei.domain.Customer"/>
</session-factory>
</hibernate-configuration>
注意事项:由于使用了JPA注解开发,省去了原有的实体映射配置文件,所以这里的mapping采用calss的配置方式
【测试代码】
@Test
public void test1() throws HibernateException {
Customer customer = new Customer();
// customer.setId(1);
customer.setName("里斯");
customer.setGender("女");
Session session = HibernateUtil.getConnection();
//4、开启事务
Transaction tx = session.beginTransaction();
//5、执行添加操作
session.save(customer);
//6、提交事务
tx.commit();
//7、关闭资源
HibernateUtil.closeSession(session);
}
三、@Transient注解
@Transient:以为临时的意思,也就是被@Transient注解注释的属性,它默认是不被反应到数据库上的
// 临时字段 不反应到数据库中
@Transient
private boolean isMarried;
使用该注解在添加的时候不会往数据库中添加新建此字段
四、JPA主键策略
JPA主键策略,没有Hibernate主键策略丰富
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
常见的主键策略:
- TABLE:利用JPA生成表维护主键值
- SEQUENCE:使用序列的自增长 Oracle
- IDENTITY:数据库的自增长能力,MySQL
- AUTO:自动匹配数据库源来实现自动配置主键自增策略
说明:使用Table的主键策略后,Hibernate会自动生成一个hibernate_sequences的表,通过模拟Oracle的序列来实现主键自增。
五、JPA的关系映射
5.1 一对多映射
【Customer实体类】—一方
@Entity
@Table(name = "t_customer_jpa")
public class Customer implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@Column(name = "name")
private String name;
@Column(name = "gender")
private String gender;
// 关联订单
@OneToMany(targetEntity = Order.class,mappedBy = "customer")
private Set<Order> orders = new HashSet<Order>();
// getter、setter...
}
【Order实体类】— 多方
@Entity
@Table(name = "t_order_jpa")
public class Order implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@Column(name = "order_no")
private String orderNo;
// 关连客户
@ManyToOne(targetEntity = Customer.class)
@JoinColumn(name = "cust_id")
private Customer customer;
// getter、setter...
}
说明:
- 在一方使用注解@OneToMany表示target的关联实体类为
Order.class
,使用mapperBy标识被关联实体类中的关联字段customer
;
- 在多方使用注解@ManyToOne标识一方的关联实体类,并使用
@JoinColumn
注解标识数据库中所关联表的的字段名为cust_id
5.1.1 测试
/**
* 演示一对多的测试
* @throws HibernateException
*/
@Test
public void test2() throws HibernateException {
Customer customer = new Customer();
customer.setName("JACK");
customer.setGender("男");
Order o1 = new Order();
o1.setOrderNo("2022081100001");
o1.setCustomer(customer);
Order o2 = new Order();
o2.setOrderNo("2022081100002");
o2.setCustomer(customer);
Session session = HibernateUtil.getConnection();
//4、开启事务
Transaction tx = session.beginTransaction();
//5、执行添加操作
session.save(customer);
session.save(o1);
session.save(o2);
//6、提交事务
tx.commit();
//7、关闭资源
HibernateUtil.closeSession(session);
}
5.2 多对多映射
【User实体类】
@Entity
@Table(name = "t_user_jpa")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@Column(name = "name")
private String userName;
/*
* joinColumns表是当前方在中间表的列名
* inverseJoinColumns表示对方表在中间表的列名
* name表示表名
* */
@ManyToMany(targetEntity = Role.class)
@JoinTable(name = "t_user_role_jpa",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id"))
Set<Role> roles = new HashSet<Role>();
}
【Role实体类】
@Entity
@Table(name = "t_role_jpa")
public class Role implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@Column(name = "name")
private String roleName;
@ManyToMany(targetEntity = User.class,mappedBy = "roles")
Set<User> users = new HashSet<User>();
}