Hibernate配置文件
添加环境
1.Jar包
2.配置文件hibernate.cfg.xml/xxx.hbm.xml
3.应用hibernate实现增删改查
Configuration cfg = new configuration.config();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Try{
Transaction tx = session.beginTransaction().commit();
}catch(Exception e)
{
Tx.rollback();
}finally{
Session.close();
}
4.办法:save(object) / update(object) / delete(Object) / createQuery(hql) ./ get(class,id)
5.主配置文件:
数据库信息:方言、URL、驱动、用户名、密码
导入映照文件
其他的配置show_sql = true; hbm2ddl.auto = update;
6.映照配置
映照基本:无参的构造办法,get和set办法
映照普通属性name ,type, length , column ,not-null
映照的主键native,assigned,uuid,hilo等等
1 hibernate.cfg.xml
该文件配置了Hibernate须要的数据库的url和账号和密码等等的信息
例如:
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"https://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">mysql</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="connection.pool_size">1</property>
<property name="show_sql">true</property>
<mapping resource="com/shangyanyuan/entity/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
2 配置文件:User.hbm.xml
该文件负责对User进行映照的文件,配置了user的一些属性值和数据库中对应的属性和相应的设置信息,如类型,是不是为空。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"https://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
<class name = "com.shangyanyuan.entity.User" table="user">
<id name = "id" type = "java.lang.Integer" column = "id">
<generator class="increment"></generator>
</id>
<property name="username" type = "java.lang.String" column = "username" length = "20"></property>
<property name="password" type = "java.lang.String" column = "password" length = "20"></property>
</class>
</hibernate-mapping>
Name属性:对象中的属性名,这个必须要有的
Type属性:类型属性,如果不写的话Hibernate会主动的检测其类型
Column属性:对应着数据库当中的某一列。
Length属性:长度。
Not-null属性:非空属性。
如果说你现在设置好了User.hbm.xml这个文件,但是数据库当中没有该数据库,那末由这个配置文件Hibernate会主动的帮你在数据库当中生成该表。
注意:type的值如果大写的话可以这样java.lang.String(java中类型),小写的话string(Hibernate类型)便可。
图象,byte[] 的情势
在配置文件中类型对应着binary类型,最好是指定长度值。
主键:如果是int的话最好是设置为Integer类型,初始值int类型为0,而Integer则为null
3 主键生成策略:
Native 依据数据的性质主动的选择用那个生成策略。
Assigned 手动的指定它的值。应用UUID.randomUUID().toString();手动配置可保证唯一性。
Identity 应用数据库的自己的主键生成策略,但是oracle不支撑。
Sequence oracle中应用这个,也能够db2等等数据库
Hilo 高下位算法来生成主键,只须要一张额外的表,所以的数据库都支撑。
Increment 查询最大的id值然后加1增加,Hibernate赞助增加的,不推举应用,多线程的情形下会有问题的。
Uuid 设定其主键生成策略为uuid便可实现与assigned中应用UUID.randomUUID().toString();的后果。
4 聚集类型的数据的存储
Set 无序 不反复
List 有序 可反复
Map 无序 不反复
有序的聚集没法配置使其排序,但是无序的聚集可以通过配置的方法使其排序但是排序一般不会用到。
比如购物网站用户地址信息
Set聚集 非常主要会经常常使用到
设置有序无序unsorted|natural|comparatorClass默许的方法是unsorted
须要设置的属性是sort属性
order-by属性order-by = “address DESC/ASC(默许是ASC)”
List聚集
List聚集是有次序的所以在映照的时候须要配置这样几个属性:userid, address,idx(索引表现它的次序)
这样设计它的映照文件中应当写为:
<list name = “addressList” table = “user_address”>
<key column = “userid”></key>
<list-index column = “idx”></list-index>
<element type = “string” column = “address”></element>
</list>
数组
<array name = “addressList” table = “user_address”>
<key column = “userid”></key>
<list-index column = “idx”></list-index>
<element type = “string” column = “address”></element>
</array>
Arrays.toString(“”);可查看数组的元素
Map聚集
<map name = “addressMap” table = “user_addressMap”>
<key column = “userid”></key>
<map-key type = “string” column = “key_”></map-key>
<element type = “string” column = “address”></element>
</map>
Hibernate独有的聚集
Bag 无序,可反复
<bag name = “addressbag” table = “user_addressbag”>
<key column = “userid”></key>
<element type = “string” column = “address”></element>
</map>
5:set聚集次序问题
HashSet 无序的
TreeSet 有序,放入数据以后里面的数据是排好了次序的
LinkedHashSet 有序的,依照放入的数据的次序寄存的
6:一对多的关系
外键在多的那一方中
例如员工部门的关系
package cn.itcast.f_hbm_oneToMany;
import java.util.HashSet;
import java.util.Set;
/**
* 部门
*
* @author tyg
*
*/
public class Department {
private Integer id;
private String name;
private Set<Employee> employees = new HashSet<Employee>(); // 关联的很多员工
@Override
public String toString() {
return "[Department: id=" + id + ", name=" + name + "]";
}
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"https://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.itcast.f_hbm_oneToMany">
<class name="Department" table="department">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"/>
<!-- employees属性,Set聚集,表达的是本类与Employee的一对多
class属性:关联的实体类型
key子元素:对方表中的外键列(多方的那个表)
inverse属性:
默以为false,表现本方保护关联关系。
如果为true,表现本方不保护关联关系。
只是影响是不是能设置外键列的值(设成有效值或是null值),对获得信息没有影响。
cascade属性:
默以为none,代表不级联。
级联是指操作主对象时,对关联的对象也做雷同的操作。
可设为:delete, save-update, all, none ...
<set name="employees" cascade="all">
<key column="departmentId"></key>
<one-to-many class="Employee"/>
</set>
-->
</class>
</hibernate-mapping>
================================================================
package cn.itcast.f_hbm_oneToMany;
/**
* 员工
*
* @author tyg
*
*/
public class Employee {
private Integer id;
private String name;
private Department department; // 关联的部门对象
@Override
public String toString() {
return "[Employee: id=" + id + ", name=" + name + "]";
}
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"https://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.itcast.f_hbm_oneToMany">
<class name="Employee" table="employee">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name" type="string" column="name"/>
<!-- department属性,表达的是本类与Department的多对一
class属性:关联的实体类型
column属性:外键列(援用关联对象的表的主键)
-->
<many-to-one name="department" class="Department" column="departmentId"></many-to-one>
</class>
</hibernate-mapping>
测试
package cn.itcast.f_hbm_oneToMany;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
public class App {
private static SessionFactory sessionFactory = new Configuration()//
.configure()//
.addClass(Department.class)// 添加Hibernate实体类(加载对应的映照文件)
.addClass(Employee.class)// 添加Hibernate实体类(加载对应的映照文件)
.buildSessionFactory();
// 保留,有关联关系
@Test
public void testSave() throws Exception {
Session session = sessionFactory.openSession();
session.beginTransaction();
// --------------------------------------------
// 新建对象
Department department = new Department();
department.setName("开发部");
Employee employee1 = new Employee();
employee1.setName("张三");
Employee employee2 = new Employee();
employee2.setName("李四");
// 关联起来
employee1.setDepartment(department);
employee2.setDepartment(department);
department.getEmployees().add(employee1);
department.getEmployees().add(employee2);
// 保留
// session.save(employee1);
// session.save(employee2);
session.save(department); // 保留部门
// --------------------------------------------
session.getTransaction().commit();
session.close();
}
// 获得,可以获得到关联的对方
@Test
public void testGet() throws Exception {
Session session = sessionFactory.openSession();
session.beginTransaction();
// --------------------------------------------
// 获得一方,并显示另外一方信息
Department department = (Department) session.get(Department.class, 1);
System.out.println(department);
System.out.println(department.getEmployees());
// Employee employee = (Employee) session.get(Employee.class, 1);
// System.out.println(employee);
// System.out.println(employee.getDepartment());
// --------------------------------------------
session.getTransaction().commit();
session.close();
}
// 消除关联关系
@Test
public void testRemoveRelation() throws Exception {
Session session = sessionFactory.openSession();
session.beginTransaction();
// --------------------------------------------
// // 从员工方消除
// Employee employee = (Employee) session.get(Employee.class, 1);
// employee.setDepartment(null);
// 从部门方消除(与inverse有关系,为false时可以消除)
Department department = (Department) session.get(Department.class, 1);
department.getEmployees().clear();
// --------------------------------------------
session.getTransaction().commit();
session.close();
}
// 删除对象,对关联对象的影响
@Test
public void testDelete() throws Exception {
Session session = sessionFactory.openSession();
session.beginTransaction();
// --------------------------------------------
// // 删除员工方(多方),对对方没有影响
// Employee employee = (Employee) session.get(Employee.class,2);
// session.delete(employee);
// 删除部门方(一方)
// a, 如果没有关联的员工:能删除。
// b, 如果有关联的员工且inverse=true,由于不能保护关联关系,所以会直接履行删除,就会有异常
// c, 如果有关联的员工且inverse=false,由于可以保护关联关系,他就会先把关联的员工的外键列设为null值,再删除自己。
Department department = (Department) session.get(Department.class, 4);
session.delete(department);
// --------------------------------------------
session.getTransaction().commit();
session.close();
}
}
多对多
对老师的hbm的配置文件应当是:
<!--
Teacher属性,Set聚集
表达的是本类与Teacher的多对多的关系
Table属性:中间表(聚集表)-->必定要一致
Key子元素:聚集外键(援用当前表主键的那个外键)
-->
<set name = “teachers” table = “t_teacher_student”>
<key column = “studentId”></key>
<many-to-many class = “Teacher” column = “teacherId”></many-to-many>
</set>
对学生类的hbm的配置文件应当是:
<set name = “students” table = “t_teacher_student”>
<key column = “teacherId”></key>
<many-to-many class = “Student” column = “studentId”></many-to-many>
</set>
默许的是双方都保护中间表中这个数据库的数据,与inverse有关,inverse = true那末本方不保护。
多对多的时候inverse = false的时候,能保护关联关系,那末先接触关联关系然后再删除。但是inverse = true 的时候,如果本身不保护的话就直接删除但是这样会报错(由于存在着关联关系)。
Cascade属性
级联
默许的是none
操作本对象的时候对与之关联的对象也做雷同的操作
可以设置的值是delete,save-update,all,none
7. Session对象
Session.save(“”);Session.save(“”);
Session.save(“”);Session.save(“”);
只会履行一次insert语句。
session.save(“sdfsdfsdf”);session.flush();立即履行
Session.evict(user);消除某一个指定的对象
一.操作实体对象的
Save(),update(),saveOrUpdate(),delete()
Save()的时候直接就履行而不是等到提交的时候才履行。
二.操作缓存的
Clear(),evict();flush();
三.查询实体对象的
Get();load();createQuery();createCriteria();
Load()不是马上履行,只有在你用的时候才会履行
Hibernate事务隔离级别
<property name = “connnection.isolation”>1(读未提交)/2(读已提交)/4(可反复读)/8(串行化(不可并行))</property>
一对一映照
基于外键的方法:
1. 在person的配置文件中,其配置文件当中没有外键,property-ref属性写的是对方映照中外键列对应的属性名。
采取<one-to-one name = “” column = “”></one-to-one>标签
2.在idcard的配置文件中设置有外键的
<many-to-one name = “” class = “” column = “” > </many-to-many>
注意:从有外键的哪一方消除关系可以的,但是从没有外键的哪一方消除关系是不可以的,只能由有外键的哪一方去消除关联关系。
基于主键的方法:
1. 在Person的配置文件当中
采取<one-to-one name = “idcard” column = “Idcard”></one-to-one>标签
2.在Idcard的配置文件当中
采取:
<one-to-one name = “person” column = “Person” constrained = “true”></one-to-one>标签
注意当应用一对一基于主键方法的时候,有外键方的主键生成策略必定要是foreign
<generator class = “foreign”>
<param name = “property”> person </param>
</generator>
删除时如果是没有外键的那一方(和对方的外键值有关联关系),直接履行删除动作的时候会产生异常,由于和对方的外键值有关联关系,但是如果是对方进行删除的话不会涌现异常。
继承构造的:
1.设计表的时候可以将所有的内容都放在一张表中。不过一行中常常会有多个null的值
配置文件:
<!--
discriminator-value属性:
用于辨别是哪一个类的一个值,表现这个值就是这个类。
如果不写,默以为类的全限定名。
-->
<class name="Article" table="article" discriminator-value="Aticle">
<id name="id">
<generator class="native"/>
</id>
<!-- 用于辨别是甚么类型的一个列 -->
<discriminator type="string" column="class_"></discriminator>
<property name="title"/>
<property name="content" type="text" length="10000"/>
<property name="postTime" type="timestamp"/>
<!-- 子类:Topic -->
<subclass name="Topic" discriminator-value="Topic">
<property name="type"></property>
</subclass>
<!-- 子类:Reply -->
<subclass name="Reply" discriminator-value="Reply">
<property name="floor"></property>
</subclass>
2.
<!-- 采取每一个类一张表的方法,抽象类也对应表。 -->
<class name="Article" table="article2">
<id name="id">
<generator class="native"/>
</id>
<property name="title"/>
<property name="content" type="text" length="10000"/>
<property name="postTime" type="timestamp"/>
<!-- 子类:Topic -->
<joined-subclass name="Topic" table="topic2">
<key column="id"></key>
<property name="type"></property>
</joined-subclass>
<!-- 子类:Reply -->
<joined-subclass name="Reply" table="reply2">
<key column="id"></key>
<property name="floor"></property>
</joined-subclass>
</class>
3.
<!-- 采取每一个具体类一张表的方法,抽象类不对应表。
abstract默以为false,设为true表现本类不对应表(类可以不是abstract的),这时候就会疏忽table属性。
-->
<class name="Article" abstract="false" table="article3">
<id name="id">
<!--
当应用每一个具体类一张表的方法时,主键生成策略不能是identity。
由于在全部继承构造中,主键值是不能反复的。
-->
<generator class="hilo">
<param name="table">hi_value</param>
<param name="column">next_value</param>
<param name="max_lo">100</param>
</generator>
</id>
<property name="title"/>
<property name="content" type="text" length="10000"/>
<property name="postTime" type="timestamp"/>
<!-- 子类:Topic -->
<union-subclass name="Topic" table="topic3">
<property name="type"></property>
</union-subclass>
<!-- 子类:Reply -->
<union-subclass name="Reply" table="reply3">
<property name="floor"></property>
</union-subclass>
</class>
8 HQL语句
Auto-import 表现在HQL语句中写类的简略名称时,是不是主动的导包
QBC方法查询 :Query by Criteria
一对一的只有有外键的那一方能力保护关系。
继承构造的映照
1.所有的数据都放在一张表当中去,固然很多的列会存在=null的情形。
2.每一个类对应着一张表,包含抽象类也有自己的一张表。
3.每一个具体的类都对应着一张表但是抽象类不对应着表。
HQL语句查询的是对象和属性。
症结字不辨别大小写,但是类名和属性名的话辨别大小写。
语法 FROM 实体 AS E
Where / Order by / group by 、having /
Lazy属性
True:第一次的时候加载
False:及时的加载
Extra:加强的懒加载策略。
Hibernate衔接池
应用C3P0衔接池须要导入C3P0的包,只须要在Hibernate的配置文件当中进行设置便可
<!-- C3P0衔接池设定-->
<!-- 应用c3p0衔接池 配置衔接池供给的供给商-->
<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider </property>
<!--在衔接池中可用的数据库衔接的最少数量 -->
<property name="c3p0.min_size">5</property>
<!--在衔接池中所有数据库衔接的最大数量 -->
<property name="c3p0.max_size">20</property>
<!--设定数据库衔接的过期时光,以秒为单位,
如果衔接池中的某个数据库衔接处于空闲状况的时光超过了timeout时光,就会从衔接池中消除 -->
<property name="c3p0.timeout">120</property>
<!--每3000秒检讨所有衔接池中的空闲衔接 以秒为单位-->
<property name="c3p0.idle_test_period">3000</property>
二级缓存:EhCacheProvider(比拟壮大些)(应用之前要导入三个jar包+ehcache.xml(直接拷贝用略微修正便可))
<!-- 应用二级缓存,默许是未打开的。 -->
<!-- 指定要应用的缓存的供给商,这也就打开了二级缓存
<property name="cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
-->
<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<!-- 开启应用查询缓存 -->
<property name="cache.use_query_cache">true</property>
<!-- 指定要应用二级缓存的实体类 -->
<class-cache usage="read-write" class="cn.itcast.l_second_cache.Employee"/>
<class-cache usage="read-write" class="cn.itcast.l_second_cache.Department"/>
<collection-cache usage="read-write" collection="cn.itcast.l_second_cache.Department.employees"/>
<!-- 导入映照文件
<mapping resource="cn/itcast/a_helloworld/User.hbm.xml"/>
-->
HashTable -->线程安全的,但是速度回慢一些
HashMap-->线程不安全的,速度快一些。
getCurrentSession只要是存在Session的时候就不会创立新的Session,当产生提交或回滚后,Hibernate会主动的关闭Session
但是openSession则不一样,每次都是重新创立一个新的Session。
Hibernate配置文件
添加环境
1.Jar包
2.配置文件hibernate.cfg.xml/