《hibernate多对多的自关联》

1.entity

package com.zy.four.entity;

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

public class Book {
	
//	book_id int primary key auto_increment,
//	book_name varchar(50) not null,
//	price float not null
	
	private Integer book_id;
	private String book_name;
	private Float price;
	
	private Set<Category> categorys = new HashSet<>();
	
	public Set<Category> getCategorys() {
		return categorys;
	}
	public void setCategorys(Set<Category> categorys) {
		this.categorys = categorys;
	}
	
	public Integer getBook_id() {
		return book_id;
	}
	public void setBook_id(Integer book_id) {
		this.book_id = book_id;
	}
	public String getBook_name() {
		return book_name;
	}
	public void setBook_name(String book_name) {
		this.book_name = book_name;
	}
	public Float getPrice() {
		return price;
	}
	public void setPrice(Float price) {
		this.price = price;
	}
	
	public Book() {
		super();
	}
	public Book(Integer book_id, String book_name, Float price) {
		super();
		this.book_id = book_id;
		this.book_name = book_name;
		this.price = price;
	}

	@Override
	public String toString() {
		return "Book [book_id=" + book_id + ", book_name=" + book_name + ", price=" + price + "]";
	}
	

}

package com.zy.four.entity;

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

public class Category {
	
//	 category_id int primary key auto_increment,
//	 category_name varchar(50) not null
	
	private Integer category_id;
	private String category_name;
	
	private Set<Book> books = new HashSet<>();
	
	public Set<Book> getBooks() {
		return books;
	}
	public void setBooks(Set<Book> books) {
		this.books = books;
	}
	
	public Integer getCategory_id() {
		return category_id;
	}
	public void setCategory_id(Integer category_id) {
		this.category_id = category_id;
	}
	public String getCategory_name() {
		return category_name;
	}
	public void setCategory_name(String category_name) {
		this.category_name = category_name;
	}

	public Category() {
		super();
	}
	public Category(Integer category_id, String category_name) {
		super();
		this.category_id = category_id;
		this.category_name = category_name;
	}
	
	@Override
	public String toString() {
		return "Category [category_id=" + category_id + ", category_name=" + category_name + "]";
	}
	

}

2.entity.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <!-- name:类的全限定名; table:类对应的数据库表名 -->
	<class name="com.zy.four.entity.Book" table="t_hibernate_book">
	    <!-- name:实体类属性名; type:类属性类型; column:表列列段名 -->
		<id name="book_id" type="java.lang.Integer" column="book_id">
		    <!-- 配置数据库表的主键生成策略 -->
			<generator class="increment"/> <!-- 自增长 -->
		</id>
		
		<!-- name:实体类属性名; type:类属性类型; column:表列列段名 -->
		<property name="book_name" type="java.lang.String" column="book_name"></property>
		<property name="price" type="java.lang.Float" column="price"></property>
		
		
		<!-- 
		当前节点与子节点是一对多的关系 
		name:指的是当前映射实体的属性
		table:对应的中间表,关联关系(中间表数据)交于对方管理
		-->
		<set name="categorys" table="t_hibernate_book_category">
		 <!-- 指的是中间表字段(与当前映射实体对应的表主键相关联) -->
		 <key column="bid"></key>
		 <!-- 
		  class:多方的全类名
		  column:中间表字段(与多方主键相关联的字段)
		  -->
		 <many-to-many class="com.zy.four.entity.Category" column="cid"></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://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    
<!-- 
    1.session.get
    select * from t_hibernate_category where category_id = ? (3)
    return数据:-> resultSet = Category [category_id=3, category_name=历史]
    2.读取Category.hbm.xml文件
    class name = com.zy.four.entity.Category
    Category c = Class.forName(com.zy.four.entity.Category).newInstance();
    while(rs.next){
       <property name="category_name" type="java.lang.String" column="category_name"
        
        ......
        
       ->Filed f = ...
       f.set(c,rs.getObject(category_name))
    }
    
    -> Category c里面此时有值了
    
    3.<set name="books" table="t_hibernate_book_category" ...
    select bid from t_hibernate_book_category where cid = ? (3)
    
    4.根据<many-to-many class="com.zy.four.entity.Book" column="bid"></many-to-many>
          根据class找到com.zy.four.entity.Book对应的映射文件Book.hbm.xml
          
    5.name="com.zy.four.entity.Book" table="t_hibernate_book"
    select * from t_hibernate_book where book_id = ? 
    
          得到数据:-> resultSet:...
          
    Book b = Class.forName(com.zy.four.entity.Book).newInstance();
    while(rs.next){
       <property name="book_name" type="java.lang.String" column="book_name"
        
        ......
        
       ->Filed f = ...
       f.set(b,rs.getObject(book_name))
    }
    
    -> Book b里面此时有值了



 -->
    
<hibernate-mapping>
    <!-- name:类的全限定名; table:类对应的数据库表名 -->
	<class name="com.zy.four.entity.Category" table="t_hibernate_category">
	    <!-- name:实体类属性名; type:类属性类型; column:表列列段名 -->
		<id name="category_id" type="java.lang.Integer" column="category_id">
		    <!-- 配置数据库表的主键生成策略 -->
			<generator class="increment"/> <!-- 自增长 -->
		</id>
		
		<!-- name:实体类属性名; type:类属性类型; column:表列列段名 -->
		<property name="category_name" type="java.lang.String" column="category_name"></property>
		
		<!-- 
		当前节点与子节点是一对多的关系 
		name:指的是当前映射实体的属性
		table:对应的中间表,关联关系(中间表数据)交于对方管理
		
		cascade:save-update(新增-修改)控制数据权利
		inverse:true/false(是否)
		cascade+inverse:是否将控制数据权利交给对方(book类)
		-->
		<set name="books" table="t_hibernate_book_category" cascade="save-update" inverse="true">
		 <!-- 指的是中间表字段(与当前映射实体对应的表主键相关联) -->
		 <key column="cid"></key>
		 <!-- 
		  class:多方的全类名
		  column:中间表字段(与多方主键相关联的字段)
		  -->
		 <many-to-many class="com.zy.four.entity.Book" column="bid"></many-to-many>
		</set>
		
	</class>
</hibernate-mapping>

3.hibernate.cfg.xml

        <!-- 多对多的自关联 -->
		<mapping resource="com/zy/four/entity/Book.hbm.xml"/>
		<mapping resource="com/zy/four/entity/Category.hbm.xml"/>

4.dao

package com.zy.four.dao;

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

import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.query.Query;

import com.zy.four.entity.Book;
import com.zy.six.dao.BaseDao;
import com.zy.two.util.PageBean;
import com.zy.two.util.SessionFactoryUtil;
import com.zy.two.util.StringUtils;

public class BookDao extends BaseDao{
	
	/**
	 * 查询书本
	 * @param book
	 * @return
	 */
	public Book get(Book book) {
		Session session = SessionFactoryUtil.getSession(); //获取session会话
		Transaction transaction = session.beginTransaction(); //开启事物
		
		Book books = session.get(Book.class, book.getBook_id()); //操作数据库
		Hibernate.initialize(books.getCategorys()); //强制加载代理对象
		
		transaction.commit(); //提交事物
		session.close(); //关闭会话
		return books;
	}
	
	/**
	 * 添加书本
	 * @param book
	 * @return
	 */
	public Integer save(Book book) {
		Session session = SessionFactoryUtil.getSession(); //获取session会话
		Transaction transaction = session.beginTransaction(); //开启事物
		
		Integer bid = (Integer) session.save(book); //操作数据库
		
		transaction.commit(); //提交事物
		session.close(); //关闭会话
		return bid;
	}
	
	/**
	 * 主控方删除
	 * 删除书本
	 * @param book
	 * @return
	 */
	public void delete(Book book) {
		Session session = SessionFactoryUtil.getSession(); //获取session会话
		Transaction transaction = session.beginTransaction(); //开启事物
		
		session.delete(book); //操作数据库
		
		transaction.commit(); //提交事物
		session.close(); //关闭会话
	}
	
	
	
	/**
	 * 分页
	 * @return
	 */
	public List<Book> pageBookList(Book book, PageBean pageBean){
		Session session = SessionFactoryUtil.getSession(); //获取session会话
		Transaction transaction = session.beginTransaction(); //开启事物
		
		//操作数据库
		String bookName = book.getBook_name();
		
		String hql = " from Book where 1=1 ";
		if(StringUtils.isNotBlank(bookName)) {
			hql+=" and book_name like :book_name ";
		}
		
		Query query = session.createQuery(hql);
		if(StringUtils.isNotBlank(bookName)) {
			query.setParameter("book_name", "%"+bookName+"%");
		}
		
		if(pageBean != null && pageBean.isPagination()) {
			query.setFirstResult(pageBean.getStartIndex());
			query.setMaxResults(pageBean.getRows());
		}
		
		List list = query.list();
		
		transaction.commit(); //提交事物
		session.close(); //关闭会话
		return list;
	}
	
	
	/**
	 * 通用分页
	 * @return
	 */
	public List<Book> pageBookAll(Book book, PageBean pageBean){
		Session session = SessionFactoryUtil.getSession(); //获取session会话
		Transaction transaction = session.beginTransaction(); //开启事物
		
		//操作数据库
		String bookName = book.getBook_name();
		Map<String, Object> map = new HashMap<>();
		
		String hql = " from Book where 1=1 ";
		if(StringUtils.isNotBlank(bookName)) {
			hql+=" and book_name like :book_name ";
			map.put("book_name", "%"+bookName+"%");
		}
		
		List list = super.executeQuery(session, hql, map, pageBean);
		
		transaction.commit(); //提交事物
		session.close(); //关闭会话
		return list;
	}
	
	
	/**
	 * 原生SQL分页
	 * @return
	 */
	public List pageBook(Book book, PageBean pageBean){
		Session session = SessionFactoryUtil.getSession(); //获取session会话
		Transaction transaction = session.beginTransaction(); //开启事物
		
		//操作数据库
		String sql = "select * from t_hibernate_book";
		List list = session.createSQLQuery(sql).list();
		
		transaction.commit(); //提交事物
		session.close(); //关闭会话
		return list;
	}
	

}

package com.zy.four.dao;

import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.zy.four.entity.Book;
import com.zy.four.entity.Category;
import com.zy.two.util.SessionFactoryUtil;

public class CategoryDao {
	
	/**
	 * 查询类别
	 * @param category
	 * @return
	 */
	public Category get(Category category) {
		Session session = SessionFactoryUtil.getSession(); //获取session会话
		Transaction transaction = session.beginTransaction(); //开启事物
		
		Category categorys = session.get(Category.class, category.getCategory_id()); //操作数据库
		Hibernate.initialize(categorys.getBooks());
		
		transaction.commit(); //提交事物
		session.close(); //关闭会话
		return categorys;
	}
	
	/**
	 * 添加类别
	 * @param category
	 * @return
	 */
	public Integer save(Category category) {
		Session session = SessionFactoryUtil.getSession(); //获取session会话
		Transaction transaction = session.beginTransaction(); //开启事物
		
		Integer cid = (Integer) session.save(category); //操作数据库
		
		transaction.commit(); //提交事物
		session.close(); //关闭会话
		return cid;
	}
	
	/**
	 * 被控方删除
	 * 1.先要获取到被控方的数据
	 * 2.利用被控方获取到主控方来解除关联关系
	 * 3.最后将被控方给删除
	 * 
	 * 删除类别
	 * @param book
	 * @return
	 */
	public void delete(Category category) {
		Session session = SessionFactoryUtil.getSession(); //获取session会话
		Transaction transaction = session.beginTransaction(); //开启事物
		
		//操作数据库
		Category c = session.get(Category.class, category.getCategory_id()); //1.获取到被控方的数据
		for (Book b : c.getBooks()) {
			b.getCategorys().remove(c); //2.解除关联关系
		}
		session.delete(c); //3.将被控方给删除
		
		transaction.commit(); //提交事物
		session.close(); //关闭会话
	}

}

5.daoTest

package com.zy.four.dao;

import static org.junit.Assert.*;

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.List;

import org.junit.Test;

import com.zy.four.entity.Book;
import com.zy.four.entity.Category;
import com.zy.two.util.PageBean;

public class BookDaoTest {
	
	private BookDao bDao = new BookDao();

	/**
	 * 查询
	 */
	@Test
	public void testGet() {
		Book book = new Book();
		book.setBook_id(4);
		Book b = bDao.get(book);
		System.out.println(b.getBook_name());
		System.out.println(b);
		System.out.println(b.getCategorys());
		for (Category c : b.getCategorys()) {
			System.out.println(c.getCategory_name());
		}
	}
	
	/**
	 * 添加
	 * Category.hbm.xml: cascade="save-update" inverse="true"
	 * Book.hbm.xml:
	 * 组合的含义是:
	 * 将中间表t_hibernate_book_category中的数据新增以及修改的权利交给book类
	 */
	@Test
	public void testSave() {
		Book book = new Book();
		book.setBook_name("海底两万里");
		book.setPrice(88f);
		Category category = new Category();
		category.setCategory_id(3);
		book.getCategorys().add(category);
		Integer bid = bDao.save(book);
		System.out.println(bid);
	}
	
	/**
	 * 主控方删除
	 * 删除
	 */
	@Test
	public void testDelete() {
		Book book = new Book();
		book.setBook_id(5);
		bDao.delete(book);
	}
	
	
	
	/**
	 * 分页(测试)
	 */
	@Test
	public void testpageBookList() {
		Book book = new Book();
		PageBean pageBean = new PageBean();
		pageBean.setRows(2);
		List<Book> bookList = bDao.pageBookList(book, pageBean);
		for (Book b : bookList) {
			System.out.println(b.getBook_name());
		}
	}
	
	/**
	 * 通用分页(测试)
	 */
	@Test
	public void testpageBookAll() {
		Book book = new Book();
		book.setBook_name("abc");
		PageBean pageBean = new PageBean();
		pageBean.setRows(2);
		pageBean.setPage(1);
		List<Book> bookList = bDao.pageBookAll(book, pageBean);
		for (Book b : bookList) {
			System.out.println(b.getBook_name());
		}
	}
	
	/**
	 * 原生SQL分页(测试)
	 */
	@Test
	public void testpageBook() {
		List bookList = bDao.pageBook(null, null);
		for (Object object : bookList) {
			System.out.println(Arrays.toString((Object[])object));
		}
	}

}

package com.zy.four.dao;

import static org.junit.Assert.*;

import org.junit.Test;

import com.zy.four.entity.Book;
import com.zy.four.entity.Category;

public class CategoryDaoTest {
	
	private CategoryDao cDao = new CategoryDao();

	/**
	 * 查询
	 */
	@Test
	public void testGet() {
		Category category = new Category();
		category.setCategory_id(3);
		Category c = cDao.get(category);
		System.out.println(c.getCategory_name());
		System.out.println(c);
		System.out.println(c.getBooks());
		for (Book b : c.getBooks()) {
			System.out.println(b.getBook_name());
		}
	}
	
	/**
	 * 新增
	 * Category.hbm.xml: cascade="save-update" inverse="true"
	 * Book.hbm.xml:
	 * 组合的含义是:
	 * 将中间表t_hibernate_book_category中的数据新增以及修改的权利交给book类,category类没有新增以及修改权利
	 * 所以此方法会报错:
	 * ERROR: Column 'book_name' cannot be null
     * ERROR: HHH000346: Error during managed flush [org.hibernate.exception.ConstraintViolationException: could not execute statement]
	 */
	@Test
	public void testSave() {
		Category category = new Category();
		category.setCategory_name("科幻");
		Book book = new Book();
		book.setBook_id(5);
		category.getBooks().add(book);
		Integer cid = cDao.save(category);
		System.out.println(cid);
	}
	
	/**
	 * 被控方删除
	 */
	@Test
	public void testDelete() {
		Category category = new Category();
		category.setCategory_id(3);
		cDao.delete(category);
	}

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值