第25章 J2EE SSH基础学习-hibernate概述-2-一对一和多对多映射说明

这一章主要是对Hibernate多对多的实例进行讲解。其实多对多我们可以很好理解。就是我们平常的数据库表中的关系。无法直接用外键描述两个对象之间的关系是,我们引入第三章表来进行描述多对多的现象。例如(课程,学生,学生选课)这些关系就是典型的例子。

下面直接简单粗暴一点:

上代码:

数据库表信息:

-- 商品分类
create table tbl_category( 
category_id char(32) primary key, -- 分类ID
category_name varchar(30) not null -- 分类名称
);
-- 商品表
create table tbl_goods(
goods_id int primary key, -- 商品主键编号
goods_name varchar(30) not null, -- 商品 名称
goods_price number default 0.0  -- 商品 价格
)
-- 分裂货物表
create table tbl_category_goods(
	category_id char(32) not null, 
	goods_id int null,
	constraint PK_CTG_GOODS primary key(category_id,goods_id),
	constraint FK_CTG_GOODS foreign key(goods_id) references tbl_goods(goods_id),
	constraint FK_CTG_CATEGORYS foreign key(category_id) references tbl_category(category_id)
) 

分类信息:Category.java

/**
 * @Title: Category.java
 * @package: edu.fjnu.domain
 * @author: Zhou kailun
 * @date: 2018年5月30日 下午4:01:54
 * @version: V1.0
 */
package edu.fjnu.domain;

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

/** 
 * ClassName: Category
 * Description: TODO
 * Author: Zhou kailun 
 *
 */
public class Category {
	/**分类编号*/
	private String categoryId;
	/**分类名称*/
	private String categoryName;
	
	private Set<Goods> goods=new HashSet<Goods>();
	/**
	 * <p>Title: </p>
	 * <p>Description: </p>
	 */
	public Category() {
		// TODO Auto-generated constructor stub
	}
	public String getCategoryId() {
		return categoryId;
	}
	public void setCategoryId(String categoryId) {
		this.categoryId = categoryId;
	}
	public String getCategoryName() {
		return categoryName;
	}
	public void setCategoryName(String categoryName) {
		this.categoryName = categoryName;
	}
	public Set<Goods> getGoods() {
		return goods;
	}
	public void setGoods(Set<Goods> goods) {
		this.goods = goods;
	}

}

货物信息:Goods.java

/**
 * @Title: Goods.java
 * @package: edu.fjnu.domain
 * @author: Zhou kailun
 * @date: 2018年5月30日 下午4:02:21
 * @version: V1.0
 */
package edu.fjnu.domain;

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

/** 
 * ClassName: Goods
 * Description: TODO
 * Author: Zhou kailun 
 *
 */
public class Goods {
	/**货物编号*/
	private Integer goodsId;
	/**货物名称*/
	private String goodsName;
	/**货物价格*/
	private double goodsPrice;
	/**货物分类*/
	private Set<Category> category=new HashSet<Category>();
	
	/**
	 * <p>Title: </p>
	 * <p>Description: </p>
	 */
	public Goods() {
		// TODO Auto-generated constructor stub
	}

	public Integer getGoodsId() {
		return goodsId;
	}

	public void setGoodsId(Integer goodsId) {
		this.goodsId = goodsId;
	}

	public String getGoodsName() {
		return goodsName;
	}

	public void setGoodsName(String goodsName) {
		this.goodsName = goodsName;
	}

	public double getGoodsPrice() {
		return goodsPrice;
	}

	public void setGoodsPrice(double goodsPrice) {
		this.goodsPrice = goodsPrice;
	}

	public Set<Category> getCategory() {
		return category;
	}

	public void setCategory(Set<Category> category) {
		this.category = category;
	}

}

分类信息配置文件:Category.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="edu.fjnu.domain">
	<!-- 货物分类信息与数据库匹配 -->
	<class name="Category" table="tbl_category">
		<id name="categoryId" column="category_id" type="java.lang.String" length="32">
			<!-- 
				uuid:全球资源唯一标志符(时间,mac....,理论上是不会重复的,128为二进制数,32为字符);
				uuid.hex的主键是依靠hibernate来完成的,不依靠任何的数据库,不如sequence生成,只有oracle,db2支持。
			 -->
			<generator class="uuid.hex"></generator>
		</id>
		<property name="categoryName" column="category_name" type="java.lang.String" length="30" not-null="true"></property>
		 	<!-- 
		 		1 提供各种条件让hibernate 找到goods(必须
		 		 a.table="tbl_category_goods"
		 		  select * from tbl_category_goods;
		 		 b.<key column="category_id"/>
		 		  select * from tbl_category_goods where category_id=?
		 		 c.当前的category的id
		 		 select * from tbl_category_id where [email protected];
		 		 d.<many-to-many class="Goods" column="goods_id"></many-to-many>
		 		 select goods_id from tbl_category_goods where [email protected];
		 		 e.class="Goods"
		 		  select * from tbl_goods where goods_id=@goods_id
		 		2 根据业务需求,提供各种调优参数(可选
		 	 	  a. cascade=true 级联保存
		 	 	  b. fetch="true" 联合查询,缩减SQL语句
		 	 	  c. lazy="false" 缩减SQL数据库。
		 	 -->
		 	<set name="goods" table="tbl_category_goods" cascade="all" fetch="join" lazy="false">
	 			<key column="category_id" ></key>
	 			<many-to-many class="Goods" column="goods_id"></many-to-many>
	 		</set>
	</class>
</hibernate-mapping>

货物信息配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="edu.fjnu.domain">
	<!-- 公交卡信息与数据库匹配 -->
	<class name="Goods" table="tbl_goods">
		<id name="goodsId" column="goods_id" type="java.lang.Integer">
			<generator class="assigned">
			 
			</generator>
		</id>
		<property name="goodsName" column="goods_name" type="java.lang.String" length="30" not-null="true"></property>
		<property name="goodsPrice" column="goods_price" type="double" not-null="true"></property>
		<!-- 
			注意:这里的constraint="true",表明了当前的BusCard必须和一个Citizen对象关联,这个关系是强制的。
			当使用one-to-one获得对象的时候,如果能够加constrained=true的,尽量加,因为很多情况下,一个实体通过one-to-one关联的实体
			可能存在,也可能不存在,这时候,在查询实体的时候,hibernate总是发起一次查询检查《one-to-one》所关联的实体是否存在,而如果把
			constrained设置weitrue,这个不走则可以省略,直接加载对象
		 -->
		<set name="category" table="tbl_category_goods"  cascade="all">
			<key column="goods_id"></key>
			<many-to-many class="Category" column="category_id" ></many-to-many>
		</set>
		 
	</class>
</hibernate-mapping>

测试代码:CategoryTest.java

/**
 * @Title: CategoryTest.java
 * @package: edu.fjnu.test
 * @author: Zhou kailun
 * @date: 2018年5月30日 下午4:39:01
 * @version: V1.0
 */
package edu.fjnu.test;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import edu.fjnu.domain.Category;
import edu.fjnu.domain.Goods;

/** 
 * ClassName: CategoryTest
 * Description: TODO
 * Author: Zhou kailun 
 *
 */
public class CategoryTest {
	/**Hibernate的sessionFactroy*/
	private SessionFactory factory;
	/**Hibernate的Session对象*/
	private Session session;
	/**
	 * Title:setUp	<br>
	 * Description:TODO	<br>
	 * @param @throws java.lang.Exception :
	 * @return void 
	 * @throws 
	 */
	@Before
	public void setUp() throws Exception {
		Configuration config=new Configuration();//构建一个配置器
		config.configure("edu/fjnu/config/hibernate.cfg.xml");
		factory=config.buildSessionFactory();
		session=factory.openSession();
	}

	/**
	 * Title:tearDown	<br>
	 * Description:TODO	<br>
	 * @param @throws java.lang.Exception :
	 * @return void 
	 * @throws 
	 */
	@After
	public void tearDown() throws Exception {
		if(session.isOpen()){
			session.close();
		}
		if(!factory.isClosed()){
			factory.close();
		}
	}

	@Test
	public void testAddCategory() {
		Category c1=new Category();
		c1.setCategoryName("化妆品");
//		c1.setCategoryId("uuuuuuuuuuuuuuuuuuuu");
		
		Category c2=new Category();
		c2.setCategoryName("学习用品");
		
		Goods g1=new Goods();
		g1.setGoodsId(109);
		g1.setGoodsName("文具盒");
		g1.setGoodsPrice(20.5);
		
		Goods g2=new Goods();
		g2.setGoodsId(110);
		g2.setGoodsName("橡皮檫");
		g2.setGoodsPrice(5.5);
		
		Goods g3=new Goods();
		g3.setGoodsId(111);
		g3.setGoodsName("铅笔");
		g3.setGoodsPrice(2);
 
//		g1.getCategory().add(c1);
//		g1.getCategory().add(c2);
		
		c1.getGoods().add(g1);
	    c1.getGoods().add(g2);
		c1.getGoods().add(g3);
//		
		
		c2.getGoods().add(g3);
		
		Transaction trans=null;
		 try{
			 trans=session.beginTransaction();
			 session.save(c1);
			 session.save(c2);
//			session.saveOrUpdate(g1);
			 trans.commit();
		 }catch(HibernateException e){
			 e.printStackTrace();
			 trans.rollback();
		 }
	}
	
	@Test
	public void testCheckCategory(){

		Transaction trans=null;
		 try{
			 trans=session.beginTransaction();
			 Category category=session.get(Category.class,"8aa2d51563b047ac0163b047ae0d0000");
			 System.out.println(category.getCategoryName()+",total goods:"+category.getGoods().size());
			 trans.commit();
		 }catch(HibernateException e){
			 e.printStackTrace();
			 trans.rollback();
		 }
	}

}

注意:在我们的测试中,有时候关于uuid.hex这个使用要小心,容易导致我们出现主键唯一约束异常,从而无法存入数据库。

所以基本需要控制好主键唯一约束异常。



猜你喜欢

转载自blog.csdn.net/qq_36346496/article/details/80515127