1.什么叫hibernate?
Hibernate说的最简单实际上是一种能能够 直接操作 JAVA对象 和 数据库 进行 交互 的一个技术,hibernate就是直接桥梁
Hibernate<----数据库
HIbernate:是用来访问数据库的一种框架
是一个非侵入式的ORMapping框架
是一个对象关系映射的框架
是一个能够将JAVA对象直接映射到关系型数据库的
Hibernate---->JAVA对象------>关系型的数据库
非侵入式框架:
就是我们在使用这个框架的时候,不需要让我们原来的代码来 继承于某些特定的类,或者实现某些特定的类 的这种类型框架。
侵入式框架呢:
就是我们在使用这个框架的时候需要 继承或者实现 某些特定的类或者接口的这种类型的框架。
O------->Object(对象)
R------->Relation(关系型的数据库)
------>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
<!--配置的是我们复合主键的属性-->
key-property
key-property
/composite-id>
4>:编写测试类
具体操作如下:
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:配置的是对方的主键在关系表中映射的这个值的列名,class:配置的是对方的这个名字-->
<many-to-many column="dev_id" class="Developer"></many-to-many>
</set> Developer一方的配置
<!--配置的是多对多的集合映射-->
set <!--上面的这个key你记住就是映射的当前的类的主键-->
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
1 张三
下面有几种情况:
t_idcard
pId(fk)外键
t_idcard
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
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:这个表示的是外键的意思-->
constrained="true"
</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.flush();刷新,刷新之后就同步数据库了。
见下面
持久化状态
//在session关闭之前,对象处于持久化状态
session.flush();//刷新后,就同步到数据库了
session.close();
//=====================================================
<3>. 清空缓存的两个方法:
session.clear(); //清空缓存里面的所有的内容
session.evict(dept); //清空指定对象的缓存
一级缓存是不能够在session之间共享数据(没用的原因)?
2).二级缓存(主要就讲Hibernate整合Ehcache的问题)
要想在session之间能够共享数据的话那么只能够使用二级缓存
<1>.添加架包
hibernate.cfg.xml文件里配置:
配置二级缓存-->
<!--初始化类路径 -->
hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
<!--打开二级缓存-->
true</property>
<!--打开查询缓存-->
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的连接池的支持-->
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.对象的持久化
后面会继续更新……