主配置文件
Hibernate.cfg.xml:主配置文件中主要配置:数据库连接信息、其它参数、映射信息!
常用配置查看源码:hibernate-distribution-3.6.0.Finalprojectetchibernate.properties
数据库连接参数配置
例如:MySQL
#hibernate.dialect org.hibernate.dialect.MySQLDialect
#hibernate.dialect org.hibernate.dialect.MySQLInnoDBDialect
#hibernate.dialect org.hibernate.dialect.MySQLMyISAMDialect
#hibernate.connection.driver_class com.mysql.jdbc.Driver
#hibernate.connection.url jdbc:mysql:///test
#hibernate.connection.username gavin
#hibernate.connection.password
自动建表
#hibernate.hbm2ddl.auto create-drop //每次在创建sessionFactory时候执行创建表;当调用sessionFactory的close方法的时候,删除表!
#hibernate.hbm2ddl.auto create //每次都重新建表;如果表已经存在就先删除再创建
#hibernate.hbm2ddl.auto update ///如果表不存在就创建,表存在就不创建
#hibernate.hbm2ddl.auto validate //生产环境时候执行验证,当映射文件的内容与数据库表结构不一样的时候就报错!
代码自动建表
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.Test;
public class App_dll {
@Test
public void testCreate() {
//创建配置管理类对象
Configuration configuration = new Configuration();
//加载主配置文件
configuration.configure();
//创建工具类对象
SchemaExport export = new SchemaExport(configuration);
//建表
//第一个参数:是否在控制台打印建表语句
//第二个参数:是否执行脚本
export.create(true, true);
}
}
hibernate.cfg.xml
<!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节点代表一个数据库 -->
<session-factory>
<!-- 1. 数据库连接配置 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- 防止出现插入MySQL数据库中文乱码,加上useUnicode=true&characterEncoding=utf8 -->
<property name="hibernate.connection.url">
<![CDATA[jdbc:mysql:///hib_demo?useUnicode=true&characterEncoding=utf8]]>
</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123</property>
<!--
数据库方法配置, hibernate在运行的时候,会根据不同的方言生成符合当前数据库语法的sql
-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- 2. 其他相关配置 -->
<!-- 2.1 显示hibernate在运行时候执行的sql语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 2.2 格式化sql -->
<property name="hibernate.format_sql">true</property>
<!-- 2.3 自动建表 -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 3. 加载所有映射-->
<mapping resource="com/yly/a_hello/Employee.hbm.xml"/>
</session-factory>
</hibernate-configuration>
映射文件配置
单一主键映射
<?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">
<!-- 映射文件:映射一个实体类对象;描述一个对象,最终实现可以直接保存对象数据到数据库中. -->
<!-- package:要映射的对象所在的包(可选,如果不指定,下面所有的类都要指定全路径) -->
<!-- auto-import:默认为true,在写hql的时候自动导入包名;如果指定为false,再写hql的时候要写上类的全名 -->
<hibernate-mapping package="com.yly.a_hello" auto-import="true">
<!-- class 映射某一个对象的(一般情况下,一个对象写一个映射文件,即一个class节点)
name:指定要映射的对象类型
table:指定对象对应的表.如果没有指定表名,默认与对象名称一样.
-->
<class name="Employee" table="employee">
<!-- 主键,映射 -->
<id name="empId" column="id">
<!-- 主键的生成策略
identity:自增长(MySQL,db2)
native:自增长[会根据底层数据库自增长的方式选择identity或sequence],
如果是MySQL数据库,采用的自增长方式是identity;
如果是Oracle数据库,使用sequence序列的方式实现自增长
sequence:自增长(序列),Oracle中自增长是以序列方法实现
increment:自增长(会有并发访问的问题,一般在服务器集群环境使用会存在问题.)
assigned:指定主键生成策略为手动指定主键的值
uuid:指定uuid随机生成的唯一的值
foreign:(外键的方式)
-->
<generator class="increment"/>
</id>
<!--
普通字段映射
property
name 指定对象的属性名称
column 指定对象属性对应的表的字段名称,如果不写默认与对象属性一致
length 指定字符的长度,默认为255
type 指定表的字段的类型,如果不指定会匹配属性的类型
Java类型:必须写全名
hibernate类型:直接写类型,都是小写
-->
<!-- 如果列名称为数据库关键字,需要用反引号``或改列名 -->
<property name="empName" column="empName" length="20" type="string"/>
<property name="workDate" column="workDate"/>
</class>
</hibernate-mapping>
多个主键映射
<?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 package="com.yly.c_compositekey" auto-import="true">
<class name="User" table="user">
<composite-id name="keys">
<key-property name="username" column="username" type="java.lang.String"></key-property>
<key-property name="address" column="address" type="java.lang.String"></key-property>
</composite-id>
<property name="age" column="age" type="java.lang.Integer"></property>
</class>
</hibernate-mapping>
集合映射
<?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 package="com.yly.a_collection" auto-import="true">
<class name="com.yly.a_collection.User" table="t_user">
<id name="userId" column="id">
<generator class="native"/>
</id>
<property name="name" column="name" length="20" type="string"/>
<!--
set集合属性的映射
name 指定要映射的set集合的属性
table 集合属性要映射到的表
key 指定集合表(t_address)的外键字段
element 指定集合表的其它字段 type元素类型一定要指定
-->
<set name="address" table="t_address">
<key column="uid"></key>
<element column="address" type="java.lang.String"></element>
</set>
<!--
List集合映射,数组和List一样
list-index 指定的是排序列的名称(因为要保证list集合的有序)
-->
<list name="addressList" table="t_addressList">
<key column="uid"></key>
<list-index column="idx"></list-index>
<element column="address" type="java.lang.String"></element>
</list>
<!--
map集合的映射
key 指定外键字段
map-key 指定map的key
element 指定map的value
-->
<map name="addressMap" table="t_addressMap">
<key column="uid"></key>
<map-key column="shortName" type="java.lang.String"></map-key>
<element column="address" type="java.lang.String"></element>
</map>
</class>
</hibernate-mapping>
关联映射
一对多(如一个部门对应多个员工)
<?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 package="com.yly.one2many" auto-import="true">
<class name="Dept" table="t_dept">
<id name="deptId" column="deptId">
<generator class="native"/>
</id>
<property name="deptName" column="deptName" length="20" type="string"/>
<!-- 一对多关联映射配置(通过部门管理到员工) -->
<set name="emps" table="t_employee">
<key column="deptId"></key>
<one-to-many class="Employee"></one-to-many>
</set>
</class>
</hibernate-mapping>
多对一(如:多个员工对应一个部门)
<?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 package="com.yly.one2many" auto-import="true">
<class name="Employee" table="t_employee">
<id name="empId" column="empId">
<generator class="native"/>
</id>
<property name="empName" column="empName" length="20" type="string"/>
<property name="salary" column="salary" type="java.lang.Double"/>
<!-- 多对一映射配置 -->
<many-to-one name="dept" class="Dept" column="deptId"></many-to-one>
</class>
</hibernate-mapping>
总结:在一对多与多对一的关联关系中,保存数据最好的通过多的一方来维护关系,这样可以减少update语句的生成,从而提高hibernate的执行效率!
inverse属性
inverse属性,是在维护关联关系的时候起作用的。表示控制权是否转移。(在一的一方起作用)
inverse = false 不反转
inverse = true 控制反转,当前方没有控制权
维护关联关系中,设置inverse属性:
1.保存数据有影响。如果设置控制反转,即inverse=true,然后通过部门方维护关联关系。在保存部门的时候,同时保存员工,数据会保存,但关联关系不会维护。即外键字段为null。
2.获取数据没有影响。
3.解除关联关系有影响。inverse=false可以解除关联;inverse=true当前方(部门)没有控制权,不能解除关联关系(不会生成update语句,也不会报错)
4.删除数据对关联关系有影响。inverse=false,有控制权,可以删除。先清空外键引用,再删除数据。inverse=true,没有控制权:如果删除的记录有被外键引用,会报错,违反主外键引用约束!如果删除的记录没有被引用,可以直接删除。
cascade属性
cascade表示级联操作【可以设置到一的一方或多的一方】
none:不级联操作,默认值
save-update:级联保存或更新
delete:级联删除
save-update,delete:级联保存、更新、删除
all:同上。级联保存、更新、删除
多对多映射
Developer.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 package="com.yly.many2many" auto-import="true">
<class name="Developer" table="t_developer">
<id name="d_id" column="d_id">
<generator class="native"/>
</id>
<property name="d_name" column="d_name" length="20" type="string"/>
<!-- 多对多关联映射配置 -->
<set name="projects" table="t_relation">
<key column="did"></key>
<many-to-many column="prjId" class="Project"></many-to-many>
</set>
</class>
</hibernate-mapping>
Project.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 package="com.yly.many2many" auto-import="true">
<class name="Project" table="t_project">
<id name="prj_id" column="prj_id">
<generator class="native"/>
</id>
<property name="prj_name" column="prj_name" length="20" type="string"/>
<!-- 多对多关联映射配置 -->
<set name="devs" table="t_relation">
<key column="prjId"></key>
<many-to-many column="did" class="Developer"></many-to-many>
</set>
</class>
</hibernate-mapping>
多对多维护关联关系
设置inverse属性,在多对多中维护关联关系的影响?
保存数据有影响。inverse=false,有控制权,可以维护关联关系;保存数据的时候会把对象关系插入中间表;inverse=true,没有控制权,不会往中间表插入数据。
获取数据没有影响
解除关系有影响。inverse=false,有控制权,解除关系就是删除中间表的数据。inverse=true,没有控制权,不能解除关系。
删除数据有影响。inverse=false,有控制权。先删除中间表数据,再删除自身。inverse=true,没有控制权。如果删除的数据有被引用,会报错!否则,才可以删除。