5.0、Hibernate-配置文件详解 1
首先来说一下 hibernate.cfg.xml 全局环境配置,参考配置如下所示->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!--数据源配置-->
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/hibernate?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC</property>
<!-- C3P0 连接池-->
<!-- 每次不够用的时候,自增10个-->
<property name="hibernate.c3p0.acquire_increment">10</property>
<!-- 多少时间之后会自动 -> 释放资源-->
<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>
<!-- sql的最大线程数-->
<property name="hibernate.c3p0.max_statements">10</property>
<!-- 设置数据库方言,现在我们用的是mysql所以设置mysql的方言,这样 hibernate 可以根据 mysql 的语法去生成执行语句-->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 打印SQL语句,方便排查-->
<property name="show_sql">true</property>
<!-- 格式化SQL语句,方便排查-->
<property name="format_sql">true</property>
<!-- 是否自动生成数据表-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 注册实体关系映射文件-->
<mapping resource="com/hkl/pojo/People.hbm.xml"></mapping>
<mapping resource="com/hkl/pojo/Customer.hbm.xml"></mapping>
<mapping resource="com/hkl/pojo/Order.hbm.xml"></mapping>
<mapping resource="com/hkl/pojo/Account.hbm.xml"></mapping>
<mapping resource="com/hkl/pojo/Course.hbm.xml"></mapping>
</session-factory>
</hibernate-configuration>
1、配置数据库的基本信息;
2、集成 C3P0,设置数据库连接池信息;
3、Hibernate 基本信息;
解释一下 hibernate.hbm2ddl.auto 是否自动生成数据库表的一些属性配置 ->
update | 动态创建表,如果表存在,则直接使用,如果不存在则创建 |
create | 无论表是否存在,都会重新创建 |
create-drop | 初始化创建表,程序结束时删除表 |
validate | 校验实体关系映射文件和数据库表是否对应,不能对应直接报错 |
4、注册实体关系映射文件
接着说一下映射文件,参考配置如下所示->
<?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>
<class name="com.hkl.pojo.Customer" table="customer">
<!-- 主键映射,数据库表中的主键字段用 id 配置,而 name = "id" 这个 id 指的是 Customer 实体类中的 id 属性名-->
<id name="id" type="java.lang.Integer">
<!-- 数据库表 id 主键字段配置-->
<column name="id"></column>
<!-- 设置主键自增方式 -> identity-->
<generator class="identity"></generator>
</id>
<property name="name" type="java.lang.String">
<column name="name"></column>
</property>
<!-- orders是实体类Customer中的属性名,该属性是一个Order类的集合,所以对应表 order-->
<set name="orders" table="orders" lazy="extra">
<!-- 这里配置一下主外键 cid -->
<key column="cid"></key>
<!-- 消费者和订单的关系是一对多,所以这里是 one-to-many,然后给set类型加一个对象,对象类型是Order-->
<one-to-many class="com.hkl.pojo.Order"></one-to-many>
</set>
</class>
</hibernate-mapping>
我们可以在 <hibernate-mapping> 标签中添加 package 属性,给 class 节点对应的实体类统一设置包名,此处设置包名,class 的 name 属性就可以省略包名;
schema | 数据库 schema 的名称 |
catalog | 数据库 catalog 的名称 |
default-cascade | 默认的级联关系,默认为 none |
default-access | Hibernate 用来访问属性的策略 |
default-lazy | 指定了未明确注明 lazy 属性的 Java 属性和集合类,Hibernate 会采用什么样的加载风格,默认为 true |
auto-import | 指定我们是否可以在查询语句中使用非全限定类名,默认为 true ,如果项目中有两个同名的持久化类,最好在这两个类的对应映射文件中配置为 false |
Class属性:
name | 实体类名 |
table | 数据表名 |
schema | 数据库 schema 的名称,会覆盖 hibernate-mapping 的 schema |
catalog | 数据库 catalog 的名称,会覆盖 hibernate-mapping 的 catalog |
proxy | 指定一个接口,在延迟加载时作为代理使用 |
dynamic-update:动态更新;【当我们没有开启动态更新的时候,假设我们表中有两个字段 name 和 sex,有一条数据 name = "小澜",sex = "男" ,当我们只修改 sex = "女" 字段的时候,由于我们没有开启动态更新,会导致 hibernate 执行的 sql 的语句中出现 name = "小澜",sex = "女",就是两个字段都会去修改一遍,这样做显然效率会降低;当我们开启动态更新后,当我们只修改一个字段时,hibernate 执行的 sql 语句中就只会出现被修改的那个字段】
dynamic-insert:动态添加;【动态添加和上面的动态更新类似,假设表 table_01 中有两个字段 name 和 sex,当我们没有开启动态添加然后直插入一个 name 字段的数据并不插入 sex 字段数据的时候,hibernate 执行的 sql 语句是 insert into table_01(name,sex) values(小澜,null),而这个 null 本来就是当我们没有插入数据的时候,mysql 会给这个字段一个默认值就是 null ,根本不需要我们手动的去添加 null ;而我们开启动态添加后,执行的 sql 语句就是 insert into table_01(name) values(小澜)】
where:查询时给 SQL 添加 where 条件,代码演示如下所示->
import com.hkl.pojo.People;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;
import java.util.List;
public class Test8 {
public static void main(String[] args) {
// 创建configuration
Configuration configuration = new Configuration().configure();
// 获取sessionFactory
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 获取Session
Session session = sessionFactory.openSession();
String hql = "from People";
Query query = session.createQuery(hql);
List<People> list = query.list();
for(People people:list) {
System.out.println(people);
}
session.beginTransaction().commit();
session.close();
}
}
执行这段测试代码,可以查询出 people 表中所有的数据,但是在映射文件中加上where 属性就可以查询出指定的数据,如下面映射文件中部分代码所示->
<class name="com.hkl.pojo.People" table="people" where="id = 6">
在映射文件中加上 where = "id = 6" 之后再次运行,就只会查询出 id = 6 的这一条数据了;
id属性
name | 实体类属性名 |
type | 实体类属性数据类型 |
此处可以设置两种类型的数据:Java 数据类型或者 hibernate 映射类型;
实体类的属性数据类型必须与数据表对应的字段数据类型一致;
Java 数据类型映射到 hibernate 映射类型,再由 hibernate 映射类型映射到 SQL 数据类型 Java ---> hibernate ---> SQL
colunm:数据库表的主键字段名
generator:主键生成策略有以下几种可以选择的值 ->
Hilo 算法 |
increment:hibernate 自增 |
identity:数据库自增 |
native:本地策略,根据底层数据库自动选择主键的生成策略; |
uuid.hex 算法 |
select 算法 |
property属性
name | 实体类属性名 |
column | 数据库表字段名 |
type | 数据类型 |
update | 该字段是否可以修改,默认为 true |
insert | 该字段是否可以添加,默认为 true |
lazy | 延迟加载策略 |
inverse属性
inverse 属性是用来设置是否将维护权交给对方,默认是 false ,不交出维护权,双方都在维护,将他设置为 true ,表示 Customer 放弃维护;
级联删除操作
实现方法一 -> 先将从表中对应数据删除再去删除主表中的数据;
实现方法二 -> 实体关系映射文件中设置 cascade 值完成级联删除;-> cascade = "delete"