文章目录
- 简介
- 配置文件
- hibernate.cfg.xml
- 映射配置文件
- 主键生成方式
- 主键生成方式的配置
- identity
- sequence
- native
- increment
- assigned
- 映射类型
- 使用 Hibernate 实现 CRUD
简介
Hibernate是对象关系映射(ORM,Object RelationShip Mapping)框架,Hibernate 用于系统中的封装数据访问层,我们称之为数据访问层框架(或叫持久层框架)。
这个框架会自动将数据库查询出来的数据行封装成所映射的Java类对象,也会将Java类对象中的数据根据所映射的数据表拼接成SQL语句,从而可以很便捷地存储数据、更新数据、删除数据。
实际上 Hibernate 的底层是调用 JDBC 有关 API 来访问数据库的。只是先将访问数据库的参数、数据库配置参数以及 Java 类与数据表的对应关系等全部记录在 xml 文件中,然后再调用 Hibernate 有关 API 去解析这些配置文件,从而实现数据库的访问以及数据的自动封装。
配置文件
关于配置文件的详解参考这些文章:
1.http://t.zoukankan.com/rodge-run-p-6415552.html
2.https://blog.csdn.net/qq_45874814/article/details/121461885
3.https://blog.csdn.net/weixin_44048823/article/details/106762026
4.https://www.cnblogs.com/rodge-run/p/6415552.html
5.https://blog.csdn.net/qq_34598667/article/details/86496008
hibernate.cfg.xml
这个 Hibernate 的核心配置文件,主要配置数据库的连接参数以及数据库运行时的一些参数,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration><session-factory><!--第一部分: 配置数据库信息,必须有,这里使用的是postgre数据库 --><property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property><property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property><property name="hibernate.connection.username">root</property><property name="hibernate.connection.password">lwx83129</property><!--第二部分: 配置hibernate信息, 输出数据库SQL语句,可选 --><property name="hibernate.show_sql">true</property><property name="hibernate.format_sql">true</property><!-- 自动创建表和更新 --><property name="hibernate.hbm2ddl.auto">update</property><!-- 配置方言 --><property name="hibernate.dialec">org.hibernate.dialect.MySQLDialect</property><!-- 配置threadLocal --><property name="hibernate.current_session_context_class">thread</property><!--第三部分: 核心配置文件关联映射文件 --><mapping resource="User.hbm.xml"/></session-factory>
</hibernate-configuration>
映射配置文件
这个配置文件主要就是配置Java 实体类与数据表的对应关系,配置文件的命名规则为:类名.hbm.xml,例如:User.hbm.xml。配置内容如下所示:
<?xml version="1.0"?>
<!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="priv.lwx.hibernate.basic.entity.User" table="user"><!--id是实体类中的与对应数据表中作为主键的列相对应的属性--><id name="id" type="java.lang.Integer"><!--column是对应的数据表中作为主键的列--><column name="id" unique="true"/><generator class="identity"/></id><!--property用来配置类的其它属性与数据表中的列的映射关系--><property generated="never" lazy="false" name="accountName" type="java.lang.String"><column name="account_name"/></property><property generated="never" lazy="false" name="password" type="java.lang.String"><column name="password"/></property><property generated="never" lazy="false" name="realName" type="java.lang.String"><column name="real_name"/></property><property generated="never" lazy="false" name="age" type="java.lang.Integer"><column name="age"/></property><property generated="never" lazy="false" name="gender" type="java.lang.String"><column name="gender"/></property><property generated="never" lazy="false" name="birthday" type="java.util.Date"><column name="birthday"/></property><property generated="never" lazy="false" name="info" type="java.lang.String"><column name="info"/></property></class>
</hibernate-mapping>
主键生成方式
常用的主键生成方式有如下几种:
1)identity
用于自动生成主键方式,除了 Oracle 不支持,其他数据库一般都支持(较常用)
2)sequence
Oracle 中使用,用序列生成主键值
3)native
主键生成方式如果是 native,那就看配置文件 hibernate.cfg.xml 中方言 <property name= "dialect">
是什么,如果方言是 MySQL,相当于 identity,如果方言是 Oracle,相当于 sequence
4)increment
不常用
5)assigned
不常用,手动生成主键 id 的值
主键生成方式的配置
identity
如果数据库支持自动生成主键方式,则可以使用 identity,MySQL 数据库常用此生成方式。
<!--id是实体类中的与对应数据表中作为主键的列相对应的属性-->
<id name="id" type="java.lang.Integer"><!--column是对应的数据表中作为主键的列--><column name="id" unique="true"/><!--主键值的生成方式--><generator class="identity"/>
</id>
sequence
Oracle 数据库常用。
创建表 t_foo 和序列 foo_seq:
SQL> CREATE TABLE t_foo(
2 t_id number(11) NOT NULL,
3 t_value varchar(50) NOT NULL,
4 PRIMARY KEY (t_id));
Table created.SQL> create sequence foo_seg;
Sequence created.
SQL>
修改配置文件 hibernate.cfg.xml,修改为连接 Oracle 数据库:
将表的主键值的生成方法改为 sequence,如下所示:
native
native 根据配置文件中的方言选择是 identity 还是 sequence。
<!-- 用来指明主键的生成方式 -->
<generator class="native"> <param name="sequence">foo_seq</param>
</generator>
如果是 MySQL 数据库,<param name="sequence">foo_seq</param>
是不起作用的,但也不会出错;如果是 Oracle 数据库,<param name="sequence">foo_seq</param>
就会起作用。
increment
不常用,如果主键生成方式为 increment,新建数据库表时不需要写“auto_increment”,插入数据时,同样也不需要指定 ID:
Foo foo = new Foo();
foo.setValue("foo_value1");
session.save(foo);
查看控制台,Hibernate 执行了 2 条 SQL:
increment 生成主键方式是先 “select max(t.id) from t_foo”,从 t_foo 中找到最大的 id,
之后将 max(t_id)
加 1
,这样就保证了主键唯一。但是这样有风险,当并发访问时会有风险。不建议使用。
assigned
不会自动生成主键值,需要用户自己指定,使用也较少。
必须手动设置 ID,如下代码所示:
// 需要指定id
Foo foo = new Foo();
foo.setId(9999);
foo.setValue ("foo_value2");
session.save(foo);
映射类型
参考文章:https://blog.csdn.net/yzy199391/article/details/80536419
使用 Hibernate 实现 CRUD
package priv.lwx.hibernate.basic.entity;import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;
import org.junit.jupiter.api.Test;
import priv.lwx.hibernate.basic.util.HibernateUtils;import java.util.List;/*** CRUD演示** @author liaowenxiong* @date 2022/6/17 07:43*/public class UserTest {/*** 往数据表插入一条记录** @param* @return* @throws* @author liaowenxiong* @date 2022/6/17 09:00*/@Testpublic void test1() {User user = new User();user.setAccountName("liaowenxiong");user.setRealName("廖文雄");user.setPassword("123");// 调用Hibernate的API,用于装载Hibernate配置文件Configuration cfg = new Configuration();// 调用无参的方法configure会默认装载目录classes下的Hibernate配置文件(hibernate.cfg.xml及mapping文件)cfg.configure();SessionFactory factory = cfg.buildSessionFactory();// 通过Session工厂类获取Session对象Session session = factory.openSession();// 通过Session对象获取事务对象Transaction tx = session.getTransaction();// 开启事务tx.begin();// 保存数据session.save(user);// 提交事务tx.commit();// 关闭Sessionsession.close();}/*** 删除数据表中的指定记录** @param* @return* @throws* @author liaowenxiong* @date 2022/6/17 09:33*/@Testpublic void test2() {User user = new User();user.setId(8);// user.setAccountName("liudehua"); // 不会按accountName删除Session session = HibernateUtils.openSession();/*// 获取事务对象Transaction tx = session.getTransaction();// 开启事务tx.begin();*/// 方法beginTransaction会完成上面的两个操作Transaction tx = session.beginTransaction();// 方法delete会获取对象user的属性ID的值,然后自动拼接一条删除的SQL语句,调用JDBC的API// 将SQL语句发送给数据库执行session.delete(user);tx.commit();session.close();}/*** 更新指定的数据行** @param* @return* @throws* @author liaowenxiong* @date 2022/6/17 09:42*/@Testpublic void test3() {User user = new User();user.setId(13);user.setAccountName("liaowenxiong");user.setRealName("雄霸天下");Session session = HibernateUtils.openSession();Transaction tx = session.beginTransaction();session.update(user);tx.commit();session.close();}/*** 查询指定数据表** @param* @return* @throws* @author liaowenxiong* @date 2022/6/17 09:58*/@Testpublic void test4() {Session session = HibernateUtils.openSession();// 方法createQuery并没有调用JDBC访问数据库,只是拼接了一条查询SQL语句而已// User是类名,"from User"是Hibernate提供的面向对象的查询语言:HQL(Hibernate Query Language)语言。Query query = session.createQuery("from User");// 方法list调用JDBC的API访问数据库,再将获取到的数据封装成List对象返回List<User> users = query.list();// 所以这里就可以关闭Session了session.close();for (User user : users) {System.out.println(user);}}
}