重量级ORM框架--持久化框架Hibernate【JPA注解开发】

时间:2022-09-30 11:00:01


hibernate

​ Hibernate是一款重量级的持久层框架,目前市面上的我很少见还有项目在开发时候使用他,之所以要学习这个,因为公司最近有一个系统升级的项目,之前的老系统用到了Hibernate。​

重量级ORM框架--持久化框架Hibernate【JPA注解开发】

同样还是老套路,学习一个新技术或者新知识,首先去他的官网看

【官网】:​​https://hibernate.org/orm/​​​ 【官方教程】:h​​ttps://hibernate.org/orm/documentation/getting-started/​​ 【github地址】:​​https://github.com/hibernate​


目前hibernate已经更新到了6的版本,这里使用的5的版本

重量级ORM框架--持久化框架Hibernate【JPA注解开发】

注意: Hibernate5.1;5.2官方推荐使用JDK1.8以及JDBC4

文章目录


一、Hibernate与JPA的关系

重量级ORM框架--持久化框架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);
}

重量级ORM框架--持久化框架Hibernate【JPA注解开发】

三、@Transient注解

@Transient:以为临时的意思,也就是被@Transient注解注释的属性,它默认是不被反应到数据库上的

// 临时字段 不反应到数据库中
@Transient
private boolean isMarried;

使用该注解在添加的时候不会往数据库中添加新建此字段

四、JPA主键策略

JPA主键策略,没有Hibernate主键策略丰富

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

常见的主键策略:

  1. TABLE:利用JPA生成表维护主键值
  2. SEQUENCE:使用序列的自增长 Oracle
  3. IDENTITY:数据库的自增长能力,MySQL
  4. 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);
}

重量级ORM框架--持久化框架Hibernate【JPA注解开发】


重量级ORM框架--持久化框架Hibernate【JPA注解开发】

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>();
}