Hibernate详解全部内容


1.什么叫hibernate?

Hibernate说的最简单实际上是一种能能够 直接操作 JAVA对象数据库 进行 交互 的一个技术,hibernate就是直接桥梁

JAVA对象<-----Hibernate<----数据库

 

HIbernate:是用来访问数据库的一种框架

                   是一个非侵入式的ORMapping框架

                   是一个对象关系映射的框架

                   是一个能够将JAVA对象直接映射到关系型数据库的

                   Hibernate---->JAVA对象------>关系型的数据库

 

       非侵入式框架:
                    就是我们在使用这个框架的时候,不需要让我们原来的代码来 继承于某些特定的类,或者实现某些特定的类 的这种类型框架。

       侵入式框架呢:
                    就是我们在使用这个框架的时候需要 继承或者实现 某些特定的类或者接口的这种类型的框架。

 

       O------->Object(对象)

       R------->Relation(关系型的数据库)

       M------->Mapping->映射


2.为什么我们要学习Hbernate呢?

     JDBC:    操作数据库需要编写复杂的交互代码====>效率比较高,但是代码比较复杂,很多

     Dbutils:  需要编写复杂的Sql代码

     Hibernate: 在这个情况下就应运而生了,它减少了程序员要编写Sql的负担,但是同时也降低了程序运行的效率,  也就是说:最终Sql语句的生成是由Hibernate来完成的,所以效率就降低了

 

3.使用hibernate步骤

* 因为hibernate是持久层(Dao层)的解决方案,既可以建立java工程也可以建立WEB工程


第一步:建立一个JAVA工程或者Web工程

第二步:导入我们的Hibernate的jar包

路径:hibernate-release-5.2.10.Final\lib\required--->改文件夹下面所有架包

 

第三步:在工程的src目录下config 创建一个名字是  hibernate.cfg.xml的全局配置文件

 

hibernate.cfg.xml代码:

<?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="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql:///hibernatetest</property>
        <property name="connection.username">root</property>
        <property name="connection.password">123</property>
    
    <!--配置方言  -->
    <!-- org.hibernate.dialect.MySQL57InnoDBDialect -->
    <!--org.hibernate.dialect.MySQL5InnoDBDialect  -->
        <property name="dialect">org.hibernate.dialect.MySQL57InnoDBDialect</property>
    <!--让数据库自动创建表  -->
        <property name="hbm2ddl.auto">update</property>
    <!--在控制台打印SQL语句  -->
        <property name="show_sql">true</property>
    <!--格式化SQL语句  -->
        <property name="format_sql">true</property>
    <!--添加映射路径  -->
        <mapping resource="com/my/test/User.hbm.xml"/>

   </session-factory>
</hibernate-configuration> 
    

第四步:建立我数据库对应的实体 User类

User类代码:


package com.my.test;

/**
 * Description:User实体类
 * Copyright (c) 2017 J.K
 * Program Name:User.java
 * Date:  2017年9月4日 下午6:50:02
 * 
 * @author  : 西瓜瓜 
 * @version : 1.0
 */
public class User {

	private int uid;//注意设置主键的时候类型
	private String uname;
	private String upwd;
	public User() {
		super();
		// TODO Auto-generated constructor stub
	}
	public User(int uid, String uname, String upwd) {
		super();
		this.uid = uid;
		this.uname = uname;
		this.upwd = upwd;
	}
	public int getUid() {
		return uid;
	}
	public void setUid(int uid) {
		this.uid = uid;
	}
	public String getUname() {
		return uname;
	}
	public void setUname(String uname) {
		this.uname = uname;
	}
	public String getUpwd() {
		return upwd;
	}
	public void setUpwd(String upwd) {
		this.upwd = upwd;
	}
	@Override
	public String toString() {
		return "User [uid=" + uid + ", uname=" + uname + ", upwd=" + upwd + "]";
	}
		
}

第五步:建立的实体和数据库表之间的映射关系

 在实体User类所对应的包里面创建一个映射文件 -----实体类名.hbm.xml

User.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.my.test"  auto-import="true">
    <!--auto-import="true" :后面使用HQL语句时,自动导入,不需要写全路径 -->
 
    <class name="User" table="t_user" auto-import="true">
     <!--配置主键  -->
	     <id name="uid"  column="u_id">
	        <!--主键生成策略  -->
	        <!--  
	        class="uuid":      主键是String类型的时候用
	        class="increment": 主键是int类型的时候用
	         -->
	         <generator class="increment"></generator>
	     </id>
    
    <!-- 普通配置属性 -->
       <property name="uname" column="u_name"  type="java.lang.String"> </property>
                 
       <property name="upwd" column="u_pwd"  type="java.lang.String"> </property>
  
    </class>    
        
</hibernate-mapping>         

 

第六步:在hibernate.cfg.xml文件中,添加我们的映射文件的路径(第三步图里面)

路径为全路径名

第七步:编写我们的测试类

 

Test001.java代码(一个简单测试类)

package com.my.test;

import static org.junit.Assert.*;
import java.util.List;
import javax.swing.plaf.synth.SynthSeparatorUI;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;
import org.junit.Test;

/**
 * Description:测试类
 * Copyright (c) 2017 J.K
 * Program Name:Test001.java
 * Date:  2017年9月4日 下午7:09:48
 * 
 * @author  : 西瓜瓜
 * @version : 1.0
 */
public class Test001 {

		@Test
		public void test() throws Exception {
			//加载配置文件
			Configuration cfg = new Configuration().configure("config/hibernate.cfg.xml");
			//创建session工厂
			SessionFactory sfg = cfg.buildSessionFactory();
			//打开session
			Session openSession = sfg.openSession();
			//开起事物
			openSession.beginTransaction();
			
//业务逻辑处理************************** User user = new User(1,"西瓜瓜","123"); openSession.save(user);
//业务逻辑处理**************************

//提交事物 openSession.getTransaction().commit(); //关闭session openSession.close(); //关闭工厂 openSession.close(); } }

注*:除了业务逻辑,事物代码外,其他的都是重复的,可以封装成hibernate工具类

因此,简化代码如下:

HibernateUtil.java代码:

 

package com.my.utils;

import static org.hamcrest.CoreMatchers.nullValue;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

/**
 * Description:HibernateUtil工具类
 * Copyright (c) 2017 J.K
 * Program Name:HibernateUtil.java
 * Date:  2017年9月4日 下午9:21:26
 * 
 * @author  : 西瓜瓜 
 * @version : 1.0
 */
public class HibernateUtil {
    
	private static Configuration cfg =null;
	private static SessionFactory sfg =null;

        //加载配置,创建session工厂设置为全局变量
	static{

		cfg = new Configuration().configure("config/hibernate.cfg.xml");
		sfg = cfg.buildSessionFactory();
	}

	
	//打开session(不能设置为全局变量)
	public static Session getSession() {
		
		return sfg.openSession();
		
	}

	
	//关闭资源
	public static void close(Session session,SessionFactory sfg) {
		if(null !=session){
			session.close();
		}
		if(null !=sfg){
			sfg.close();
		}	
		
	}
	
}

  

 补充:

      下面为HibernateUtils.java封装优化代码:

      先创建一个HbaseUtils.java工具类,再让HibernateUtils.java继承它,进一步封装。

 

 

 HbaseUtils.java代码:

 

package com.my.utils;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

/**
 * Description:TODO
 * Copyright (c) 2017 J.K
 * Program Name:HbaseUtils.java
 * Date:  2017年9月5日 下午2:59:38
 * 
 * @author  : 西瓜瓜 
 * @version : 1.0
 */
public class HbaseUtils {

	private static SessionFactory sf=null;
	//唯一的标识一个线程
	private static ThreadLocal<Session> threadLocal=new ThreadLocal<Session>();
	
	static{
		 sf= new Configuration().configure("config/hibernate.cfg.xml").buildSessionFactory();
	}
	
	//获取session
	
	public static Session getSession() {
		//首先获取线程里面的标识
		Session session = threadLocal.get();
		
		if(null!=session){
			//说明session不是第一次调用,调用了很多次,直接返回
			return session;
		}
		//如果为空,说明是第一次调用,就打开session
		
		session=sf.openSession();
		threadLocal.set(session);
		//开起事物
		session.beginTransaction();
		return session;
		
	}
	
	
	//关闭资源
	public static void  close() {
		
		Session session = threadLocal.get();
		
		if(null!=session){
			session.getTransaction().commit();
			session.close();
			//移除线程
			threadLocal.remove();
			
		}
		
		
	}

}

 HibernateUtils.java封装优化后代码 :

 

package com.my.utils;

import java.io.Serializable;

import org.hibernate.Session;

import com.sun.xml.internal.ws.Closeable;

/**
 * Description:编写传统的crud方法
 * Copyright (c) 2017 J.K
 * Program Name:HibernateUtils.java
 * Date:  2017年9月5日 下午3:30:12
 * 
 * @author  : 西瓜瓜 
 * @version : 1.0
 */
public class HibernateUtils extends HbaseUtils{
     
	/**
	 * 
	 * 添加数据
	 */
	public static void save(Object object) {
		
		Session session = getSession();
		//业务逻辑
		session.save(object);
		close();
	}
	/**
	 * 
	 * 删除数据
	 */
	public static void delete(Object object) {
		Session session = getSession();
		
	    session.delete(object);
	    close();
	}
	/**
	 * 
	 * 更新数据
	 */
	public static void update(Object object) {
        Session session = getSession();
		
	    session.update(object);
	    close();
	}
	/**
	 * 
	 * 查询数据
	 */
	public static <T>T query(Object id,Class clazz) {
		Session session = getSession();
		T t = (T) session.get(clazz, (Serializable) id);
		close();
		return t;
	}	
}

 Test测试类:

package com.my.test2;

import static org.junit.Assert.*;

import org.junit.Test;


import com.my.utils.HibernateUtils;

/**
 * Description:TODO
 * Copyright (c) 2017 J.K
 * Program Name:test2.java
 * Date:  2017年9月5日 下午3:58:06
 * 
 * @author  : 西瓜瓜 
 * @version : 1.0
 */
public class test2 {

	/**
	 * 增加
	 * @throws Exception
	 */
	@Test
	public void testSave() throws Exception {
		User user = new User();
		user.setUserName("西瓜3");
		user.setUserPassword("3333");
		HibernateUtils.save(user);
		
		
	}
	//更新
	@Test
	public void testUpdate() throws Exception {
		User user = HibernateUtils.query(2, User.class);
		user.setUserName("西瓜喵");
		user.setUserPassword("999");
		HibernateUtils.update(user);
		
		
	}
	
	@Test
	public void testDelete() throws Exception {
		User user = HibernateUtils.query(5, User.class);
		
		HibernateUtils.delete(user);
		
		
	}
	
	
}

  

 4.复合主键的用法

       1).什么是复合主键?

               现在有这样一张表:  People表

                 pName             pAddress              pJavaScore            pAndroidScore

            上面的这个表里面并没有设计主键id,我们要让用上面的pName 和pAddress 来共同做People表的主键,也就是说people有两个主键


       2). 复合主键的操作步骤:

            1>:将People实体类对象里面的两个主键抽取取为一个实体类  并且序列化(implements Serilizable)

            2>:在我们的主实体People类里面 添加我们的复合主键的实体对象(包装类的形式),并提供get and set方法

            3>:在我们的映射文件中添加如下配置
                   <!--用来配置咋们的复合主键的-->
                     <composite-id name="key">
                  <!--配置的是我们复合主键的属性-->
                     <key-property name="pName"></key-property>
                     <key-property name="pAddress"></key-property>
                    </composite-id>

           4>:编写测试类

 具体操作如下:

 

 1.people实体类;

package com.my.test905;

/**
 * Description:People实体类
 * Copyright (c) 2017 J.K
 * Program Name:People.java
 * Date:  2017年9月5日 下午2:03:05
 * 
 * @author  : 西瓜瓜 
 * @version : 1.0
 */
public class People {
	
	/**复合主键,将pname,paddress抽取出来重新建一个实体类
	 * 
	 */
    //private String pNname;
    //private String pAddress;
	
	
	private CompotionKey key;
    private String pJavsScore;
    private String pAndroidScore;
	public People() {
		super();
		// TODO Auto-generated constructor stub
	}
	public People(CompotionKey key, String pJavsScore, String pAndroidScore) {
		super();
		this.key = key;
		this.pJavsScore = pJavsScore;
		this.pAndroidScore = pAndroidScore;
	}
	public CompotionKey getKey() {
		return key;
	}
	public void setKey(CompotionKey key) {
		this.key = key;
	}
	public String getpJavsScore() {
		return pJavsScore;
	}
	public void setpJavsScore(String pJavsScore) {
		this.pJavsScore = pJavsScore;
	}
	public String getpAndroidScore() {
		return pAndroidScore;
	}
	public void setpAndroidScore(String pAndroidScore) {
		this.pAndroidScore = pAndroidScore;
	}
	@Override
	public String toString() {
		return "People [key=" + key + ", pJavsScore=" + pJavsScore + ", pAndroidScore=" + pAndroidScore + "]";
	}

}

 2.复合主键实体类CompotionKey类: 

 

package com.my.test905;

import java.io.Serializable;

/**
 * Description:复合主键实体类
 * Copyright (c) 2017 J.K
 * Program Name:CompotionKey.java
 * Date:  2017年9月5日 下午2:06:08
 * 
 * @author  : 西瓜瓜
 * @version : 1.0
 */
public class CompotionKey  implements Serializable{

	 private String pNname;
     private String pAddress;
	public CompotionKey() {
		super();
		// TODO Auto-generated constructor stub
	}
	public CompotionKey(String pNname, String pAddress) {
		super();
		this.pNname = pNname;
		this.pAddress = pAddress;
	}
	public String getpNname() {
		return pNname;
	}
	public void setpNname(String pNname) {
		this.pNname = pNname;
	}
	public String getpAddress() {
		return pAddress;
	}
	public void setpAddress(String pAddress) {
		this.pAddress = pAddress;
	}
	@Override
	public String toString() {
		return "CompotionKey [pNname=" + pNname + ", pAddress=" + pAddress + "]";
	}
     
     
}

  3.People.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.my.test905"  auto-import="true">
    <!--auto-import="true" :后面使用HQL语句时,自动导入,不需要写全路径 -->
 
    <class name="People" >
    
     <!--配置复合主键  -->
	    <composite-id name="key">
	    
		     <!--配置复合主键的属性  -->
		    <key-property name="pNname"   type="java.lang.String"></key-property>
		    <key-property name="pAddress"  type="java.lang.String"></key-property>	    
		    
	    </composite-id>
    
    <!-- 普通配置属性 -->
           
       <property name="pJavsScore"  type="java.lang.String"> </property>
                 
       <property name="pAndroidScore"  type="java.lang.String"> </property>
  
    </class>    
        
</hibernate-mapping>         
        

  4.测试类

package com.my.test905;

import static org.junit.Assert.*;

import org.hibernate.Session;
import org.junit.Test;
import com.my.utils.HibernateUtils;

/**
 * Description:测试类
 * Copyright (c) 2017 J.K
 * Program Name:Test905.java
 * Date:  2017年9月5日 下午2:17:49
 * 
 * @author  : 西瓜瓜 
 * @version : 1.0
 */
public class TestCompositeKey {

	@Test
	public void test1() throws Exception {
	
		
		
		//创建people对象
		People people = new People();
		people.setpJavsScore("90");
		people.setpAndroidScore("99");
		//创建Compotion对象
		CompotionKey compotionKey = new CompotionKey();
		
		compotionKey.setpNname("西瓜瓜");
		compotionKey.setpAddress("四川成都");
		people.setKey(compotionKey);
		
	   HibernateUtils.save(people);
		

	}
}

  5.hibernate.cfg.xml配置文件代码

 

 5.Set,List,Map集合的映射关系

 

   需求:一个淘宝的用户需要在下单的时候 下不同地址的单

          这样的数据关系在我们的数据库的结构中是怎样的呢?


     一个用户对应了多个地址  一对多  一对多的关系:我们是在多的一方来维护一 的一方的主键

         t_taobaouser(用户表)

              uId               uName              uPassword                uNickName(昵称)

               1                xiguagua                  123                       西瓜瓜


          t_address(地址表)

            address               u_id

            北京****路             1

            成都****路             1

 1 ).Set集合的映射关系

 

 

 TaoBaoUser.java实体类代码:

package com.my.set;

import java.util.HashSet;
import java.util.Set;

/**
 * Description:TODO
 * Copyright (c) 2017 J.K
 * Program Name:TaoBaoUser.java
 * Date:  2017年9月5日 下午7:56:05
 * 
 * @author  : 西瓜瓜
 * @version : 1.0
 */
public class TaoBaoUser {

	private int uId;
	private String uName;
	private String uPassword;
	private String uNickname;//昵称
	//一个用户对应多个类
	private Set<String> address=new HashSet<String>();
	public TaoBaoUser() {
		super();
		// TODO Auto-generated constructor stub
	}
	public TaoBaoUser(int uId, String uName, String uPassword, String uNickname, Set<String> address) {
		super();
		this.uId = uId;
		this.uName = uName;
		this.uPassword = uPassword;
		this.uNickname = uNickname;
		this.address = address;
	}
	public int getuId() {
		return uId;
	}
	public void setuId(int uId) {
		this.uId = uId;
	}
	public String getuName() {
		return uName;
	}
	public void setuName(String uName) {
		this.uName = uName;
	}
	public String getuPassword() {
		return uPassword;
	}
	public void setuPassword(String uPassword) {
		this.uPassword = uPassword;
	}
	public String getuNickname() {
		return uNickname;
	}
	public void setuNickname(String uNickname) {
		this.uNickname = uNickname;
	}
	public Set<String> getAddress() {
		return address;
	}
	public void setAddress(Set<String> address) {
		this.address = address;
	}
	@Override
	public String toString() {
		return "TaoBaoUser [uId=" + uId + ", uName=" + uName + ", uPassword=" + uPassword + ", uNickname=" + uNickname
				+ ", address=" + address + "]";
	}
	
	
}

  TaoBaoUser.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.my.set" >
    <!--auto-import="true" :后面使用HQL语句时,自动导入,不需要写全路径 -->
 
    <class name="TaoBaoUser" table="t_taobaouser" >
     <!--配置主键  -->
	     <id name="uId"  column="u_id">
	        
	         <generator class="native"></generator>
	     </id>
    
    <!-- 普通配置属性 -->
         
       <property name="uName" column="u_name"  type="java.lang.String"> </property>
                 
       <property name="uPassword" column="u_pwd"  type="java.lang.String"> </property>
  
        <property name="uNickname" column="u_nickname"  type="java.lang.String"> </property>
  
  
    <!--配置地址address,集合映射  -->
  
     <set name="address" table="t_address">
        <!--此处的B_id等于上面的uId值,相当于在t_address表中的主键  
            element会自动使用上面集合中的值
必须有type类型,不然运行报错 --> <key column="B_id"></key> <element column="address" type="java.lang.String"></element> </set> </class> </hibernate-mapping>

  Test类代码:

 

package com.my.set;

import static org.junit.Assert.*;

import java.util.Set;

import org.junit.Test;

import com.my.utils.HibernateUtils;

/**
 * Description:TODO
 * Copyright (c) 2017 J.K
 * Program Name:TestSet.java
 * Date:  2017年9月5日 下午8:12:08
 * 
 * @author  : 西瓜瓜 
 * @version : 1.0
 */
public class TestSet {

	@Test
	public void test1() throws Exception {
		
		TaoBaoUser taoBaoUser = new TaoBaoUser();
		taoBaoUser.setuName("张三");
		taoBaoUser.setuPassword("123");
		taoBaoUser.setuNickname("西瓜");
		Set<String> address = taoBaoUser.getAddress();
		address.add("成都");
		address.add("上海");
		address.add("北京");
		HibernateUtils.save(taoBaoUser);
TaoBaoUser taoBaoUser2 = new TaoBaoUser(); taoBaoUser2.setuName("李四"); taoBaoUser2.setuPassword("222"); taoBaoUser2.setuNickname("哈哈"); Set<String> address2 = taoBaoUser2.getAddress(); address2.add("福建"); address2.add("湖南"); address2.add("澳门");
HibernateUtils.save(taoBaoUser2); } }

   2 ).List集合的映射关系

 

 TaoBaoUser.java实体类代码:

package com.my.list;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Description:TODO
 * Copyright (c) 2017 J.K
 * Program Name:TaoBaoUser.java
 * Date:  2017年9月5日 下午7:56:05
 * 
 * @author  : 西瓜瓜 
 * @version : 1.0
 */
public class TaoBaoUser {

	private int uId;
	private String uName;
	private String uPassword;
	private String uNickname;
	//一个用户对应多个类
	private List<String> address=new ArrayList<String>();
	public TaoBaoUser() {
		super();
		// TODO Auto-generated constructor stub
	}
	public TaoBaoUser(int uId, String uName, String uPassword, String uNickname, List<String> address) {
		super();
		this.uId = uId;
		this.uName = uName;
		this.uPassword = uPassword;
		this.uNickname = uNickname;
		this.address = address;
	}
	public int getuId() {
		return uId;
	}
	public void setuId(int uId) {
		this.uId = uId;
	}
	public String getuName() {
		return uName;
	}
	public void setuName(String uName) {
		this.uName = uName;
	}
	public String getuPassword() {
		return uPassword;
	}
	public void setuPassword(String uPassword) {
		this.uPassword = uPassword;
	}
	public String getuNickname() {
		return uNickname;
	}
	public void setuNickname(String uNickname) {
		this.uNickname = uNickname;
	}
	public List<String> getAddress() {
		return address;
	}
	public void setAddress(List<String> address) {
		this.address = address;
	}
	@Override
	public String toString() {
		return "TaoBaoUser [uId=" + uId + ", uName=" + uName + ", uPassword=" + uPassword + ", uNickname=" + uNickname
				+ ", address=" + address + "]";
	}
	
	
}

 

 

 TaoBaoUser.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.my.list" >
    <!--auto-import="true" :后面使用HQL语句时,自动导入,不需要写全路径 -->
 
    <class name="TaoBaoUser" table="t_taobaouser_list" >
     <!--配置主键  -->
	     <id name="uId"  column="u_id">
	        
	         <generator class="native"></generator>
	     </id>
    
    <!-- 普通配置属性 -->
         
       <property name="uName" column="u_name"  type="java.lang.String"> </property>
                 
       <property name="uPassword" column="u_pwd"  type="java.lang.String"> </property>
  
        <property name="uNickname" column="u_nickname"  type="java.lang.String"> </property>
  
  
    <!--配置地址address,集合映射  -->
  
     <!-- <set name="address" table="t_address_list">
                         此处的B_id等于上面的uId值,相当于在t_address表中的主键  
            element会自动使用上面集合中的值
       
        <key column="B_id"></key>
        
        <element column="address" type="java.lang.String"></element>
     
     </set> -->
  
  <list name="address" table="t_address_list">
  
    <key column="B_id"></key>
    
    <!--List必须添加list_index 列,因为list是有序的,这个列的值不需要写,是用来自动创建以便维护的 ,set是无序的 -->
    <list-index  column="bianhao" ></list-index>
  
    <element column="address" type="java.lang.String"></element>
  
  
  
  </list>
  

    </class>    
        
</hibernate-mapping>         
        

 

 Test类代码:

 

package com.my.list;

import static org.junit.Assert.*;

import java.util.List;
import org.junit.Test;
import com.my.utils.HibernateUtils;

/**
 * Description:TODO
 * Copyright (c) 2017 J.K
 * Program Name:TestSet.java
 * Date:  2017年9月5日 下午8:12:08
 * 
 * @author  : 西瓜瓜 
 * @version : 1.0
 */
public class TestList {

	@Test
	public void test1() throws Exception {
		
		TaoBaoUser taoBaoUser = new TaoBaoUser();
		taoBaoUser.setuName("张三");
		taoBaoUser.setuPassword("123");
		taoBaoUser.setuNickname("西瓜");
		List<String> address = taoBaoUser.getAddress();
		address.add("成都");
		address.add("上海");
		address.add("北京");
		HibernateUtils.save(taoBaoUser);

		TaoBaoUser taoBaoUser2 = new TaoBaoUser();
		taoBaoUser2.setuName("李四");
		taoBaoUser2.setuPassword("222");
		taoBaoUser2.setuNickname("哈哈");
		List<String> address2 = taoBaoUser2.getAddress();
		address2.add("福建");
		address2.add("湖南");
		address2.add("澳门");

		HibernateUtils.save(taoBaoUser2);
		
	}
	
	
}

  3).Map集合的映射关系

 

 

  TaoBaoUser.java实体类代码:

package com.my.map;

import java.util.HashMap;
import java.util.Map;

/**
 * Description:TODO
 * Copyright (c) 2017 J.K
 * Program Name:TaoBaoUser.java
 * Date:  2017年9月5日 下午7:56:05
 * 
 * @author  : 西瓜瓜
 * @version : 1.0
 */
public class TaoBaoUser {

	private int uId;
	private String uName;
	private String uPassword;
	private String uNickname;
	//一个用户对应多个类
	private Map<String, String> address=new HashMap<String,String>();
	public TaoBaoUser() {
		super();
		// TODO Auto-generated constructor stub
	}
	public TaoBaoUser(int uId, String uName, String uPassword, String uNickname, Map<String, String> address) {
		super();
		this.uId = uId;
		this.uName = uName;
		this.uPassword = uPassword;
		this.uNickname = uNickname;
		this.address = address;
	}
	public int getuId() {
		return uId;
	}
	public void setuId(int uId) {
		this.uId = uId;
	}
	public String getuName() {
		return uName;
	}
	public void setuName(String uName) {
		this.uName = uName;
	}
	public String getuPassword() {
		return uPassword;
	}
	public void setuPassword(String uPassword) {
		this.uPassword = uPassword;
	}
	public String getuNickname() {
		return uNickname;
	}
	public void setuNickname(String uNickname) {
		this.uNickname = uNickname;
	}
	public Map<String, String> getAddress() {
		return address;
	}
	public void setAddress(Map<String, String> address) {
		this.address = address;
	}
	@Override
	public String toString() {
		return "TaoBaoUser [uId=" + uId + ", uName=" + uName + ", uPassword=" + uPassword + ", uNickname=" + uNickname
				+ ", address=" + address + "]";
	}
	
	
	
}

  TaoBaoUser.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.my.map" >
    <!--auto-import="true" :后面使用HQL语句时,自动导入,不需要写全路径 -->
 
    <class name="TaoBaoUser" table="t_taobaouser_map" >
     <!--配置主键  -->
	     <id name="uId"  column="u_id">
	        
	         <generator class="native"></generator>
	     </id>
    
    <!-- 普通配置属性 -->
         
       <property name="uName" column="u_name"  type="java.lang.String"> </property>
                 
       <property name="uPassword" column="u_pwd"  type="java.lang.String"> </property>
  
        <property name="uNickname" column="u_nickname"  type="java.lang.String"> </property>
  
       <!--==================================================================================  -->
  
    <!--配置地址address,集合映射  -->
  
     <!-- <set name="address" table="t_address_list">
                         此处的B_id等于上面的uId值,相当于在t_address表中的主键  
            element会自动使用上面集合中的值
       
        <key column="B_id"></key>
        
        <element column="address" type="java.lang.String"></element>
     
     </set> -->
     
     <!--==================================================================================  -->
  
  <!-- <list name="address" table="t_address_list">
  
    <key column="B_id"></key>
    
    List必须添加list_index 列,因为list是有序的,这个列的值不需要写,是用来自动创建以便维护的 
    <list-index  column="bianhao" ></list-index>
  
    <element column="address" type="java.lang.String"></element>
  
  
  
  </list>
   -->
       <!--==================================================================================  -->
  
     <map name="address" table="t_address_map">
     
     <key column="B_id"></key>
     
     <!--map-key表示上面这个集合中的key对应的列名叫什么 -->
     <map-key column="bianhao"  type="java.lang.String"></map-key>
     <!--map集合中value对应的字段  -->
     <element column="address" type="java.lang.String"></element>
     
     
     
     </map>
  
  
  
    </class>    
        
</hibernate-mapping>         
        

  Test类代码:

 

package com.my.map;

import static org.junit.Assert.*;

import java.util.List;
import java.util.Map;

import org.junit.Test;
import com.my.utils.HibernateUtils;

/**
 * Description:TODO
 * Copyright (c) 2017 J.K
 * Program Name:TestSet.java
 * Date:  2017年9月5日 下午8:12:08
 * 
 * @author  : 西瓜瓜
 * @version : 1.0
 */
public class TestMap {

	@Test
	public void test1() throws Exception {
		
		TaoBaoUser taoBaoUser = new TaoBaoUser();
		taoBaoUser.setuName("张三");
		taoBaoUser.setuPassword("123");
		taoBaoUser.setuNickname("西瓜");
		Map<String, String> address = taoBaoUser.getAddress();
		address.put("地址1","成都");
		address.put("地址2","上海");
		address.put("地址3","北京");
		HibernateUtils.save(taoBaoUser);
	
	}

}

6.继承映射关系

 

        思考: 假设在你的程序中是存在继承关系的,那么继承关系在我们的映射文件中应该怎样来表示呢?

 

                   Animal表

 


                   Dog extends Animal

 


                    Fish extends Animal

 


            思考下该存储呢?

 

 

                  t_animal表

 

                    id                                         name                               gender

 

 

 

                    t_fish表 

                    fishCoatCount                        type                                animalId

 


                    t_dog表

 

                      num                                    type                                 animalId

 


------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

                    t_dog表

 


                       id                                       type                                   gender                            name

 

 

 

                     t_fish表

 


                       id                                      type                                   gender                             name

 


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

      4>:所有的类都对应了同一个表

                  t_animal表

 


                       id                          name                      gender                    category_type(分类)                       type_dog                      type_fish                  fishCoatCount                   num

 

 

 

 

 

7.一对多,多对一,多对多,一对一 的映射关系

 

   1).一对多的映射

          需求:现在需要做一个系统来管理公司的员工和部门

                一个部门有多个员工 。 这就是一对多的关系===>员工 ""的一方来维护的是 " "的一方的外键;

          分析需求:

               假设我们需要使用JAVA类来描述这个关系:

              t_dept表:

               deptId                 deptName                       deptAddress

                   1                 JAVAEE教学部                    18楼3号

                   2                 WEB前端教学部                   18楼6号


              t_emp表:

               empId                  empName                   empNum (编号)            deptId

                  1                         张三                            525                                 1

                  2                         李四                            526                                 2


            编写映射文件重要

                   接下来配置部门和员工之间的关系 一对多的关系

                    cascade:级联
                    save-update:级联保存和更新
                    delete:级联删除
                    all:相当于上面的并集

                 *级联保存和更新经常用,但是级联删除基本不用, 因为他会设计到多张表,删除一张表,下面的表全部都删除了

            一般设置级联设置 关联的关系上的 一对多 ,多对一

        一对多步骤:

 

 Dept.java代码:

 

package com.my.oneTomany;

import java.util.HashSet;
import java.util.Set;

/**
 * Description:部门表
 * Copyright (c) 2017 J.K
 * Program Name:Dept.java
 * Date:  2017年9月5日 下午9:00:38
 * 
 * @author  : 西瓜瓜
 * @version : 1.0
 */
public class Dept {

	private int deptId;
	private String deptName;
	private String deptAddress;
	//部门下面的员工,用集合来表示
	private Set<Employee> emps=new HashSet<Employee>();
	public Dept() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Dept(int deptId, String deptName, String deptAddress, Set<Employee> emps) {
		super();
		this.deptId = deptId;
		this.deptName = deptName;
		this.deptAddress = deptAddress;
		this.emps = emps;
	}
	public int getDeptId() {
		return deptId;
	}
	public void setDeptId(int deptId) {
		this.deptId = deptId;
	}
	public String getDeptName() {
		return deptName;
	}
	public void setDeptName(String deptName) {
		this.deptName = deptName;
	}
	public String getDeptAddress() {
		return deptAddress;
	}
	public void setDeptAddress(String deptAddress) {
		this.deptAddress = deptAddress;
	}
	public Set<Employee> getEmps() {
		return emps;
	}
	public void setEmps(Set<Employee> emps) {
		this.emps = emps;
	}
	@Override
	public String toString() {
		return "Dept [deptId=" + deptId + ", deptName=" + deptName + ", deptAddress=" + deptAddress + ", emps=" + emps
				+ "]";
	}
	

}

 

 Employee代码:

 

package com.my.oneTomany;

/**
 * Description:员工表
 * Copyright (c) 2017 J.K
 * Program Name:Employee.java
 * Date:  2017年9月5日 下午8:58:57
 * 
 * @author  : 西瓜瓜 
 * @version : 1.0
 */
public class Employee {
 
	private int empId;
	private String empName;
	private String empAddress;
	private String empNum;//员工编号
	//员工所对应的部门
	private Dept dept=new Dept();
	
	public Employee() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Employee(int empId, String empName, String empAddress, String empNum, Dept dept) {
		super();
		this.empId = empId;
		this.empName = empName;
		this.empAddress = empAddress;
		this.empNum = empNum;
		this.dept = dept;
	}
	public int getEmpId() {
		return empId;
	}
	public void setEmpId(int empId) {
		this.empId = empId;
	}
	public String getEmpName() {
		return empName;
	}
	public void setEmpName(String empName) {
		this.empName = empName;
	}
	public String getEmpAddress() {
		return empAddress;
	}
	public void setEmpAddress(String empAddress) {
		this.empAddress = empAddress;
	}
	public String getEmpNum() {
		return empNum;
	}
	public void setEmpNum(String empNum) {
		this.empNum = empNum;
	}
	public Dept getDept() {
		return dept;
	}
	public void setDept(Dept dept) {
		this.dept = dept;
	}
	@Override
	public String toString() {
		return "Employee [empId=" + empId + ", empName=" + empName + ", empAddress=" + empAddress + ", empNum=" + empNum
				+ ", dept=" + dept + "]";
	}
	
	
	
}

 Dept.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.my.oneTomany" >
    <!--auto-import="true" :后面使用HQL语句时,自动导入,不需要写全路径 -->
 
    <class name="Dept" table="t_dept" >
     <!--配置部门表主键  -->
	     <id name="deptId"  column="d_id">
	        
	         <generator class="native"></generator>
	     </id>
    
    <!-- 普通配置属性 -->
         
       <property name="deptName" column="d_name"  type="java.lang.String"> </property>
                 
       <property name="deptAddress" column="d_address"  type="java.lang.String"> </property>
  
  
       <!--==================================================================================  -->
  
    <!--配置员工表,集合映射  -->
       <!--
        cascade 级联:
        
       cascade="save-update":级联保存和更新
       cascade="delete":级联删除
       cascade="all":级联保存,删除,更新,相当于上面的并集
       
         -->
  
  
     <set name="emps" table="t_employee" cascade="all">
                         
       <!-- 员工表主键 -->
        <key column="deptId"></key>
        
        <one-to-many class="Employee"/>
     
     </set> 

    </class>    
        
</hibernate-mapping>         

 

 Employee.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.my.oneTomany" >
    <!--auto-import="true" :后面使用HQL语句时,自动导入,不需要写全路径 -->
 
    <class name="Employee" table="t_employee" >
     <!--配置员工表主键  -->
	     <id name="empId"  column="e_id">
	        
	         <generator class="native"></generator>
	     </id>
    
    <!-- 普通配置属性 -->
         
       <property name="empName" column="e_name"  type="java.lang.String"> </property>
                 
       <property name="empAddress" column="e_address"  type="java.lang.String"> </property>
  
        <property name="empNum" column="e_num"  type="java.lang.String"> </property>
  
       <!--单向配置就好了,这边不用写  -->

    </class>    
        
</hibernate-mapping>         
        

  Test代码:

package com.my.oneTomany;

import static org.junit.Assert.*;

import java.util.Set;

import org.junit.Test;

import com.my.utils.HibernateUtil;
import com.my.utils.HibernateUtils;

/**
 * Description:TODO
 * Copyright (c) 2017 J.K
 * Program Name:Test.java
 * Date:  2017年9月5日 下午9:34:00
 * 
 * @author  : 西瓜瓜
 * @version : 1.0
 */
public class Test001 {

	/**
	 * 测试一对多:oneTomany
	 * @throws Exception
	 */
	@Test
	public void test01() throws Exception {
		
		Dept dept = new Dept();
		dept.setDeptName("张三");
		dept.setDeptAddress("成都");
		Set<Employee> emps = dept.getEmps();
		
		Employee employee = new Employee();
		employee.setEmpName("李四");
		employee.setEmpAddress("北京");
		employee.setEmpNum("1");
		emps.add(employee);
		
		Employee employee2 = new Employee();
		employee2.setEmpName("王五");
		employee2.setEmpAddress("上海");
		employee2.setEmpNum("2");
		emps.add(employee2);
		
		Employee employee3 = new Employee();
		employee3.setEmpName("小明");
		employee3.setEmpAddress("上海");
		employee3.setEmpNum("3");
		emps.add(employee3);
		
		
		
		/*HibernateUtils.save(employee);
		HibernateUtils.save(employee2);
		HibernateUtils.save(employee3);*/
		
		HibernateUtils.save(dept);
		

	}

	
} 

 2).多对一的映射:

       分析:多个员工对应一个部门

  

 Dept.java代码:和上面一样

 Employee代码和上面一样

  Dept.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.my.manyToone" >
    <!--auto-import="true" :后面使用HQL语句时,自动导入,不需要写全路径 -->
 
    <class name="Dept" table="t_dept" >
     <!--配置部门表主键  -->
	     <id name="deptId"  column="d_id">
	        
	         <generator class="native"></generator>
	     </id>
    
    <!-- 普通配置属性 -->
         
       <property name="deptName" column="d_name"  type="java.lang.String"> </property>
                 
       <property name="deptAddress" column="d_address"  type="java.lang.String"> </property>
        
//此处不用写many-to-one,只在一方写就可以 </class> </hibernate-mapping>

   Employee.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.my.manyToone" >
    <!--auto-import="true" :后面使用HQL语句时,自动导入,不需要写全路径 -->
 
    <class name="Employee" table="t_employee" >
     <!--配置部门表主键  -->
	     <id name="empId"  column="e_id">
	        
	         <generator class="native"></generator>
	     </id>
    
    <!-- 普通配置属性 -->
         
       <property name="empName" column="e_name"  type="java.lang.String"> </property>
                 
       <property name="empAddress" column="e_address"  type="java.lang.String"> </property>
           
       <property name="empNum" column="e_num"  type="java.lang.String"> </property>
      
 
 
         <many-to-one name="dept" class="Dept" column="d_id"  cascade="all"></many-to-one>
 

  
    </class>    
        
</hibernate-mapping>         
        

  Test代码:

 

package com.my.manyToone;

import static org.junit.Assert.*;

import org.junit.Test;

import com.my.utils.HibernateUtils;



/**
 * Description:TODO
 * Copyright (c) 2017 J.K
 * Program Name:Test001.java
 * Date:  2017年9月6日 上午9:24:44
 * 
 * @author  : 西瓜瓜
 * @version : 1.0
 */
public class Test001 {
        //测试many-to-one
	@Test
	public void test1() throws Exception {
		
		Employee employee = new Employee();
		
		employee.setEmpName("张三");
		employee.setEmpAddress("成都");
		employee.setEmpNum("2");
		
		
       Employee employee2 = new Employee();
		
		employee2.setEmpName("李四");
		employee2.setEmpAddress("成都2");
		employee2.setEmpNum("2");
		
		
		Dept dept = employee.getDept();
		dept.setDeptName("张五");
		dept.setDeptAddress("广州");
		
		HibernateUtils.save(employee);
		HibernateUtils.save(employee2);
	}
	
	
}

  3).多对多的关系映射:

          需求:程序员和项目之间的关系(编写一个项目的管理系统)  程序员 和 项目

            

                     一个程序员可以开发多个项目 程序员----->项目(一对多的关系)

                     一个项目是由多个开发人员来进行开发 项目----->程序员(一对多的关系)

             综上所述 :
                       两个一对多的关系就构成了 多对多的关系

                       多对多的关系在我们设计表的时候 是不是也会拆分成两个一对多,也就是说会映入咋们的中间表

             t_project(项目表)

              proId                     proName                       proStartTime               proEndTime                    proDesc(项目描述)

                 1                 医院床边信息娱乐系统          项目开始时间                  2017-8-10                  这个项目是医院娱乐系统

                 2                        环境系统                         2016-2-1                        2016-2-1                  这个项目是环境系统


             t_devloper(开发人员表)

              devId                          devName                     devDes                           devGender                   devTel

                 1                               张三丰                       真正的码农                          男                        156xxxxxxxx

                  2                              毛小雨                         二货大师                            女                        134xxxxxxxx

 

             t_relation(关系表)-------该表没有实体类,但会在数据库中显示

              proId                           devId

                  1                              1

                  1                              2

                  2                              1


         上面就是我们的表结构的分析

 

     Project的一方的配置

            <!--配置的是多对多的集合映射-->

           <set name="devs" table="t_relation" cascade="all">


              <!--上面的这个key你记住就是映射的当前的类的主键-->
                    <key column="pro_id"></key>


               <!--配置的是相关联的另外一张表, column:配置的是对方的主键在关系表中映射的这个值的列名,class:配置的是对方的这个名字-->
                     
              <many-to-many column="dev_id" class="Developer"></many-to-many>
            </set>


       Developer一方的配置

                <!--配置的是多对多的集合映射-->
              <set name="pros" table="t_relation" cascade="all">


                <!--上面的这个key你记住就是映射的当前的类的主键-->
                 <key column="dev_id"></key>


                  <!--配置的是相关联的另外一张表
                     column:配置的是对方的主键在关系表中映射的这个值的列名,class:配置的是对方的这个名字-->


                 <many-to-many column="pro_id" class="Project"></many-to-many>
             </set>

       注意:在实际开发中可以只是配置一方,多对多在项目开发的时候, 是没有特定的 ,谁维护谁的说法 ;也就是说你可以使用任意的以防来维护这个关联的关系

具体步骤如下:

Developer.java代码:

package com.my.manyTomany;

import java.util.HashSet;
import java.util.Set;

/**
 * Description:开发人员类
 * Copyright (c) 2017 J.K
 * Program Name:Developer.java
 * Date:  2017年9月6日 下午2:09:48
 * 
 * @author  : 西瓜瓜
 * @version : 1.0
 */
public class Developer {
	private int  devId;
	private String devName;
	private String devGender;//性别
	private String devDes;  //描述    
	private String devTel; 
	//一个开发人员开发多个项目
	private Set<Project>projects=new HashSet<Project>();
	
	
	public Developer() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Developer(int devId, String devName, String devGender, String devDes, String devTel, Set<Project> projects) {
		super();
		this.devId = devId;
		this.devName = devName;
		this.devGender = devGender;
		this.devDes = devDes;
		this.devTel = devTel;
		this.projects = projects;
	}
	public int getDevId() {
		return devId;
	}
	public void setDevId(int devId) {
		this.devId = devId;
	}
	public String getDevName() {
		return devName;
	}
	public void setDevName(String devName) {
		this.devName = devName;
	}
	public String getDevGender() {
		return devGender;
	}
	public void setDevGender(String devGender) {
		this.devGender = devGender;
	}
	public String getDevDes() {
		return devDes;
	}
	public void setDevDes(String devDes) {
		this.devDes = devDes;
	}
	public String getDevTel() {
		return devTel;
	}
	public void setDevTel(String devTel) {
		this.devTel = devTel;
	}
	public Set<Project> getProjects() {
		return projects;
	}
	public void setProjects(Set<Project> projects) {
		this.projects = projects;
	}
	@Override
	public String toString() {
		return "Developer [devId=" + devId + ", devName=" + devName + ", devGender=" + devGender + ", devDes=" + devDes
				+ ", devTel=" + devTel + ", projects=" + projects + "]";
	}
	

}

  project.java代码:

package com.my.manyTomany;


import java.sql.Date;
import java.util.HashSet;
import java.util.Set;

/**
 * Description:项目表
 * Copyright (c) 2017 J.K
 * Program Name:Project.java
 * Date:  2017年9月6日 下午2:05:01
 * 
 * @author  : 西瓜瓜 
 * @version : 1.0
 */
public class Project {

	private int  proId ;
	private String proName;
	private Date  proStartTime;//项目开始时间
	private Date  proEndTime;//项目结束时间
	private String proDesc;//项目详细信息
	//一个项目对应多个开发人员
	private Set<Developer> developers=new HashSet<Developer>();
	
	
	public Project() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Project(int proId, String proName, Date proStartTime, Date proEndTime, String proDesc,
			Set<Developer> developers) {
		super();
		this.proId = proId;
		this.proName = proName;
		this.proStartTime = proStartTime;
		this.proEndTime = proEndTime;
		this.proDesc = proDesc;
		this.developers = developers;
	}
	public int getProId() {
		return proId;
	}
	public void setProId(int proId) {
		this.proId = proId;
	}
	public String getProName() {
		return proName;
	}
	public void setProName(String proName) {
		this.proName = proName;
	}
	public Date getProStartTime() {
		return proStartTime;
	}
	public void setProStartTime(Date proStartTime) {
		this.proStartTime = proStartTime;
	}
	public Date getProEndTime() {
		return proEndTime;
	}
	public void setProEndTime(Date proEndTime) {
		this.proEndTime = proEndTime;
	}
	public String getProDesc() {
		return proDesc;
	}
	public void setProDesc(String proDesc) {
		this.proDesc = proDesc;
	}
	public Set<Developer> getDevelopers() {
		return developers;
	}
	public void setDevelopers(Set<Developer> developers) {
		this.developers = developers;
	}
	@Override
	public String toString() {
		return "Project [proId=" + proId + ", proName=" + proName + ", proStartTime=" + proStartTime + ", proEndTime="
				+ proEndTime + ", proDesc=" + proDesc + ", developers=" + developers + "]";
	}

}

  Developer.hbm2.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.my.manyTomany" >
    <!--auto-import="true" :后面使用HQL语句时,自动导入,不需要写全路径 -->
 
    <class name="Developer" table="d_Developer" >
     <!--配置部门表主键  -->
	     <id name="devId"  column="d_devId">
	        
	         <generator class="native"></generator>
	     </id>
    
    <!-- 普通配置属性 -->
         
       <property name="devName"     type="java.lang.String"> </property>
       <property name="devGender"   type="java.lang.String"> </property>
       <property name="devDes"      type="java.lang.String"> </property>
       <property name="devTel"      type="java.lang.String"> </property>
  
     <!--==========================  -->
   
     <set name="projects" table="t_relation" cascade="all">
        
        <key column="d_devId"></key>
    
        <many-to-many class="Project" column="t_proId"></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.my.manyTomany" >
    <!--auto-import="true" :后面使用HQL语句时,自动导入,不需要写全路径 -->
 
    <class name="Project" table="t_project" >
     <!--配置部门表主键  -->
	     <id name="proId"  column="t_proId">
	        
	         <generator class="native"></generator>
	     </id>
    
    <!-- 普通配置属性 -->
         
       <property name="proName"  type="java.lang.String"> </property>
                 
       <property name="proStartTime"   type="java.sql.Date"> </property>
  
       <property name="proEndTime"   type="java.sql.Date"> </property>
                 
       <property name="proDesc"   type="java.lang.String"> </property>
  
      <!-- ========== -->
      <!--table="t_relation":表示映入到第三张表,关系表,数据库有表,但java中没有实体类  -->
     
    <!--   <set name="developers" table="t_relation"  cascade="all">
  
        <key column="t_proId"> </key>
  
        <many-to-many class="Developer" column="d_devId"></many-to-many>
                 此处可以只写一边,不需要两边都写
      </set> -->
  
    </class>    
        
</hibernate-mapping>         
        

  Test代码;

package com.my.manyTomany;

import static org.junit.Assert.*;

import java.sql.Date;
import java.util.Set;

import org.junit.Test;

import com.my.utils.HibernateUtils;

/**
 * Description:TODO
 * Copyright (c) 2017 J.K
 * Program Name:Test.java
 * Date:  2017年9月6日 下午2:34:15
 * 
 * @author  : 西瓜瓜
 * @version : 1.0
 */
public class Test001 {

	/**
	 * 一个项目对应多个程序员
	 * @throws Exception
	 */
	@Test
	public void test01() throws Exception {
		
		
		//一个项目
		Project project = new Project();
		project.setProName("西瓜瓜娱乐系统");
		project.setProStartTime(new Date(117, 1, 1));
		project.setProEndTime(new Date(118, 1, 1));
		project.setProDesc("这是西瓜瓜娱乐系统");
		
		//多个程序员
		Set<Developer> developers = project.getDevelopers();
		//表示第一个程序员
		Developer developer1 = new Developer();
		developer1.setDevName("张三");
		developer1.setDevGender("男");
		developer1.setDevDes("是一个有干劲的程序员");
		developer1.setDevTel("15678900000");;
	    developers.add(developer1);
	  //表示第二个程序员
	  		Developer developer2 = new Developer();
	  		developer2.setDevName("李四");
	  		developer2.setDevGender("女");
	  		developer2.setDevDes("是一个漂亮的程序员");
	  		developer2.setDevTel("15345678900");;
	  	    developers.add(developer2);
	    
	  	//表示第三个程序员
			Developer developer3 = new Developer();
			developer3.setDevName("西瓜瓜");
			developer3.setDevGender("男");
			developer3.setDevDes("是一个风华正茂的程序员");
			developer3.setDevTel("17898657788");;
		    developers.add(developer3);
	    //保存
	    
	    HibernateUtils.save(project);

		
	}
	/**
	 * 一个程序员对应多个项目
	 * @throws Exception
	 */
	
	@Test
	public void test02() throws Exception {
		//一个程序员
		Developer developer = new Developer();
		developer.setDevName("张三");
		developer.setDevGender("男");
		developer.setDevDes("是一个有干劲的程序员");
		developer.setDevTel("15678900000");;
		
		Set<Project> projects = developer.getProjects();
		//第一个项目
		Project project = new Project();
		project.setProName("医院系统");
		project.setProStartTime(new Date(117, 3, 1));
		project.setProEndTime(new Date(118, 3, 1));
		project.setProDesc("这是医院娱乐系统");
		projects.add(project);
		//第二个项目
		Project project2 = new Project();
		project2.setProName("图书系统");
		project2.setProStartTime(new Date(117, 7, 1));
		project2.setProEndTime(new Date(118, 7, 1));
		project2.setProDesc("这是图书管理系统");
		projects.add(project2);
		//第三个项目
		Project project3 = new Project();
		project3.setProName("商城系统");
		project3.setProStartTime(new Date(117, 6, 1));
		project3.setProEndTime(new Date(118, 6, 1));
		project3.setProDesc("这是商城娱乐系统");
		projects.add(project3);
		
		HibernateUtils.save(developer);
		
		
	}

}

4).一对一的关系映射:

      人和身份证的问题

              一个人----->一个身份证    人和身份证------>一对一

              一个身份证--->一个人      身份证和人------>一对一


             建表:

            t_people

              pId                     pName

               1                        张三

下面有几种情况:

           t_idcard

            cardId(primary key)                        cardNum                                     pId(fk)外键


            t_idcard  

            cardNum(primary key)                        pId

 

           t_idcard

            pId(primary key)                            cardNum

 

          1>:基于外键的映射

            人的一端配置

                   <!--下面就是配置的一对一的关联映射 没有外键的一方-->
                       <one-to-one name="idCard" class="IdCard" cascade="all"></one-to-one>

            身份证一端的配置
                      <!--下面就是配置的一对一的关联映射 有外键的一方-->
                        <many-to-one name="people" class="People" column="p_id" cascade="all"></many-to-one>

        注*:一对一的时候,一方配置one-to-one,另一方必须many-to-one

 下面为具体步骤:

 

Card.java代码:

package com.my.oneToone;

/**
 * Description:人和身份证
 * Copyright (c) 2017 J.K
 * Program Name:Card.java
 * Date:  2017年9月6日 下午7:25:02
 * 
 * @author  : 西瓜瓜 
 * @version : 1.0
 */
public class Card {

	private int cid;
	private String  cnum;//身份证编号
	private People people;
	public Card(int cid, String cnum, People people) {
		super();
		this.cid = cid;
		this.cnum = cnum;
		this.people = people;
	}
	public Card() {
		super();
		// TODO Auto-generated constructor stub
	}
	public int getCid() {
		return cid;
	}
	public void setCid(int cid) {
		this.cid = cid;
	}
	public String getCnum() {
		return cnum;
	}
	public void setCnum(String cnum) {
		this.cnum = cnum;
	}
	public People getPeople() {
		return people;
	}
	public void setPeople(People people) {
		this.people = people;
	}
	@Override
	public String toString() {
		return "Card [cid=" + cid + ", cnum=" + cnum + ", people=" + people + "]";
	}
	
	
}

 People.java代码: 

package com.my.oneToone;

/**
 * Description:人和身份证
 * Copyright (c) 2017 J.K
 * Program Name:People.java
 * Date:  2017年9月6日 下午7:24:46
 * 
 * @author  : 西瓜瓜
 * @version : 1.0
 */
public class People {

	private int pid;
	private String pname;
	private Card card;
	public People() {
		super();
		// TODO Auto-generated constructor stub
	}
	public People(int pid, String pname, Card card) {
		super();
		this.pid = pid;
		this.pname = pname;
		this.card = card;
	}
	public int getPid() {
		return pid;
	}
	public void setPid(int pid) {
		this.pid = pid;
	}
	public String getPname() {
		return pname;
	}
	public void setPname(String pname) {
		this.pname = pname;
	}
	public Card getCard() {
		return card;
	}
	public void setCard(Card card) {
		this.card = card;
	}
	@Override
	public String toString() {
		return "People [pid=" + pid + ", pname=" + pname + ", card=" + card + "]";
	}
	
}

  Card.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.my.oneToone" >
    <!--auto-import="true" :后面使用HQL语句时,自动导入,不需要写全路径 -->
 
    <class name="Card" table="t_card" >
     <!--配置部门表主键  -->
	     <id name="cid"  column="c_id">
	        
	         <generator class="native"></generator>
	     </id>
    
    <!-- 普通配置属性 -->
         
       <property name="cnum" column="c_num"  type="java.lang.String"> </property>
             
        <!--下面就是配置的一对一关联映射,有外键的一方;   多的一方维护一的 一方  -->    
      <!--  <many-to-one name="people" class="People" column="p_id"  cascade="all"></many-to-one> -->
      <!-- 交换一下位置 -->
            <one-to-one name="people" class="People" cascade="all"  ></one-to-one>
  
    </class>    
        
</hibernate-mapping> 

  People.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.my.oneToone" >
    <!--auto-import="true" :后面使用HQL语句时,自动导入,不需要写全路径 -->
 
    <class name="People" table="t_people" >
     <!--配置部门表主键  -->
	     <id name="pid"  column="p_id">
	        
	         <generator class="native"></generator>
	     </id>
    
    <!-- 普通配置属性 -->
         
       <property name="pname" column="p_name"  type="java.lang.String"> </property>
                 
       <!-- <one-to-one name="card" class="Card" cascade="all" ></one-to-one> -->
  
  <!--交换一下位置  -->
   <many-to-one name="card" class="Card" column="c_id"   cascade="all"></many-to-one>
  

    </class>    
        
</hibernate-mapping>              

  Test代码:

package com.my.oneToone;

import static org.junit.Assert.*;

import org.junit.Test;

import com.my.utils.HibernateUtils;

/**
 * Description:T测试类
 * Copyright (c) 2017 J.K
 * Program Name:TestoneToone.java
 * Date:  2017年9月6日 下午7:41:00
 * 
 * @author  : 西瓜瓜
 * @version : 1.0
 */
public class TestoneToone {
       //test01维护card,一对一
	@Test
	public void test1() throws Exception {
		Card card = new Card();
		card.setCnum("24512199010112943");
		People people = new People();
		people.setPname("张三");
		card.setPeople(people);
		
		HibernateUtils.save(card);
		
	//注意上面映射文件,互换测试时要交换一下位置就好了	
		
	}
	//Test02维护people,一对一
	@Test
	public void test2() throws Exception {
		
		People people = new People();
		people.setPname("毛小雨");
		Card card = new Card();
		card.setCnum("234567892943");
		people.setCard(card);
		
		HibernateUtils.save(people);
	
	}

}

  2>:基于主键的映射

             t_people表

                pId                                         Name

                  1                                          张三  


             t_idcard表

             pId(primary key fk)                    cardNum

                1                                          51352xxxxxxxx

 


           基于主键映射的 Idcard的映射类:

               <hibernate-mapping package="com.qf.one2one">
                               <class name="IdCard" table="t_idcard">
                                            <id name="pId">
                                                        <!-- foreign:表示的是要引用一个外键 -->
                                                            <generator class="foreign">
                                                                 <!--要告诉他要引用谁的主键 name="property"是不能变的 固定的 -->
                                                                          <param name="property">people</param>
                                                            </generator>
                                              </id>
                                             <!--配置的是普通的属性 -->
                                             <property name="cardNum"></property>

                                              <!--下面配置我们的这个关联信息 constrained:这个表示的是外键的意思-->
                                              <one-to-one name="people" class="People" constrained="true" cascade="all"></one-to-one>

                                </class>
                </hibernate-mapping>

 

 

具体操作步骤如下:

 Card.java代码:

package com.my.oneTooneZhujian;

/**
 * Description:TODO
 * Copyright (c) 2017 J.K
 * Program Name:Card.java
 * Date:  2017年9月7日 上午8:59:00
 * 
 * @author  : 西瓜瓜 
 * @version : 1.0
 */
public class Card {

	private int pid;
	
	private String cnum;//身份证号码
	private  People people;
	public Card() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Card(int pid, String cnum, People people) {
		super();
		this.pid = pid;
		this.cnum = cnum;
		this.people = people;
	}
	public int getPid() {
		return pid;
	}
	public void setPid(int pid) {
		this.pid = pid;
	}
	public String getCnum() {
		return cnum;
	}
	public void setCnum(String cnum) {
		this.cnum = cnum;
	}
	public People getPeople() {
		return people;
	}
	public void setPeople(People people) {
		this.people = people;
	}
	@Override
	public String toString() {
		return "Card [pid=" + pid + ", cnum=" + cnum + ", people=" + people + "]";
	}
}

  People.java代码:

package com.my.oneTooneZhujian;

/**
 * Description:人实体类
 * Copyright (c) 2017 J.K
 * Program Name:People.java
 * Date:  2017年9月7日 上午8:59:16
 * 
 * @author  : 西瓜瓜 
 * @version : 1.0
 */
public class People {

	private int pid;
	private String pname;
	public People() {
		super();
		// TODO Auto-generated constructor stub
	}
	public People(int pid, String pname) {
		super();
		this.pid = pid;
		this.pname = pname;
	}
	public int getPid() {
		return pid;
	}
	public void setPid(int pid) {
		this.pid = pid;
	}
	public String getPname() {
		return pname;
	}
	public void setPname(String pname) {
		this.pname = pname;
	}
	@Override
	public String toString() {
		return "People [pid=" + pid + ", pname=" + pname + "]";
	}

}

  Card.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.my.oneTooneZhujian" >
   
 
    <class name="Card" table="c_card" >
     <!--配置部门表主键  -->
	     <id name="pid"  column="p_id">
	        <!--外键  -->
	         <generator class="foreign">
	            <!--告诉是引用谁的外键来作为主键    ,name="property"  是固定的,不能变-->
	            <param name="property">people</param>
	         </generator>
	         
	     </id>
    
    <!-- 普通配置属性 -->
         
       <property name="cnum" column="c_num"  type="java.lang.String"> </property>
             
        
            <one-to-one name="people" class="People" constrained="true" cascade="all"  ></one-to-one>
  
    </class>    
        
</hibernate-mapping>         

  People.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.my.oneTooneZhujian" >
    <!--auto-import="true" :后面使用HQL语句时,自动导入,不需要写全路径 -->
 
    <class name="People" table="p_people"  >
     <!--配置部门表主键  -->
	     <id name="pid"  column="p_id">
	        
	         <generator class="native"></generator>
	     </id>
    
    <!-- 普通配置属性 -->
         
       <property name="pname"  type="java.lang.String"> </property>
             

    </class>    
        
</hibernate-mapping>         
        

  Test001.java代码:

package com.my.oneTooneZhujian;

import static org.junit.Assert.*;

import org.junit.Test;

import com.my.utils.HibernateUtils;

/**
 * Description:基于主键的映射----测试类
 * Copyright (c) 2017 J.K
 * Program Name:Test001.java
 * Date:  2017年9月7日 上午9:08:44
 * 
 * @author  : 西瓜瓜
 * @version : 1.0
 */
public class Test001 {

	/**
	 * @throws Exception
	 */
	@Test
	public void testName() throws Exception {
		
	    Card card = new Card();
		card.setCnum("5132xxxxxxxx");
		
	    People people = new People();
		people.setPname("张三");
		card.setPeople(people);
		
		HibernateUtils.save(card);
		
	}

}

8.HQL语句查询

    HQL: hibernate   query    langue

详细步骤:

 

 

 这里只列出TestHql.java代码: oneTomany包下面的代码和上面一样,省略不写了。

 详细见代码:

package com.my.HqlQuery;

import static org.junit.Assert.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Restrictions;
import org.hibernate.query.Query;
import org.junit.Test;

import com.my.oneTomany.Dept;
import com.my.utils.HibernateUtils;

/**
 * Description:Hql测试类
 * Copyright (c) 2017 J.K
 * Program Name:TestHql.java
 * Date:  2017年9月7日 下午3:23:47
 * 
 * @author  : 西瓜瓜
 * @version : 1.0
 */
public class TestHql {

	
	
	/**
	 * HQL语句的查询使用
	 */
	@Test
	public void OtherQuery() throws Exception {
		Session session = new Configuration().configure("config/hibernate.cfg.xml").buildSessionFactory().openSession();
		
		
		
		//查询出Dept类(对象)的全部列
		//Query query1 = session.createQuery("select d from Dept d");
		//Query query = session.createQuery("from Dept");
		//前面部分可以省略不写,从from开始写
		//List list = query.list();
		//System.out.println(list);   
		//带条件的查询
      //Query query = session.createQuery("select e from Employee e where e.empId < 3");

		
		//带条件的占位符
       //Query query = session.createQuery("select e from Employee e where e.empId < ?");
		//query.setInteger(0, 2);下标是从0开始的
		
		
		//给站位符取别名   :名字         下标也是从0开始的
		//Query query = session.createQuery("select e from Employee e where e.empId < :empId");
		//query.setParameter("empId", 2);
		
		
		//between  ?  and   ?
		//Query query = session.createQuery("select e from Employee e where e.empId  between  ?  and  ?");
		//query.setInteger(0, 1);
		//query.setInteger(1, 3);
		
		
		//between  ?  and   ?   取别名       此处就是查empId=1和empId=3之间的,包括1和3
		//Query query = session.createQuery("select e from Employee e where e.empId  between  :empId1  and  :empId2");
		//query.setParameter("empId1", 1);
		//query.setParameter("empId2", 3);
		
		
		
		//查询指定的列
		//Query query = session.createQuery("select e.empName,e.empAddress from Employee e ");
		//查询指定的列===>封装成的对象,并且还要将这两列生成有参构造函数
		//Query query=session.createQuery("select new Employee(e.empName,e.empNum) from Employee e");
		
		//聚合函数的查询
		//Query query = session.createQuery("select count(*) from User");
		//查询结果集的所有数量
		// Long number = (Long) query.uniqueResult();
		//System.out.println(number);
		
		
		
		/**
		 * 本地的SQL查询==
		 * 
		 * 这儿必须用  : createSQLQuery();
		 */
		Query query = session.createSQLQuery("select * from h_dept ");
	
		
	
		List list = query.list();
		System.out.println(list);
	}
	
	/**
	 * 分页查询
	 */
	@Test
	public void testSplitPage() throws Exception {
		Session session = new Configuration().configure("config/hibernate.cfg.xml").buildSessionFactory().openSession();
		//业务逻辑
		//Query query = session.createQuery("from new Employee (e.empName,e.empNum) from Employee e ");
		Query query = session.createQuery("select new User(u.uName,u.uPassword) from User u ");
               //先获取一共有多少数量
		 ScrollableResults results = query.scroll();
		//滚动到最后
		 results.last();
		//获取行数(条目数),下标从0开始的
		long counts= results.getRowNumber()+1;
		//打印条目数
		System.out.println("共有的行数:"+counts);
		//从第几页开始,     每页多少条数据(前提是必须要有3页以上的数据,否则每页查不到3条数据)
	    query.setFirstResult(1);
	    query.setMaxResults(3);
	    //最后遍历出来
	    List list=query.list();
	    System.out.println(list);
		

	}
	
	
	

	/**
	 * Criteria指定查询
	 */
	@Test
	public void testCretiria() throws Exception {
		Session session = new Configuration().configure("config/hibernate.cfg.xml").buildSessionFactory().openSession();
	
		Criteria criteria = session.createCriteria(Dept.class);
		/*//添加的条件
		criteria.add(Restrictions.idEq(1));
		//返回一个结果
		Dept dept = (Dept) criteria.uniqueResult();
		System.out.println(dept);*/
		
		
		
		
		Map<String, Object> maps = new HashMap<String,Object>();
		maps.put("deptId", 1);
		maps.put("deptName", "开发部");
		
		
		criteria.add(Restrictions.allEq(maps));
		
		//CriteriaImpl(com.my.oneTomany.Dept:this[][(deptName=开发部 and deptId=1)])
		System.out.println(criteria);
		
		
		
		//Criteria dept2 = criteria.add(Restrictions.allEq(maps));
		//CriteriaImpl(com.my.oneTomany.Dept:this[][(deptName=开发部 and deptId=1)])
		//System.out.println(dept2);
		


	}
	
	
	
}

  2).懒加载close之后使用数据的问题

 

               解决方案:使用Hibernate来强制代理对象初始化*
                 Hibernate.initialize(dept);

               解决方案二:在关闭session之前来使用一下这个数据
                  dept.getDeptAddress();

               解决方案三:关闭懒加载

              解决方案四:就是在close之前使用数据

 

 9.一级缓存,二级缓存

 

 1).一级缓存

 

        <1>.一级缓存也叫session缓存, 这个缓存是由session来进行管理的 ,不需要我们去进行管理,因为生命周期太短了,在session关闭之前有效 一旦session关闭了 那么 一级缓存也就没有了

 

        

        <2>.在session关闭之前,对象处于持久化状态,此时在数据库里面只有对应的记录,没有同步数据库,如果要想同步到数据库,(强制持久化的对象和数据库同步),就用session.flush();刷新,刷新之后就同步数据库了。

        例子:    Dept dept=(Dept)session.get(Dept.class,1);  //这个就是持久化状态,具体持久化内容见下面
                  

                      dept.setDeptName("张三");//这就是持久化状态

                      //在session关闭之前,对象处于持久化状态

                      session.flush();//刷新后,就同步到数据库了

                       session.close();

        //=====================================================

 

         <3>.  清空缓存的两个方法:
                session.clear(); //清空缓存里面的所有的内容

                session.evict(dept); //清空指定对象的缓存

    

      一级缓存是不能够在session之间共享数据(没用的原因)?

 

 2).二级缓存(主要就讲Hibernate整合Ehcache的问题)

 

   要想在session之间能够共享数据的话那么只能够使用二级缓存

        <1>.添加架包

          

       <2>.在hibernate.cfg.xml文件里配置:


                             <!--配置二级缓存-->

                              <!--初始化类路径  --> 
         放在第一个:      <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
                              <!--打开二级缓存-->
                                  <property name="hibernate.cache.use_second_level_cache">true</property>
                             <!--打开查询缓存-->
                                 <property name="hibernate.cache.use_query_cache">true</property>

 

                               <mapping resource="com/my/oneTomany/Dept.hbm.xml"/>

                               <mapping resource="com/my/oneTomany/Employee.hbm.xml"/>


                        <--添加我们需要缓存的类-->    注意必须在mapping下面

                                   <!--配置哪些类你需要缓存-->
                                  <class-cache usage="read-only" class="com.qf.one2many.Dept"/>


                                 <class-cache usage="read-only" class="com.qf.one2many.Employee"/>


                                   <  !--缓存的是集合-->
                                   <collection-cache usage="read-only" collection="com.qf.one2many.Dept.emps"/>

 

            < 3>:搜索我们的hibernate的下载文件 找到 ehcache.xml文件,复制里面需要的内容,并在src下新建echcache.xml文件夹,粘贴代码进去,改变里面硬盘存储数据的位置

                

 

            <4>:编写测试文件Test.java



   3). Hibernate如何使用C3p0的连接池?


             <!--配置我们C3p0的连接池-->

                    <!--Hibernate对C3p0的连接池的支持-->
                    <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>

                   <!--C3p0的配置-->
                     <property name="c3p0.acquire_increment">2</property>
                     <property name="c3p0.max_size">200</property>
                     <property name="c3p0.max_statements">100</property>
                     <property name="c3p0.min_size">2</property>
                    < property name="c3p0.timeout">3000</property>

 

 下面为详细步骤:

 

 一级缓存:

	/**
	 * 一级缓存
	 */
	@Test
	public void testFirstCache() throws Exception {
		Session session = new Configuration().configure("config/hibernate.cfg.xml").buildSessionFactory().openSession();
	    /**清空缓存:
	     *  clear():清空缓存里面的所有内容
	     *  evict():清空指定对象的缓存内容
	     */
		
		/*Dept dept = session.get(Dept.class, 1);
		//清空缓存  
	    session.clear();
	    Dept dept1 = session.get(Dept.class, 1);
	    session.clear();
	    Dept dept2 = session.get(Dept.class, 1);
	    session.clear();
	    Dept dept3 = session.get(Dept.class, 1);
	    session.clear();
	    Dept dept4 = session.get(Dept.class, 1);
	    session.clear();
	    //上面这样查询要执行很多次*/
           	    
	    
		Dept dept = session.get(Dept.class, 1);
		session.evict(dept);
		
		Dept dept1 = session.get(Dept.class, 1);
	    
	    
        session.close();

	}

 二级缓存:

 hibernate.cfg.xml代码:

<?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="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql:///hibernatetest</property>
        <property name="connection.username">root</property>
        <property name="connection.password">123</property>
    
    <!--配置方言  -->
    <!-- org.hibernate.dialect.MySQL57InnoDBDialect -->
    <!--org.hibernate.dialect.MySQL5InnoDBDialect  -->
    <!-- SQL方言-->
        <!-- 如果使用MySQL5.7及以上版本配置MySQL57Dialect -->
        <!-- 如果使用MySQL5.7以下版本配置MySQL5InnoDBDialect/MySQL57InnoDBDialect -->
        <!-- 如果使用Hibernate5.2.9以前的版本直接配置MySQLDialect -->
        <property name="dialect">org.hibernate.dialect.MySQL57InnoDBDialect</property>
    <!--让数据库自动创建表  -->
        <property name="hbm2ddl.auto">update</property>
    <!--在控制台打印SQL语句  -->
        <property name="show_sql">true</property>
    <!--格式化SQL语句  -->
        <property name="format_sql">true</property>
    <!--添加映射路径  -->
  
  
  
       <!--配置二级缓存  -->
  
           <!--初始化类路径  -->                              
           <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
          <!--打开二级缓存  -->
           <property name="hibernate.cache.use_second_level_cache">true</property>
          <!--打开查询缓存  -->
          <property name="hibernate.cache.use_query_query">true</property>
  
  
   <!--     配置二级缓存
          <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
          打开二级缓存
          <property name="hibernate.cache.use_second_level_cache">true</property>
          打开查询缓存
          <property name="hibernate.cache.use_query_cache">true</property>
   -->
  
  
  
  
  
           <!--查询  -->
           <!--  <mapping resource="com/my/HqlQuery/User.hbm.xml"/>   -->
        
            <mapping resource="com/my/oneTomany/Dept.hbm.xml"/> 
        
            <mapping resource="com/my/oneTomany/Employee.hbm.xml"/> 
        
        
        
        <!--配置哪些类你需要缓存  -->
        <class-cache usage="read-only" class="com/my/oneTomany/Dept"/>
        <class-cache usage="read-only" class="com/my/oneTomany/Employee"/>
        <!--类中的集合也要缓存  -->
        <collection-cache usage="read-only" collection="com/my/oneTomany/Dept.emps"/>
        
        
       
        
        
   </session-factory>
</hibernate-configuration> 
    

  ehcache.xml代码:

 

<?xml version="1.0" encoding="UTF-8"?>  
<ehcache
    updateCheck="false">
    
    <!-- 缓存写入文件目录 -->
    
    <!--  
    	指定一个文件夹目录:当 EHCache 把数据写到本地硬盘上时, 将把数据写到这个目录下.可以用来共享数据
    -->  
    <diskStore path="F:\\SecondCacheFile"/>
    
    
    <!-- 设置缓存的默认数据过期策略  -->
    <!--
          如果没有设置任何的缓存区域,则所有被缓存的对象,都将使用默认的缓存策略。即:<defaultCache.../>
    
    Hibernate 在不同的缓存区域保存不同的类/集合。
	              对于类而言,区域的名称是类名。如:com.my.oneTomany.Dept
                     对于集合而言,区域的名称是类名加属性名。如com.my.oneTomany.Dept.emps
    
    
      maxElementsInMemory:   缓存中可存放的对象最大数目
                  eternal:   设置对象是否为永久的, true表示永不过期,默认是false
        timeToIdleSeconds:   设置对象空闲最长时间,以秒为单位, 超过这个时间,对象过期。
        timeToLiveSeconds:   设置对象生存最长时间,超过这个时间,对象过期
           overflowToDisk:   设置缓存中的对象数目达到上限后,是否把溢出的对象写到基于硬盘的缓存文件夹中
    
    
      -->
    <defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        overflowToDisk="true"
        />
    </ehcache>

 Test代码:

/**
	 * 二级缓存
	 */
	@Test
	public void testSecondCache() throws Exception {
		//一般做开发,二级缓存只需要一个工厂,所以要单独写出来,在open  session 
        SessionFactory sessionFactory = new Configuration().configure("config/hibernate.cfg.xml").buildSessionFactory();
			
        //打开两个session,如果二级缓存测试成功,那么就只打印出一条SQL语句????
        
        Session session = sessionFactory.openSession();
        Dept dept = session.get(Dept.class, 1);
        
        Session session2 = sessionFactory.openSession();
        Dept dept2= session.get(Dept.class, 1);
        

        session.close();
        session2.close();

	}
	

 10.权利反转的测试

     权利的反转:就是说我能控制你的属性,你不能控制我的属性

      例:

         Dept和Employee

        1个部门对应多个员工,部门里的老大有权利操控手下员工的属性,而员工没有权利操控部门;

 代码如下:

 

/**
	 * 权利反转的测试
	 * @throws Exception
	 */
	@Test
	public void testInverse() throws Exception {

		Dept dept=new Dept();
		dept.setDeptAddress("18楼6号");
		dept.setDeptName("后勤保障部");
		Set<Employee> emps=dept.getEmps();
		
		Employee employee=new Employee();
		employee.setEmpName("张三");
		employee.setEmpNum(1234);
		
		Employee employee1=new Employee();
		employee1.setEmpName("李四");
		employee1.setEmpNum(1234);
		
		Employee employee2=new Employee();
		employee2.setEmpName("王五");
		employee2.setEmpNum(1234);
		
		emps.add(employee);
		emps.add(employee1);
		emps.add(employee2);
		
	/*	
		Employee emp=new Employee();
		emp.setEmpName("王麻子");
		emp.setEmpNum(123);
		
		Dept dept=new Dept();
		dept.setDeptName("应用开发部门");
		dept.setDeptAddress("17楼5号");
	
		emp.setDept(dept);*/
		
		
		HibernateUtils.save(dept);

	}

  还需要修改配置文件:(待更新)

 

 11.懒加载 

可以写在上面:

 也可以写在下面:(二选一

 

Test测试类代码:

 

@Test
	public void testLzQuery() throws Exception {
		
		Session session = new Configuration().configure("config/hibernate.cfg.xml").buildSessionFactory().openSession();
		//Query query = session.createNamedQuery("from User");
		//List list = query.list();
		//System.out.println(list);
		//========================================
		Dept dept = session.get(Dept.class, 1);
		//System.out.println(dept);
		/**默认是不支持懒加载,如果中间有集合的话,就默认支持懒加载???????
		 * Dept dept = session.get(Dept.class, 1);
		 * 
		 * 此处如果是get,并且有输出命令,就生成2条SQL语句;如果没有输出命令,就只生成1条部门的SQL语句,懒加载===>
		 * 因为,在Dept.hbm.xml的set配置里面,
		 * lazy="true":默认不支持懒加载。就是说:你不使用我,我就不加载出来,你使用我才加载出来
		 * 所以,如果我们想让它一次加载完2条SQL语句,就要要改为lazy="false":支持的是懒加载。
		 * 
		 * Dept dept = session.load(Dept.class, 1);
		 * 此处如果是load,并且有输出命令,就生成2条SQL语句;如果没有输出命令,就没有SQL语句生成,懒加载===>
		 * 
		 * 
		 * 总结:
		 *  
		 *   如果改成lazy="false"或者default-lazy="false",管你要不要使用,都会先迫切的加载出来再说
		 * 
		 * 
		 * 还可以在上面hibernate-mapping里面,设置default-lazy="false",默认全局都支持懒加载
		 * lazy="true":意思是,我不是用你就不加载出来,使用才加载
		 * lazy="false":意思是,我不使用你这个,也要你加载出来
		 * 
		 * 
		 * 
		 * 
		 * 
		 */

	}

12.对象的持久化

 

 

 

 

 

 

 

 

 

 

 后面会继续更新……

 

posted @ 2017-09-05 01:52  大西瓜猫  阅读(1034)  评论(0编辑  收藏  举报