1

【笔记】Hibernate学习笔记

 1 year ago
source link: https://loli.fj.cn/2023/02/23/Hibernate%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

【笔记】Hibernate学习笔记

2023-02-23

Hibernate学习笔记

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.3.7.Final</version>
</dependency>

org.hibernate.dialect.MySQLDialectorg.hibernate.dialect.MySQL5Dialectorg.hibernate.dialect.MySQL57Dialect:根据使用的数据库版本进行修改。版本不指定生成的SQL代码量会越多;版本指定越精确生成的SQL代码量越少
com/User.hbm.xml:根据实体类配置子配置文件名。子配置文件与实体类在同级目录下
<property name="hbm2ddl.auto"></property>:配置数据库生成方式

update:表如果存在,就直接插入数据;如果不存在,就创建表
create:每次创建表之前,都会删除原表
create-drop:每次创建表之前,都会删除原表,在关闭会话后,再次删除表
validate:用来验证表结构,如果表不存在或不一致则抛异常

src/main/resources/hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernatr-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
<!-- 初始化数据库连接 -->
<property name="connection.diver_class">com.mysql.jdbc.url</property>
<property name="connection.url">jdbc:mysql:///数据库名</property>
<property name="connection.username">用户名</property>
<property name="connection.password">密码</property>
<!-- 配置方言 -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 配置数据库生成方式 -->
<property name="hbm2ddl.auto">update</property>
<!-- 指定子配置文件 -->
<mapping resource="com/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>

配置读取配置文件

pom.xml

<build>
<resource>
<directory>src/main/recources</directory>
</resource>
<recource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</recource>
</build>

创建子配置文件

class User {
private Integer id;
private String name;

public Integer getId() {
return this.id;
}

public void setId(Integer id) {
this.id = id;
}

public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}
}
  • 创建映射配置文件

<hibernate-mapping></hibernate-mapping>:配置映射关系

package="":指定包名,如果不指定,子配置中出现的类名需要用全局限定名

<class></class>:类与表映射配置

name="":指定类名
table="":指定数据表名

<id>:属性与主键字段映射配置

name="":指定属性名
<generator class="native"/>:主键自增策略

<property/>:属性与字段映射配置

name="":指定属性名
column="":指定字段名,如果属性名与字段名一致,可以省略
type="":指定数据类型,如果属性名与字段名一致,可以省略
length="":指定数据长度,可以省略

src/main/resource/com/pojo/User.hbm.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernatr-configuration-3.0.dtd">

<hibernate-mapping package="com">
<class name="User" table="user">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
</class>
</hibernate-mapping>

单向多对一

class User {
private Integer id;
private String name;
private Grade grade;

public Integer getId() {
return this.id;
}

public void setId(Integer id) {
this.id = id;
}

public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}

public Grade getGrade() {
return this.grade;
}

public void setGrade(Grade grade) {
this.grade = grade;
}
}

class Grade {
private Integer id;
private String name;

public Integer getId() {
return this.id;
}

public void setId(Integer id) {
this.id = id;
}

public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}
}

<many-to-one/>:指定多对一关系

name="":指定属性名
class="":指定类名
column="":指定字段名,如果属性名与字段名一致,可以省略
foreign-key="":指定外键
not-null="true":指定是否为空

src/main/resource/com/pojo/User.hbm.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernatr-configuration-3.0.dtd">

<hibernate-mapping package="com">
<class name="User" table="user">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="grade" class="Grade"/>
</class>
</hibernate-mapping>

src/main/resource/com/pojo/Grade.hbm.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernatr-configuration-3.0.dtd">

<hibernate-mapping package="com">
<class name="User" table="user">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
</class>
</hibernate-mapping>

单向一对多

class User {
private Integer id;
private String name;

public Integer getId() {
return this.id;
}

public void setId(Integer id) {
this.id = id;
}

public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}
}

class Grade {
private Integer id;
private String name;
private Set<User> users;

public Integer getId() {
return this.id;
}

public void setId(Integer id) {
this.id = id;
}

public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}

public Set<User> getUsers() {
return this.users;
}

public void setGrade(Set<User> users) {
this.users = users;
}
}

src/main/resource/com/pojo/User.hbm.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernatr-configuration-3.0.dtd">

<hibernate-mapping package="com">
<class name="User" table="user">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
</class>
</hibernate-mapping>

<set/><set>:指定集合类型

name="":指定集合属性名
<key></key>:指定外键配置

column="":外键列名
foreign-key="":生成的外键约束名,如果省略则随机
not-null="false":是否不允许为空,默认为false

<one-to-many/>:指定一对多关系

class="":指定类名

inverse="":关系维护(只能配置在一的一端,不能配置在多的一端)

false:缺省值,由一的一端维护关系
true:要求多的一端维护关系,一的一端所维护的关系将失效

src/main/resource/com/pojo/Grade.hbm.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernatr-configuration-3.0.dtd">

<hibernate-mapping package="com">
<class name="User" table="user">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="users">
<key column="user_id"></key>
<one-to-many class="User"/>
</set>
</class>
</hibernate-mapping>

双向一对多

class User {
private Integer id;
private String name;
private Grade grade;

public Integer getId() {
return this.id;
}

public void setId(Integer id) {
this.id = id;
}

public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}

public Grade getGrade() {
return this.grade;
}

public void setGrade(Grade grade) {
this.grade = grade;
}
}

class Grade {
private Integer id;
private String name;
private Set<User> users;

public Integer getId() {
return this.id;
}

public void setId(Integer id) {
this.id = id;
}

public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}

public Set<User> getUsers() {
return this.users;
}

public void setGrade(Set<User> users) {
this.users = users;
}
}

<many-to-one/>:指定集合类型

cascade="":设置级联,单一的数据被增删改时,其相关的所有数据也执行相同的操作

all:全部级联
save-update:级联插入
create:级联创建
delete:级联删除

src/main/resource/com/pojo/User.hbm.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernatr-configuration-3.0.dtd">

<hibernate-mapping package="com">
<class name="User" table="user">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="grade" class="Grade"/>
</class>
</hibernate-mapping>

<set/><set>:指定集合类型

cascade="":设置级联,单一的数据被增删改时,其相关的所有数据也执行相同的操作

all:全部级联
save-update:级联插入
create:级联创建
delete:级联删除

src/main/resource/com/pojo/Grade.hbm.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernatr-configuration-3.0.dtd">

<hibernate-mapping package="com">
<class name="User" table="user">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="users">
<key column="user_id"></key>
<one-to-many class="User"/>
</set>
</class>
</hibernate-mapping>

通过Hibernate操作数据库

  • Hibernate5.x的写法

<filename>:配置文件名,如果省略则默认加载hibernate.cfg.xml配置文件

Transaction transaction = null;
try {
// 创建注册服务对象
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure("<filename>").build();
// 从元信息获取会话工厂对象
SessionFactory sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
// 开启事务
transaction = session.beginTransaction();

/* 操作数据库 */

// 提交事务
transcation.commit();
// 关闭会话
session.close();
} catch (Exception e) {
e.printStackTrace();
session.rollback();
} finally {
if (session != null && session.isOpen())
session.close();
}
  • 先查询缓存,如果缓存没有,再查询数据库
User user = session.get(User.class, <num>);
  • 执行load()后不会立即加载,只有当对象需要使用时,才会执行查询操作
User user = session.load(User.class, <num>);
User user = new User();
session.save(user);

清除全部缓存

session.clear();

清除指定缓存

session.evict(user);

封装工具类

public class HibernateUtil {
private static ThreadLocal<Session> threadLocal = new ThreadLocal<>();
private static StandardServiceRegistry registry;
private static SessionFactory sessionFactory;

// 初始化会话工厂
static {
registry = new StandardServiceRegistryBuilder().configure().build();
sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
}

// 获取会话对象
public static Session getSession() {
Session session = threadLocal.get();
if (null != session || !session.isOpen()) {
if (null != sessionFactory)
buildSessionFactory();
session = (null != sessionFactory) ? sessionFactory.openSession() : null;
threadLocal.set(session);
}
return session;
}

// 加载会话工厂
private static void buildSessionFactory() {
registry = new StandardServiceRegistryBuilder().configure().build();
sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
}

// 关闭会话
public static void closeSession() {
Session session = threadLocal.get();
threadLocal.set(null);
if (null != session && session.isOpen())
session.close();
}
}

使用工具类

  • 先查询,后新增/修改/删除
  • 查询不需要开启事务
Session session = null;
Transaction transaction = null;
try {
session = HibernateUtil.getSession();
transaction = session.beginTransaction();

/* 操作数据库 */

transaction.commit();
} catch (Exception e) {
e.printStackTrace();
transaction.rollback();
} finally {
HibernateUtil.closeSession();
}

对象生命周期

  • 瞬时状态:刚刚使用new语句创建,还没有被持久化。Session中没有,数据库中也没有
  • 持久化状态:已经被持久化,加入到Session的缓存中。Session中有,数据库中也有
  • 游离状态:已经被持久化,但是不处于Session的缓存中。Session中没有,数据库中有

哔哩哔哩——bili_206563379


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK