Hibernate 1、引入依赖:
2、创建Hibernate配置文件
对于java项目必须放在根目录下 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <?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 >                            <property  name ="hibernate.dialect" > org.hibernate.dialect.MySQLDialect</property >          <property  name ="hibernate.connection.driver_class" > com.mysql.jdbc.Driver</property >          <property  name ="hibernate.connection.url" > jdbc:mysql://localhost:3306/for_test</property >          <property  name ="hibernate.connection.username" > root</property >          <property  name ="hibernate.connection.password" > </property >                   <property  name ="hibernate.show_sql" > true</property >          <property  name ="hibernate.format_sql" > true</property >                   <mapping  resource ="com/bean/Customer.xml" />               </session-factory >  </hibernate-configuration > 
3、创建HibernateUtil工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package  com.util;import  org.hibernate.Session;import  org.hibernate.SessionFactory;import  org.hibernate.boot.MetadataSources;import  org.hibernate.boot.registry.StandardServiceRegistry;import  org.hibernate.boot.registry.StandardServiceRegistryBuilder;public  class  HibernateUtil  {    private  static  SessionFactory sessionFactory;     static  {         StandardServiceRegistry  registry  =  new  StandardServiceRegistryBuilder ().configure().build();         try  {             sessionFactory = new  MetadataSources (registry).buildMetadata().buildSessionFactory();         }catch  (Exception e){             e.printStackTrace();             StandardServiceRegistryBuilder.destroy(registry);         }     }     public  static  Session openSession () {         return  sessionFactory.openSession();     }     public  static  void  closeSessionFactory () {         sessionFactory.close();     } } 
HelloWorld 1 2 3 4 5 6 7 8 9 10 11 12 13 <?xml version="1.0" ?> <!DOCTYPE hibernate-mapping  PUBLIC  "-//Hibernate/Hibernate Mapping DTD 3.0//EN"          "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" > <hibernate-mapping  package ="com.bean" >          <class  name ="Customer"  table ="customer" >                   <id  name ="id"  column ="id" />          <property  name ="name"  column ="name" />               </class >  </hibernate-mapping > 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 package  com.bean;public  class  Customer  {    private  int  id;     private  String name;     public  int  getId ()  {         return  id;     }     public  void  setId (int  id)  {         this .id = id;     }     public  String getName ()  {         return  name;     }     public  void  setName (String name)  {         this .name = name;     }     public  Customer (int  id, String name)  {         this .id = id;         this .name = name;     }     public  Customer ()  {     } } 
测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 import  com.bean.Customer;import  com.util.HibernateUtil;import  org.hibernate.Session;import  org.hibernate.Transaction;import  org.junit.Test;public  class  HibernateTest  {    @Test      public  static  void  main (String[] args)  {         Customer  customer  =  new  Customer (3 ,"jjw2" );         saveCustomer(customer);     }     public  static  void  saveCustomer (Customer c) {                  Session  session  =  HibernateUtil.openSession();                  Transaction  tran  =  session.beginTransaction();                  session.save(c);                  tran.commit();                  session.close();     } } 
单实体映射 对象-关系映射文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <hibernate-mapping  package ="com.bean" >     <class >          <id />          <property />      </class >  </hibernate-mapping > <class > </class >  用于指定类和表之间的映射<id > </id >  设定持久化类的 OID(对象标识符) 和表的主键的映射关系。<property > </property >  设定类的其它属性和表的字段的映射关系。
单实体的属性映射 property的属性 
在对象-关系映射文件中元素的 access 属性用于指定Hibernate访问持久化类属性的方式 
property : 默认值,通过getter(增删改)和setter(查)方法访问属性值; 
field : 通过Java反射机制直接访问属性值。 
 
场景:当持久化类属性与数据库字段不对称时,可以利用access属性调用对应的getter、setter方法 
1 2 3 4 5 6 7 8 9 public  String getUserName ()  {	return  firstName + ""  +lastName; } public  void  setUserName (String name)  {	String[] strName = userName.split("" );this .firstName = strName[0 ]; 	this .lastName = strName[1 ]; )      
场景:User 需要订单总额属性,但数据库表中没有这个字段。可在元素的 formula 属性设置查询语句(formula属性仅在查询操作中起作用)  
1 2 3 <property  name ="totalPrice"                              formula ="(select sum(o.price) from                      orders as o where o.userId=id)" />
控制持久化类的insert和update 
这些属性用于控制insert和update,例如update=”false”时,不更新这个字段 ,dynamic-update=”true”时,当执行更新操作时,如果设置的属性为null则不改变之前的值,但是使用dynamic-update=”true”的前提是先获取一次这个数据到缓存中,才能用新的数据对比缓存中的数据,进而修改不需要改变的数据 
单实体的对象标识符映射 Hibernate 采用对象标识符(OID)区分对象。
Hibernate 自带了很多种标识符生成器
increment  采用 Hibernate 数值递增的方式; 
identity 采用数据库提供的自增长方式; 
assigned 主键由应用逻辑产生; 
sequence 采用数据库提供的序列方式; 
hilo 通过hi/lo算法   // Hibernate 5.0 以后不支持; 
seqhilo 通过hi/lo算法; 
native 自动选择合适的标识符生成器; 
uuid.hex 通过uuid算法。 
 
使用注解映射单实体 
@Entity:声明一个实体
@Table(name=”table_name”):为实体类指定对应的数据库表。
@Id:声明实体类的OID属性。
@GeneratedValue(generator=”increment_generator”):声明OID的生成策略。(JPA通用注解)
@GenericGenerator(name=”increment_generator”, strategy=”increment”):使用Hibernate提供的生成策略
@Column(name=”columnName”) :将属性映射到列。
这个类只标明了他是一个注解类,并且主键是自增长的,然而其他的一些属性并没有配置注解,那么他一样会在数据库的表中存在,因为这些属性默认就有@Column注解。因此如果没有添加注解,则hibernate会自动在属性前面添加@Column注解。 
name=”columnName”    字段名称;
unique=false            是否在该字段上设置唯一约束;
nullable=true            字段是否能为空;
insertable=true        控制 insert语句;
updatable=true        控制 update语句;
length=255            指定字段长度。
 
@Access(AccessType.PROPERTY):
通过 getter 和 setter 方法访问实体类的属性; 
需要在 getter 方法上定义字段的属性 
 
@Access(AccessType.FIELD):
直接访问实体类的属性,可以不定义 getter 和 setter 方法; 
需要在变量上定义字段的属性。 
 
@Formula:将属性映射到SQL语句。
@DynamicInsert:动态生成 INSERT 语句。
@DynamicUpdate:动态生成 UPDATE 语句。
 
注意:
对于属性字段和表的字段关系对应的注解属性的位置,一般我们采用以下两种方式
第一种: 是把注解@Column(name =”xx”)放在field上
第二种: 是把注解@Column(name= “xx”)放在get方法上
但是第一种方式这样做实际上破坏了java面向对象的封装性 ,原因是一般我们写javaBean,成员变量通常定义为private,目的就是不让别人来直接访问的私有属性,而我们把注解放在私有成员的变量上,就是默认hibernate可以直接访问我们的私有的成员变量,所以我们定义属性为private,就实际没有多大意义,至于hibernate为什么能访问,hibernate采用java的反射机制完全可以访问私有成员变量!所以应该放在get方法上,第二种方式这个时候就显得更加合理。 
Hibernate继承关系映射 场景:现要为某公司开发一个员工信息管理系统,已经了解到该公司的员工中有按小时计薪和按月计薪两种方式,这种情况下系统中该如何维护员工的基本信息呢? 
三种不同的解决方案:
一方案:
关系数据模型不支持域模型中的继承关系和多态。 
每个子类所对应的表中同时存在从父类继承的属性和自己特有的属性。 
如果父类不是抽象类并且也需要被持久化,还需要为父类创建对应的表。 
 
映射文件形式 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <class  name ="HourlyEmployee"  table ="HOURLYEMPLOYEE"  >     <id  name ="id" >           <generator  class ="increment" />      </id >      <property  name ="name" />      <property  name ="rate" />  </class > <class  name ="SalariedEmployee"  table ="SALARIEDEMPLOYEE"  >     <id  name ="id" >           <generator  class ="increment" />      </id >      <property  name ="name" />      <property  name ="salary" />  </class > 
注解形式 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Entity  @Table(name="HourlyEmployee")  public  class  HourlyEmployee  extends  Employee  {     private  String name;     private  String rate;     ... }  @Entity  @Table(name="SalariedEmployee")  public  class  SalariedEmployee  extends  Employee  {     private  String name;     private  String salary;     ... }  
Employee基类
1.标注为@MappedSuperclass的类将不是一个完整的实体类,他将不会映射到数据库表,但是他的属性都将映射到其子类的数据库字段中。
2.标注为@MappedSuperclass的类不能再标注@Entity或@Table注解,也无需实现序列化接口。
1 2 3 4 5 6 7 8 9 10 11 @MappedSuperclass  public  class  Employee {	@Id       @GeneratedValue         public  Integer getId ()  {          return  this .id;      }      public  void  setId (Integer id)  {          this .id = id;      }  } 
方案二:
关系数据模型支持继承关系和多态。 
在表中加入额外的字段区分子类的类型,表中包含父类和所有子类的属性对应的字段。 
支持多态查询,就是从数据库中检索父类对象时,同时包含所有子类的对象。 
 
在数据库表中会有这样的一个字段用来区别记录的属性,如:在客户表中有一个字段表示客户级别,当这个记录为A时是一级客户,为B时是二级客户;然后,在程序中手动控制flag的值,但是这样当每个级的客户有不同的属性时Customer类将包含所有级别的属性 ,这样不是很好。
hibernate提供一个Discriminator映射的方法,就是把一个表映射成不同的类,有不同的属性 。
xml文件方式 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <class  name ="Employee"  table ="EMPLOYEE" >     <id  name ="id" >          <generator  class ="increment" />      </id >             <discriminator  column ="EMPLOYEETYPE"  />              <property  name ="name" />                <subclass  name ="HourlyEmployees"  discriminator-value ="HE" >           <property  name ="rate" />      </subclass >                <subclass  name ="SalariedEmployees"  discriminator-value ="SE" >           <property  name ="salary" />      </subclass >  </class > 
注解形式 
Employee基类
指定继承关系的生成策略
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
指定区分子类类型的字段。
 @DiscriminatorColumn(name=”EMPLOYEETYPE”)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @Entity @Table(name="employee") @Inheritance(strategy=InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name="employee_type") public  class  Employee  {	private  Integer id; 	private  String name; 	 	@Id  	@GeneratedValue(strategy=GenerationType.IDENTITY)  	public  Integer getId ()  { 		return  id; 	} 	... } 
各个子类使用注解:
指定各个子类区分字段的值。
@DiscriminatorValue(value = “”)
1 2 3 4 5 6 7 8 @Entity @DiscriminatorValue(value="HE") public  class  HourlyEmployee  extends  Employee {	private  double  rate;     ... } 
方案三:
在关系数据模型中,用外键参照关系来表示继承关系,子类对应的表中存在外键参照父类对应表的主键。 
继承关系中的每个类及接口都对应一个表。 
支持多态查询。 
 
xml文件形式 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <class  name ="Employee"  table ="EMPLOYEE" >     <id  name ="id" >          <generator  class ="increment" />      </id >             <property  name ="name" />      <joined-subclass  name ="HourlyEmployee"  table ="HOURLYEMPLOYEE" >               <key  column ="EMPLOYEEID" />           <property  name ="rate" />      </joined-subclass >           <joined-subclass  name ="SalariedEmployee"  table ="SALARIEDEMPLOYEE" >          <key  column ="EMPLOYEEID" />           <property  name ="salary" />      </joined-subclass >  </class > 
注解形式 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 @Entity @Table(name="employee") @Inheritance(strategy=InheritanceType.JOINED) public  class  Employee  {	private  Integer id; 	private  String name; 	 	@Id  	@GeneratedValue(strategy=GenerationType.IDENTITY)  	public  Integer getId ()  { 		return  id; 	}     ... } @Entity @Table(name="hourly_employee") @PrimaryKeyJoinColumn(name="employee_id") public  class  HourlyEmployee  extends  Employee {	... 	 } 
Hibernate一对一关联映射 参考:https://www.cnblogs.com/whgk/p/6128395.html 
一对一关系映射 
实体类 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public  class  User  {    private  Integer id;     private  String userName;     private  String password;     private  Person person;     …… } public  class  Person  {    private  Integer id;     private  String name;     private  String idNumber;     private  User user;     …… } 
Hibernate提供两种映射一对一关联关系的方式: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 <hibernate-mapping  package ="com.hibernate.entity" > 	 	<class  name ="Person"  table ="person" >  		 		<id  name ="id"  column ="person_id" >  			 			<generator  class ="foreign" >  				 				<param  name ="property" > user</param >  			</generator >  		</id >  		 		 		 		 		<property  name ="name"  />  		 		<property  name ="idNumber" />  		 		 		<one-to-one  name ="user"  class ="User"  constrained ="true" />  	</class >  </hibernate-mapping > <hibernate-mapping  package ="com.hibernate.entity" > 	 	<class  name ="User"  table ="user" >  		 		<id  name ="id"  column ="id" >  			 			<generator  class ="identity" />  		</id >  		 		 		 		 		<property  name ="userName"  >  			<column  name ="user_name" > </column >  		</property >  		 		<property  name ="password" />  		 		 		 		<one-to-one  name ="person"  class ="Person"  cascade ="all" > </one-to-one >  	</class >  </hibernate-mapping > 
1 2 3 4 5 6 User  u  =  session.get(User.class, id);u.setPerson(p); 	 p.setUser(u);		 session.save(p); 
级联操作(保存为例) 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21       User  u  =  new  User ("李四" , "8888888" );       Person  p  =  new  Person ();       p.setName("Tom" );       p.setIdNumber("1111111" );              u.setPerson(p);       p.setUser(u); Session  session  =  HibernateUtil.openSession();Transaction  tran  =  session.beginTransaction();session.save(u);  tran.commit(); session.close(); 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 <hibernate-mapping  package ="com.hibernate.entity" > 	 	<class  name ="Person"  table ="person" >  		 		<id  name ="id"  column ="person_id" >  			 			<generator  class ="foreign" >  				 				<param  name ="property" > user</param >  			</generator >  		</id >  		 		 		 		 		<property  name ="name"  />  		 		<property  name ="idNumber" />  		 		 		<one-to-one  name ="user"  class ="User"  property-ref ="person" />  	</class >  </hibernate-mapping >  <hibernate-mapping  package ="com.hibernate.entity" > 	 	<class  name ="User"  table ="user" >  		 		<id  name ="id"  column ="id" >  			 			<generator  class ="identity" />  		</id >  		 		 		 		 		<property  name ="userName"  >  			<column  name ="user_name" > </column >  		</property >  		 		<property  name ="password" />  		 		 		 		          		 <one-to-one  name ="person"  column ="per_id"  class ="Person"  unique ="true" />  	</class >  </hibernate-mapping > 
级联操作(保存为例) 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public  static  void  save (User u, Person p)  {	 	Session  session  =  HibernateUtil.openSession(); 	 	Transaction  tran  =  session.beginTransaction(); 	 	 	u.setPerson(p); 	p.setUser(u); 	 	 	session.save(u); 	session.save(p); 	 	tran.commit(); 	 	session.close(); } 
使用注解映射主键关联的一对一 
@OneToOne(cascade=CascadeType.ALL) //指定一对一关系,并设置级联属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 @Entity @Table(name="user") public  class  User  {	private  Integer id; 	private  String userName; 	private  String password; 	private  Person person; 	 	@Id  	@GeneratedValue(strategy=GenerationType.IDENTITY)  	public  Integer getId ()  { 		return  id; 	}          ...   	 	 	 	 	 	@OneToOne(targetEntity=Person.class, cascade=CascadeType.REMOVE)  	@PrimaryKeyJoinColumn(name="person_id")  	public  Person getPerson ()  { 		return  person; 	} 	public  void  setPerson (Person person)  { 		this .person = person; 	} 	     ...                   @Column(name="user_name")  	public  String getUserName ()  { 		return  userName; 	}          ...      } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 @Entity @Table(name="person") public  class  Person  {	private  Integer id; 	private  String name; 	private  String idNumber; 	private  User user; 	 	@Id       	@GeneratedValue(generator="my_gen")            	@GenericGenerator(name="my_gen", strategy="foreign",       /* 设置参数 */                  	 parameters= {@Parameter(value="user",name="property")}) 	public  Integer getId ()  { 		return  id; 	} 	 	... 	 	           	@OneToOne(mappedBy="person",targetEntity=User.class)  	public  User getUser ()  { 		return  user; 	} 	 	... } 
@OneToOne(cascade=CascadeType.ALL)
@JoinColumn(name=”PERSONID”):指明USER表中的外键列名。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 @Entity @Table(name="user") public  class  User  {	private  Integer id; 	private  String userName; 	private  String password; 	private  Person person; 	 	@Id  	@GeneratedValue(strategy=GenerationType.IDENTITY)  	public  Integer getId ()  { 		return  id; 	} 	... 	 	@OneToOne  	@JoinColumn(name="per_id")  	public  Person getPerson ()  { 		return  person; 	}          ...              @Column(name="user_name")  	public  String getUserName ()  { 		return  userName; 	} 	 } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @Entity @Table(name="person") public  class  Person  {	private  Integer id; 	private  String name; 	private  String idNumber; 	private  User user; 	 	@Id  	@GeneratedValue(strategy=GenerationType.IDENTITY)  	public  Integer getId ()  { 		return  id; 	} 	 	... 	@OneToOne(mappedBy="person")  	public  User getUser ()  { 		return  user; 	} } 
组合关系映射 xml映射文件方式 
Address类不能持久化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <hibernate-mapping  package ="com.hibernate.entity" > 	 	<class  name ="Contact"  table ="contact" >  		<id  name ="id" >  			<generator  class ="identity" />  		</id >  		<property  name ="phoneNum" />  		 		<component  name ="homeAddress"  class ="Address" >  			 			<property  name ="province"  column ="home_pro" />  			<property  name ="city"  column ="home_city" />  		</component >  		<component  name ="workAddress"  class ="Address" >  			 			<property  name ="province"  column ="work_pro" />  			<property  name ="city"  column ="work_city" />  		</component >  	</class >  </hibernate-mapping > 
Test
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 public  class  Test  {	public  static  void  main (String[] args)  { 		Address  home  =  new  Address (); 		home.setProvince("河北省" ); 		home.setCity("邯郸市" ); 		 		Address  work  =  new  Address (); 		work.setProvince("河北省" ); 		work.setCity("石家庄市" ); 		 		Contact  c  =  new  Contact (); 		c.setPhoneNum("15000001222" ); 		c.setHomeAddress(home); 		c.setWorkAddress(work); 		 		saveContact(c); 		 		HibernateUtil.closeSessionFactory(); 	} 	public  static  void  saveContact (Contact c)  { 		 		Session  session  =  HibernateUtil.openSession(); 		 		Transaction  tran  =  session.beginTransaction(); 		 		session.save(c); 		 		tran.commit(); 		 		session.close(); 	} } 
注解方式 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @Embeddable public  class  Address  {    ...... } @Embedded @AttributeOverrides(value={     @AttributeOverride(         name = "province",          column = @Column(name=“HOMEPROVINCE")),     @AttributeOverride(         name = "city",         column = @Column(name=“HOMECITY")),     ...... }) public  class  Contact  {    ...... } 
Hibernate一对多关联映射 
xml映射文件 
实体类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public  class  User  {    private  Integer id;     private  String userName;     private  String password;     private  Set  orderSet  =  new  HashSet <Order>();     ...... } public  class  Order  {    private  Integer id;      private  Double price;      ...... } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 <hibernate-mapping  package ="com.hibernate.entity" > 	 	<class  name ="User"  table ="user" >  		 		<id  name ="id"  column ="id" >  			 			<generator  class ="identity" />  		</id >  		 		<property  name ="userName"  column ="user_name" />  		 		<property  name ="password"  not-null ="true"  length ="11" />  		 		 		<set  name ="orders"  cascade ="all" >  			 			<key  column ="user_id" > </key >   			<one-to-many  class ="Order" />  		</set >                                                        	</class >  </hibernate-mapping > <hibernate-mapping  package ="com.hibernate.entity" > 	<class  name ="Order"  table ="orders" >  		<id  name ="id" >  			<generator  class ="identity" > </generator >  		</id >  		<property  name ="orderNum" />  		<property  name ="price" />  	</class >  </hibernate-mapping > 
Test
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 public  class  Test  {	public  static  void  main (String[] args)  { 		 		Order  o  =  new  Order (); 		o.setOrderNum("QW121212121212121" ); 		o.setPrice(100.0 ); 		 		saveOrder(111 , o); 		HibernateUtil.closeSessionFactory(); 	} 	 	public  static  void  saveOrder (Integer userId,Order o)  { 		 		Session  session  =  HibernateUtil.openSession(); 		 		Transaction  tran  =  session.beginTransaction(); 		 		User  u  =  session.get(User.class, userId); 		 		 		u.getOrders().add(o); 		 		 		session.save(o); 		 		tran.commit(); 		 		session.close(); 	} } 
xml文件形式 
1 2 3 4 5 6 7 8 9 10 11 12 <hibernate-mapping  package ="com.hibernate.entity" > 	<class  name ="Order"  table ="orders" >  		<id  name ="id" >  			<generator  class ="identity" > </generator >  		</id >  		<property  name ="orderNum" />  		<property  name ="price" />  		<many-to-one  name ="user"  class ="User"  column ="user_id" />   	</class >  </hibernate-mapping >           
注解形式 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 @Entity @Table(name="orders") public  class  Order  {	 	private  Integer id; 	private  String orderNum; 	private  double  price; 	private  User user; 	 	@Id  	@GeneratedValue(strategy=GenerationType.IDENTITY)  	public  Integer getId ()  { 		return  id; 	} 	 	... 	 	 	@ManyToOne(targetEntity=User.class)  	 	@JoinColumn(name="user_id")  	public  User getUser ()  { 		return  user; 	} } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 @Entity @Table(name="user") public  class  User  {	private  Integer id; 	private  String userName; 	private  String password; 	private  Set<Order> orders = new  HashSet <Order>(); 	 	@Id  	@GeneratedValue(strategy=GenerationType.IDENTITY)  	public  Integer getId ()  { 		return  id; 	}     ... 	 	 	 	 	@OneToMany(targetEntity=Order.class,  			cascade=CascadeType.REMOVE, 			mappedBy="user" /*表示在另一头的user属性中已经映射了*/)  	public  Set<Order> getOrders ()  { 		return  orders; 	} 	public  void  setOrders (Set<Order> orders)  { 		this .orders = orders; 	} 	 } 
Test
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 public  class  Test  {	public  static  void  main (String[] args)  { 		 		Order  o  =  new  Order (); 		o.setOrderNum("QW121212121212121" ); 		o.setPrice(100.0 ); 		 		saveOrder(111 , o); 		HibernateUtil.closeSessionFactory(); 	} 	 	public  static  void  saveOrder (Integer userId,Order o)  { 		 		Session  session  =  HibernateUtil.openSession(); 		 		Transaction  tran  =  session.beginTransaction(); 		 		User  u  =  session.get(User.class, userId); 		 		          u.getOrders().add(o);  		o.setUser(u); 		 		 		session.save(o); 		 		tran.commit(); 		 		session.close(); 	} } 
Hibernate多对多关联映射 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public  class  Student  {    private  int  id;     private  String name;     private  String studentNo;     private  Set<Course> courseSet          = new  HashSet <Course>();     ...... }  public  class  Course  {    private  Integer id;     private  String name;      private  int  credit;       private  Set<Student> studentSet         = new  HashSet <Student>();     ...... } 
xml文件形式 
inverse 是 Hibernate 中双向关联关系中的基本概念,用来设置关系由哪一方来维护
inverse=true 表示被控方,=false 表示主控方 
在多对多关系中需要设置哪一方为被控方,即设置inverse=true  
只能在双向一对多,多对多中使用 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18    <set  name ="courseSet"  table ="student_course"           inverse ="false" >          <key  column ="student_id" />      <many-to-many  class ="Course"  column ="course_id" />  </set >    <set  name ="studentSet"  table ="student_course"           inverse ="true" >          <key  column ="course_id" />      <many-to-many  class ="Student"  column ="student_id" />  </set > 
注解形式 
Hibernate操作持久化对象 session缓存 
缓存介于应用程序和永久性存储源之间,其作用是降低应用程序直接读写永久性存储源的频率,从而提高应用的运行效率。
缓存内的数据是永久性存储源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件同步缓存和永久性存储源的数据。
当 Session 执行查询方法时,先从 Session 缓存中读取据,如果缓存中有则直接读取,如果缓存中没有,从数据库中查询并加载到 Session 缓存中,再从缓存中读取。
当 Session 执行 save()、update() 方法时,将对象持久化到数据库中并将对象加载到 Session 缓存中。
session清理缓存 
Session在某一时间点按照缓存中对象的属性变化来同步更新数据库的这一过程被称为 Session 清理缓存。 
缓存清理的时间点:
当调用 transaction.commit() 方法时,会先清理缓存,再向数据库提交事务; 
当显式调用 Session.flush() 方法时,会清理缓存; 
当调用 Session 的查询(不包括 load() 和 get() )方法时,如果缓存中对象的属性有变化则清理缓存。 
 
Session清理缓存的模式 
setHibernateFlushMode() 用于设定 Session 清理缓存的模式。
Hibernate实体对象生命周期 
Transient(临时状态) : 刚刚被 new 关键字创建,还没有被持久化,不在Session的缓存中。 
Persistent(持久化状态) : 已经被持久化,并加入到 Session 缓存中。 
Detached(游离状态) : 已经被持久化,但不再处于 Session 缓存中(给id赋值了)。 
Removed(删除状态) : Session 已经计划将其从数据库删除,并且不再处于 Session 缓存中。 
 
Hibernate检索方式 HQL检索方式 
HQL语句中关键字大小写无关,但习惯将关键字小写。 
from 关键字后面是类名不是数据库表名,类名需区分大小写。 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 public  static  void  testHQL ()  {		Session  session  =  HibernateUtil.openSession(); 		 		 		String  hql  =  "select u from User u" ;  		Query<User> query = session.createQuery(hql); 		List<User> users = query.list(); 		System.out.println(users);           		 		String  hql  =  "select u.userName from User u" ; 		Query  query  =  session.createQuery(hql); 		List<String> users = query.list(); 		System.out.println(users);           		 		String  hql  =  "select u.userName, u.password from User u" ; 		 		Query  query  =  session.createQuery(hql); 		List<User> users = query.list();   		List<Object[]> users = query.list(); 		for (Object[] o : users) { 			System.out.println("用户名:"  + o[0 ]); 			System.out.println("密码:"  + o[1 ]); 		}           		 		String  hql  =  "select u from User u where u.userName='张三'" ; 		 		Query<User> query = session.createQuery(hql); 		List<User> users = query.list(); 		System.out.println(users);           		 		String  hql  =  "select u from User u where u.id=104" ; 		Query<User> query = session.createQuery(hql); 		User  u  =  query.uniqueResult(); 		System.out.println(u);           		 		String  hql  =  "select u from User u order by u.userName, u.id desc" ; 		Query<User> query = session.createQuery(hql); 		List<User> users = query.list(); 		System.out.println(users);           		 		String  hql  =  "select u.userName, count(u) from User u group by u.userName having u.userName != '张三'" ; 		Query  query  =  session.createQuery(hql); 		List<Object[]> users = query.list(); 		for (Object[] o : users) { 			System.out.println("用户名:"  + o[0 ]); 			System.out.println("个数:"  + o[1 ]); 		}           		 		String  hql  =  "select u from User u where u.userName=?" ; 		Query  query  =  session.createQuery(hql);      		 		query.setParameter(0 , "张三" ); 		List<User> users = query.list(); 		System.out.println(users); 		 		String  hql  =  "select u from User u where u.userName=:name" ; 		Query  query  =  session.createQuery(hql); 		 		query.setParameter("name" , "张三" ); 		List<User> users = query.list(); 		System.out.println(users); 		 		String  hql  =  "select u from User u where u.userName=:userName" ; 		Query  query  =  session.createQuery(hql); 		 		User  u  =  new  User (); 		u.setUserName("张三" ); 		query.setProperties(u); 		List<User> users = query.list(); 		System.out.println(users); 		 		String  hql  =  "select u from User u where u.userName=:userName" ; 		Query  query  =  session.createQuery(hql); 		Map<String, Object> map = new  HashMap <>(); 		 		map.put("userName" , "张三" ); 		query.setProperties(map); 		List<User> users = query.list(); 		System.out.println(users); 		     	 		String  hql  =  "select u from User u where (select count(o) from u.orders o) > 0" ; 		Query  query  =  session.createQuery(hql); 		List<User> users = query.list(); 		System.out.println(users); 		 		session.close(); 	} public  static  void  hqlUpdate ()  {		 		Session  session  =  HibernateUtil.openSession(); 		 		Transaction  tran  =  session.beginTransaction(); 		 		 		String  hql  =  "delete from User u where u.userName=?" ; 		Query<User> query = session.createQuery(hql); 		query.setParameter(0 , "张三" ); 		int  row  =  query.executeUpdate(); 		 		System.out.println("影响的条数:"  + row); 		 		tran.commit(); 		session.close(); 	} 
HQL子查询说明以下几点:
子查询分为相关子查询和无关子查询;
相关子查询:子查询语句引用了外层查询语句定义的别名。 
无关子查询:子查询语句没有引用外层查询语句定义的别名。 
 
HQL子查询功能依赖于底层数据库对子查询的支持;
HQL子查询返回的是多条记录,使用以下关键字量化。
如果HQL子查询的是集合,HQL提供了一组操作集合的函数。
size(),获得集合中元素的个数; 
maxIndex(),对于建立索引的集合,获得最大索引值; 
minIndex(),对于建立索引的集合,获得最小索引值; 
elements(),获得集合中所有元素。 
 
做批量查询时,如果数据量很大就需要分页功能,HQL提供了用于分页查询的方法:
引用查询指在映射文件中定义查询语句。
 
QBC检索方式 
Query  By Criteria(QBC) 可以看作是传统SQL的对象化表示。它主要由Criteria接口,Criterion接口,Restrictions类组成。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Criteria criteria=session.createCriteria(User.class); Criterion c1= Restrictions.eq("userName" , "张三" ); criteria.add(c1); List  result  =  criteria.list();
本地SQL检索方式 
1 2 3 4 5 6 7 8 String  sql  =  "select * from  user" ;NativeQuery  query  =  session.createNativeQuery(sql, User.class);List  list  =  query.list();
Hibernate检索策略 
类级别检索策略: 
立即检索:立即加载检索方法指定的对象。 
加载多于需要的对象白白浪费内存空间
select 语句数量多,频繁访问数据库,影响系统性能
1 2 映射配置文件中<class > 元素的 lazy 属性设置为 false。 <class  name ="User"  table ="USER"  lazy ="false" > 
延迟检索:延迟加载检索方法指定的对象。 
避免多加载应用程序不需要访问的数据对象
1 2 3 映射配置文件中<class > 元素的 lazy 属性设置为 true。 <class  name ="User"  table ="USER"  lazy ="true" > 
关联级别检索策略: 
在映射文件中用 元素 来配置 一对多 和 多对多 关联关系。 
1 2 3 4 5 一对多和多对多 修改User 一对多关联的Order对象的检索策略,User.hbm.xml 中<set > 元素 lazy 和 outer-join 属性      多对一 修改Order 多对一关联的 User 对象检索策略,Order.hbm.xml 中 <many-to-one > 元素 outer-join 属性和 User.hbm.xml 中<class > 元素的 lazy 属性。 
迫切左外连接检索:利用SQL外连接查询功能加载检索方法指定对象。 
减少执行select语句的数量,减少数据库访问,提高系统性能。
Hibernate二级缓存机制 SessionFactory有一个内置缓存 (实现机制跟Session缓存类似)和一个可以配置的缓存插件被称为外置缓存 
Session缓存是事务范围的缓存。
SessionFactory缓存是进程范围或者集群范围的缓存。
进程范围和集群范围的缓存可能被进程内的多个事务并发访问,因此需要采取必要的并发访问策略。
持久化层的二级缓存,在查询时先在事务缓存中查找,如果没有查询到相应数据,再到进程范围或集群范围缓存中查找,如果还没找到再数据库中查找。
Hibernate二级缓存配置 Hibernate的第二级缓存是可配置的缓存插件,允许选用以下类型的缓存插件,表中给出了各个缓存插件支持的并发访问策略。
选择EHCache缓存插件的配置步骤如下
1、在Hibernate.cfg.xml配置文件中配置 
1 2 3 4 5 6 <property  name ="cache.use_second_level_cache" > true</property > <property  name ="cache.region.factory_class" > org.hibernate.cache.ehcache.EhCacheRegionFactory</property > 
2、设置实体映射配置文件中或元素的子元素的usage属性   
1 2 3 4 5 6 7 8 9 <class  name ="User" >     <cache  usage ="read-write" />      …… </class > transactional:一般缓存插件没有此策略(除jboss-cache) nonstrict-read-write:不严格的读写(如:帖子的回帖量) read-write:严格的读写(如:银行系统数据)  read-only : 只读策略(对象不能修改,修改会报异常),效率最高