Hibernate学习
Posted 大西瓜猫
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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学习的主要内容,如果未能解决你的问题,请参考以下文章