转自:https://blog.youkuaiyun.com/wangchuanqi1234/article/details/51131285
https://blog.youkuaiyun.com/ly_rose/article/details/52328287
一、hibernate.cfg.xml
<?xml version="1.0" encoding="GBK"?>
<!-- 指定Hibernate配置文件的DTD信息 -->
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<!-- hibernate- configuration是连接配置文件的根元素 -->
<hibernate-configuration>
<session-factory>
<!-- oracle.jdbc.driver.OracleDriver -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- jdbc:oracle:thin:@172.0.0.1:1521:数据库名 或 ...oci... -->
<!-- mysql为172.0.0.1:3306时可以写成jdbc:mysql:///数据库名?... -->
<property name="hibernate.connection.url">jdbc:mysql://172.0.0.1:3306/数据库名?useUnicode=true&characterEncoding=utf8</property>
<!-- 用户名 -->
<property name="hibernate.connection.username">root</property>
<!-- 密码 -->
<property name="hibernate.connection.password">32147</property>
<!-- 连接池里最大连接数 -->
<property name="hibernate.c3p0.max_size">20</property>
<!-- 连接池里最小连接数 -->
<property name="hibernate.c3p0.min_size">1</property>
<!-- 指定连接池里连接的超时时长 -->
<property name="hibernate.c3p0.timeout">5000</property>
<!-- 指定连接池里最大缓存多少个Statement对象 -->
<property name="hibernate.c3p0.max_statements">100</property>
<property name="hibernate.c3p0.idle_test_period">3000</property>
<property name="hibernate.c3p0.acquire_increment">2</property>
<property name="hibernate.c3p0.validate">true</property>
<!-- 数据库方言 org.hibernate.dialect.OracleDialect -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
<!-- 根据需要自动创建数据表 -->
<property name="hibernate.hbm2ddl.auto">update/create-drop/create</property>
<!-- 显示Hibernate持久化操作所生成的SQL -->
<property name="hibernate.show_sql">true</property>
<!-- 将SQL脚本进行格式化后再输出 -->
<property name="hibernate.format_sql">true</property>
<property name="hibernate.cache.use_query_cache">true</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<!-- 罗列所有的映射文件 -->
<mapping resource="映射文件路径/News.hbm.xml"/>
</session-factory>
</hibernate-configuration>
二、hibernate.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://127.0.0.1/datdabseName
#用户名
hibernate.connection.username root
#密码
hibernate.connection.password 12345
#是否在控制台输出sql语句
hibernate.show_sql true/false
#设置当创建sessionfactory时,是否根据映射文件自动建立数据库表。 create-drop:表示关闭sessionFactory时,将drop刚建的数据库表。该属性可以是update/create-drop/create
hibernate.hbm2ddl.auto update/create-drop/create
###########################
### C3P0 Connection Pool C3P0连接池###
###########################
#连接池最大链接数
hibernate.c3p0.max_size 2
#连接池最小连接数
hibernate.c3p0.min_size 2
#连接池连接的超时时长
hibernate.c3p0.timeout 5000
#缓存statements 的数量
hibernate.c3p0.max_statements 100
hibernate.c3p0.idle_test_period 3000
hibernate.c3p0.acquire_increment 2
hibernate.c3p0.validate true/false
############
### JNDI (java naming directory interface)Java命名目录接口###
###当无需hibernate自己管理数据源而是直接访问容器管理数据源 使用JNDI
############
#指定数据源JNDI名字
hibernate.connection.datasource dddd
#文件系统下
hibernate.jndi.class com.sun.jndi.fscontext.RefFSContextFactory
hibernate.jndi.url file:/
#网络
#指定JND InitialContextFactory 的实现类,该属性也是可选的。如果JNDI与Hibernate持久化访问的代码处于同一个应用,无需指定该属性
hibernate.jndi.class com.ibm.websphere.naming.WsnInitialContextFactory
#指定JNDI提供者的URL,该属性可选 如果JNDI与Hibernate持久化访问的代码处于同一个应用,无需指定该属性
hibernate.jndi.url iiop://localhost:900/
#指定链接数据库用户名
hibernate.connection.username root
#指定密码
hibernate.connection.password 1111
#指定方言
hibernate.dialect org.hibernate.dialect.MySQLDialect
#######################
### Transaction API 事务属性说明###
#######################
#指定是否在事务结束后自动关闭session
hibernate.transaction.auto_close_session true/false
#指定session是否在事务完成后自动将数据刷新到底层数据库
hibernate.transaction.flush_before_completion true/false
## 指定hibernate所有的事务工厂的类型,该属性必须是TransactionFactory的直接或间接子类
hibernate.transaction.factory_class org.hibernate.transaction.JTATransactionFactory
hibernate.transaction.factory_class org.hibernate.transaction.JDBCTransactionFactory
## 该属性值是一个JNDI名,hibernate将使用JTATTransactionFactory从应用服务器中取出JTAYserTransaction
jta.UserTransaction jta/usertransaction
jta.UserTransaction javax.transaction.UserTransaction
jta.UserTransaction UserTransaction
## 该属性值为一个transactionManagerLookup类名,当使用JVM级别的缓存时,或在JTA环境中使用hilo生成器策略时,需要该类
hibernate.transaction.manager_lookup_class org.hibernate.transaction.JBossTransactionManagerLookup
hibernate.transaction.manager_lookup_class org.hibernate.transaction.WeblogicTransactionManagerLookup
hibernate.transaction.manager_lookup_class org.hibernate.transaction.WebSphereTransactionManagerLookup
hibernate.transaction.manager_lookup_class org.hibernate.transaction.OrionTransactionManagerLookup
hibernate.transaction.manager_lookup_class org.hibernate.transaction.ResinTransactionManagerLookup
三、映射文件详解
<?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">
<!--
统一属性 id, code, name, version, startLifecycle, endLifecycle, description, serialNumber
student one to many
-->
<!--
<hibernate-mapping>一般不去配置,采用默认即可。
schema="":指定映射数据库的schema(模式/数据库),如果指定该属性,则表名会自动添加该schema前缀
package="":指定包前缀 指定持久化类所在的包名 这样之后calss子元素中就不必使用全限定性的类名
catalog="":指定数据库catalog的名称
default-cascade="none":默认的级联风格,表与表联动。
default-lazy="true":默认延迟加载
default-access="property" Hibernate通过getter和setter读取(默认) --访问属性的策略--
field Hibernate直接读取类中的字段值
ClassName 使用实现了org.hibernate.property.PropertyAccessor接口的类的具体策略来访问字段属性
auto-import="true" 指定我们是否可以在查询语言中使用非全限定的类名(不带报名的类名),默认为true,如果项目中有两个同名的持久化类,则最好在这两个类的对应的映射文件中配置为false
-->
<hibernate-mapping default-access="field">
<!--
<class>:使用class元素定义一个持久化类。
name="cn.javass.user.vo.UserModel":持久化类的java全限定名;
table="tbl_user":对应数据库表名,默认持久化类名作为表名;
abstract="true":用于在<union-subclass>/<subclass>的继承结构(hierarchies)中标识抽象超类
batch-size="":指定一个用于根据标识符(identifier)抓取实例时使用的'batch size'(批次抓取数量)
catalog="":指定数据库catalog的名称
schema="":指定数据库schema的名称
check="":这是一个SQL表达式,用于为自动生成的schema添加多行(multi-row)约束检查
discriminator-value="":默认和类名一样,一个用于区分不同的子类的值,在多态行为时使用
entity-name=""
lazy="true":延迟加载
mutable="true":表明该类的实例是可变的或者是不可变的
node=""
persister="":指定一个定制的ClassPersister
polymorphism="implicit/explicit":多态,界定是隐式还是显式的多态查询
rowid=""
subselect=""
where="":指定定个附加的SQLWHERE条件,在抓取这个类的对象时会增加这个条件
proxy="":指定一个接口,在延迟装载时作为代理使用,也可在这里指定该类自己的名字。
mutable="true":默认为true,设置为false时则不可以被应用程序更新或删除,等价于所有<property>元素的update属性为false,表示整个实例不能被更新。
dynamic-insert="false":默认为false,SQL将会在运行时动态生成,并且只更新那些改变过的字段
dynamic-update="false":默认为false,SQL将会在执行时动态生成,并且只包含那些非空值字段
select-before-update="false":默认为false,在修改之前先做一次查询,与用户的值进行对比,有变化才会真正更新;
optimistic-lock="version":默认为version,检查version/timestamp字段 --此参数主要用来处理并发,每条值都有固定且唯一的版本,版本为最新时才能执行操作--
all:检查全部字段
dirty:只检查修改过的字段
none:不使用乐观锁定
如果需要采用继承映射,则class元素下还会增加<subclass.../>元素等用于定义子类。
-->
<class name="cn.javass.user.vo.StudentModel" table="student" abstract="true">
<!--
<id>:定义了该属性到数据库表主键字段的映射。
type="long" 指定该标识属性的数据类型,该类型可以是Hibernate的内建类型,也可以是java类型,如果是java类型则需要使用全限定类名(带包名)。该属性可选,如果没有指定类型, 则hibernate自行判断该标识属性数据类型。通常建议设定。
name="userId":标识属性的名字;
column="userId":表主键字段的名字,如果不填写与name一样;
access="":访问属性值的策略
length=""
node=""
unsaved-value="":用来标志该实例是刚刚创建的,尚未保存。可以用来区分对象的状态
-->
<id name="studentId">
<!--
<generator>:指定主键由什么生成,推荐使用uuid,assigned指用户手工填入。设定标识符生成器
class="increment":有Hibernat自动以递增的方式生成标识符,每次增量1;
identity:由底层数据库生成标识符,前提条件是底层数据库支持自动增长字段类型。(DB2,MYSQL)
uuid:用128位的UUID算法生成字符串类型标识符。
assigned:由java程序负责生成标识符,为了能让java应用程序设置OID,不能把setId()方法设置成private类型。
native:由Hibernate根据底层数据库自行判断采用identity、hilo、sequence其中一种作为主键生成方式。
代理主键:increment,identity,uuid,assigned 自然主键:assigned
其他:hilo,seqhilo,uuid.hex,uuid.string,foregin,select
让应用程序在save()之前为对象分配一个标识符。相当于不指定<generator.../>元素时所采用的默认策略。
应当尽量避免自然主键
-->
<generator class="uuid"/>
</id>
<!--
<version/>:使用版本控制来处理并发,要开启optimistic-lock="version"和dynamic-update="true"。
name="version":持久化类的属性名
column="version":指定持有版本号的字段名;
type="integer"
access=""
generated="never/always"
insert="true"
node=""
unsaved-value="undefined/null/negative"
-->
<version name="version" column="version"/>
<!--
<property>:为类定义一个持久化的javaBean风格的属性。
name="name":标识属性的名字,以小写字母开头;
column="name":表主键字段的名字,如果不填写与name一样;
not-null="true": 使用DDL为该字段添加可否为空的约束
unique="true"
type="string":映射类型的名字
generated="never/insert/always":从不/让数据库执行insert类型触发器/所有
index=""
lazy="false": 默认为false,指定实例变量第一次被访问时,这个属性是否延迟抓取
length=""
node=""
optimistic-lock="true": 指定这个属性在进行更新时是否需要获得乐观锁定(换句话说,它决定这个属性发生脏数据时版本version的值是否增长)
precision=""
scale=""
unique-key=""
update="true":默认为true,表示可以被更新;
insert="true": 默认为true,表示可以被插入;
access="property/field":指定Hibernate访问持久化类属性的方式。默认property。property表示使用setter/getter方式。field表示运用java反射机制直接访问类的属性。
formula="(select。。。。。)":该属性指定一个SQl表达式,指定该属性的值将根据表达式类计算,计算属性没有和它对应的数据列。
formula属性允许包含表达式:sum,average,max函数求值的结果。
例如:formula="(select avg(p.price) from Product P)"
-->
<property name="code" column="code" not-null="true" unique="true"/>
<property name="name" column="name" not-null="true" />
<property name="serialNumber" not-null="true" />
<property name="description" />
<!--
<component>:组件映射,把多个属性打包在一起当一个属性使用,用来把类的粒度变小。
name="lifecycle"
class="com.sysway.common.basetype.TimePeriod"
access=""
insert="true"
lazy="false"
node=""
optimistic-lock="true"
unique="false"
update="true"
-->
<component name="lifecycle" class="com.sysway.common.basetype.TimePeriod">
<property name="start" type="java.util.Calendar" column="startLifecycle" not-null="true" />
<property name="end" type="java.util.Calendar" column="endLifecycle" not-null="true" />
</component>
<!--
<discriminator>:鉴别器,通过此字段区分出是哪个具体实现类 ,abstruct student通过studentType映射出具体的CollegeStudent或其他实现类
-->
<discriminator column="studentType" type="string" force="true" />
<!--
<subclass>:...,CollegeStudent类要继承Student类
-->
<subclass
name="com.sysway.boss.domain.productoffering.CollegeStudent" discriminator-value="CollegeStudent">
<many-to-one name="XXX" column="XXXId" />
</subclass>
<!--
<join>:一个对象映射多个表,该元素必须放在所有<property>之后。
-->
<join table="tbl_test:子表名">
<key column="uuid:子表主键"></key>
<property name="name1:对象属性" column="name:子表字段"></property>
</join>
<!--
<any>:
name=""
id-type=""
access=""
cascade=""
index=""
insert="true"
lazy="false"
meta-type=""
node=""
optimistic-lock="true"
update="true"
-->
<any name="" id-type="">
<column name=""></column>
<meta attribute=""></meta>
<meta-value class="" value=""/>
</any>
<one-to-one name="identityCard" class="com.sysway.boss.domain.customer.IdentityCard" property-ref="student" />
<many-to-one name="class" column="classId" not-null="true" />
<!--
<set>:可以映射类型为java.util.Set接口的属性,它的元素存放没有顺序且不允许重复,也可以映射类型为java.util.SortSet接口的属性,它的元素可以按自然属性排序,也可以用sort属性指定排序规则
-->
<set name="courses" inverse="false" lazy="true" table="studentCourses" order-by="courseid desc">
<!--
<key>: 集合属性都需要保存到另一个数据表中,所以保存集合属性的数据表必须包含一个外键列用于参照到主键列
column="studentId": 指定外键字段的列名
foreign-key="":
not-null="true": 非空约束
on-delete="noaction/cascade": 是否打开级联删除
property-ref="": 指定外键字段是否为原表的主键
unique="true": 是否唯一约束
update="true": 是否可更新
-->
<key column="studentId"/>
<many-to-many class="com.sysway.boss.domain.party.role.Course" column="courseId" />
</set>
<!--
<bag>:可以映射java.util.Collection接口的属性,它的元素可能重复,但不保存属性,和set差不多,正因为有它,是因为如果通常使用list比较多,并且不想让添加一列的话,就用它。
-->
<bag name="XXXlist">
<key column="studentId" />
<one-to-many class="com.sysway.boss.domain.cas.XXX" />
</bag>
<!--
<list>:可以映射类型为java.util.List接口的属性,它需要在结合属性对象的数据库表中用一个额外的索引列保存每一个元素的位置,即是有属性可重复的。
-->
<list name="schools" inverse="false" table="school" lazy="true">
<key>
<column name="studentId"></column>
</key>
<!--
<list-index>: 索引列,除了<set.../>和<bag.../>元素外,都要为集合元素的数据表指定一个索引列——用于保存数组索引
column="schools_order": 列名
-->
<list-index column="schools_order"/>
<!--
<element>:集合元素是基本类型或包装类,字符串类型,日期类型
-->
<element type="java.lang.String">
<column name="school_name" />
</element>
<!--
<composite-element>:集合元素是复合类型的引用(即key为组件,非实体类,就是一个复合类型类)
-->
<composite-element class=""></composite-element>
</list>
<!--
<map>:可以映射为java.util.Map接口的属性,它的元素以键值对的形式保存,也是无序的,也可以映射类型为java.util.SortMap接口的属性,它的元素可以按自然顺序排序,也可以用sort属性指定排序规则
-->
<map name="imageUrls" lazy="false" table="ImageUrls">
<key column="studentId" />
<!-- 以下三个都是Map索引列,运用时只选其一 -->
<!--
<map-key>: 用于映射Map,基本数据类型的索引列
-->
<map-key column="imageType" type="string" />
<!--
<map-key-many-to-many>: 用于Map中实体类型的引用(即key为实体类)
-->
<map-key-many-to-many column="operationRoleId" class="com.sysway.boss.domain.party.role.OperationRole" />
<!--
<composite-map-key>: 用于Map中复合类型的引用(即key为组件,非实体类,就是一个复合类型类)
-->
<composite-map-key class=""></composite-map-key>
<element column="imageUrl" type="string" not-null="true"/>
</map>
<!--
<array>:可以映射类型为数组的属性,但在实际运用中用的极少
-->
<array name=""></array>
<!--
<primitive-array>:可以映射类型为基本数据类型数组的属性,但在实际运用中用的极少
-->
<primitive-array name=""></primitive-array>
<cache usage="read-only"/>
<!--
<composite-id>:如果<id.../>为组件属性,组件类必须重写过equals和hashCode方法,<id.../>元素置换为<composite-id>
或者多列为联合主键,省去name和class属性即可,效果一样
-->
<composite-id name="xxx" class="xxx.xxx.xxx">
<key-property name="xxx"/>
<key-property name="xxx"/>
</composite-id>
<!--
<union-subclass>:和<subclass>类似,各个union-subclass对应数据库不同表,各个subclass对应数据库相同的表
-->
<union-subclass></union-subclass>
<comment></comment>
<dynamic-component name=""></dynamic-component>
<fetch-profile name=""></fetch-profile>
<filter name=""></filter>
<idbag name=""></idbag>
<joined-subclass></joined-subclass>
<loader query-ref=""/>
<meta attribute=""></meta>
<natural-id></natural-id>
<properties name=""></properties>
<query name=""></query>
<resultset name=""></resultset>
<sql-delete></sql-delete>
<sql-insert></sql-insert>
<sql-query name=""></sql-query>
<sql-update></sql-update>
<subselect></subselect>
<synchronize table=""/>
<timestamp name=""></timestamp>
<tuplizer class=""/>
</class>
</hibernate-mapping>
<!--
如果组件属性里还有集合属性,继续A置换
如果组件属性里还有组件属性,继续B置换,<component.../>变成<nested-composite-element.../>
如果集合Map的索引属性为组件属性,继续B置换,<component.../>变成<nested-composite-element.../>,子元素为<key-property.../>或<key-many-to-one.../>
-->