Hibernate框架之关联关系(many-to-one)

今天天气终于放晴了,心情也会好一些。年前这段时间,打算多写点文章,将自己的东西记录下来,算是一种沉淀吧。目前写的东西都是偏基础,也是计划从基础开始写起,后面再慢慢去扩充。

这篇文章打算记录一下Hibernate实现关联关系的操作。上一篇文章介绍了Hibernate的基本使用

在实际项目开发中,不可能永远都是在一张表上进行操作,比如一本书只有一个作者,但是一个作者可以有多本书,相对于书而言,就是一个多对一的关系。如图:


就以上模型,我们开始Hibernate关联关系中的多对一配置和操作。

一、在MySQL中创建2张表

1、作者表(tb_user),创建表的语句如下:

create table bookmanager.tb_user(
	user_id int primary key auto_increment,
    user_name varchar(10),
    user_password varchar(10),
    user_create_time datetime default NOW()
);
2、图书表(tb_book),创建表的语句如下:

CREATE TABLE tb_book (
    book_id INT PRIMARY KEY AUTO_INCREMENT,
    book_name VARCHAR(45),
    book_price INT,
    book_author_id int(45),
    foreign key(book_author_id) references tb_user(user_id)
);
其中book_author_id是外键,用于关联tb_user表中的主键。接下来在使用hibernate的配置的时候,也会用到此外键。

二、接下来创建2个POJO对象,和上面的2张表相对应。

1、创建一个UserDTO对象,代码如下:

package com.androidxx.hibernatedemo.dto;

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

public class UserDTO {
	
	private Long userId;
	private String userName;
	private String password;
	private Date createTime;
	
	public UserDTO() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Long getUserId() {
		return userId;
	}
	public void setUserId(Long userId) {
		this.userId = userId;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public Date getCreateTime() {
		return createTime;
	}
	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}
	
	

}

2、创建一个Book DTO对象,代码如下(注意代码中包含了UserDTO对象):
package com.androidxx.hibernatedemo.dto;

public class BookDTO {
	
	private Long bookId;
	private String bookName;
	private Integer bookPrice;
	private UserDTO userDto;
	public Long getBookId() {
		return bookId;
	}
	public void setBookId(Long bookId) {
		this.bookId = bookId;
	}
	public String getBookName() {
		return bookName;
	}
	public void setBookName(String bookName) {
		this.bookName = bookName;
	}
	public Integer getBookPrice() {
		return bookPrice;
	}
	public void setBookPrice(Integer bookPrice) {
		this.bookPrice = bookPrice;
	}
	public UserDTO getUserDto() {
		return userDto;
	}
	public void setUserDto(UserDTO userDto) {
		this.userDto = userDto;
	}
	
	
	

}
以上代码将UserDTO作为了Book DTO的一个属性,这是为了匹配多对一的特性。一个Book对象有一个作者对象User,这在上面的代码中能体现出来。

三、创建hibernate的映射文件

1、UserDTO对应的映射文件user.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>
	<class name="com.androidxx.hibernatedemo.dto.UserDTO" table="tb_user">
		<id name="userId" type="java.lang.Long" column="user_id">
			<generator class="identity"/>
		</id>
		<property name="userName" type="java.lang.String" column="user_name"></property>
		<property name="password" type="java.lang.String" column="user_password"></property>
		<property name="createTime" type="java.sql.Date" column="user_create_time"></property>
	</class>
</hibernate-mapping>
2、BookDTO对应的映射文件book.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 package="com.androidxx.hibernatedemo.dto">
	<class name="BookDTO" table="tb_book">
		<id name="bookId" column="book_id" type="java.lang.Long">
			<generator class="identity"/>
		</id>
		<property name="bookName" column="book_name" type="java.lang.String"/>
		<property name="bookPrice" column="book_price" type="java.lang.Integer"/>
		<!-- many-to-one是多对一的配置,其中name表示在BookDTO中的userDto属性,column中配置的是tb_book表的外键book_author_id -->
		<!-- class中配置的是多对一中的“一”所对应的对象UserDTO,此处之所以能直接写UserDTO,是因为hibernate-mapping中的package属性已经指定了包名 -->
		<many-to-one name="userDto" column="book_author_id" class="UserDTO" cascade="all"/>
	</class>
</hibernate-mapping>
其中cascade熟悉表示“串联”,取值all,表示所有的操作(增删改)将执行关联操作。

四、使用Hibernate的多对一关系进行增删查改。

1、多对一关联新增

	public static void main(String[] args) {
		test2();
	}
	
	private static void test2() {
				//加载hibernate.cfg.xml配置文件
				Configuration cfg = new Configuration().configure();
				//读取user.hbm.xml文件,并创建session工厂
				SessionFactory sessionFactory = cfg.buildSessionFactory();
				//获取session对象,相当于jdbc的connection对象。可以通过session完成CURD操作
				Session session = sessionFactory.openSession();
				//新增数据
				Transaction transaction = session.beginTransaction();
				UserDTO userDto = new UserDTO();
				userDto.setUserName("javen2016");
				userDto.setPassword("123456");
				userDto.setCreateTime(new Date(System.currentTimeMillis()));
				
				BookDTO bookDto = new BookDTO();
				bookDto.setBookName("JavaEE从入门到放弃");
				bookDto.setBookPrice(300);
				bookDto.setUserDto(userDto);
				
				session.save(bookDto);
				transaction.commit();
				
				session.close();
				sessionFactory.close();
	}
以上代码执行完成之后,在数据库的tb_user表和tb_book表中将同时新增一条记录。

2、多对一关联查询

	public static void main(String[] args) {
		test2();
	}
	
	private static void test2() {
				//加载hibernate.cfg.xml配置文件
				Configuration cfg = new Configuration().configure();
				//读取user.hbm.xml文件,并创建session工厂
				SessionFactory sessionFactory = cfg.buildSessionFactory();
				//获取session对象,相当于jdbc的connection对象。可以通过session完成CURD操作
				Session session = sessionFactory.openSession();
				//查询数据
				Query query = session.createQuery("from BookDTO");
				List<BookDTO> books = query.getResultList();
				for (int i = 0; i < books.size(); i++) {
					BookDTO book = books.get(i);
					System.out.println(book.getUserDto().getUserName() + "--" + book.getBookName());
				}
				session.close();
				sessionFactory.close();		
	}
仅仅是查询BookDTO会自动将UserDTO的信息关联查询出来。

3、多对一关联修改

	public static void main(String[] args) {
		test3();
	}
	
	private static void test3() {
		//加载hibernate.cfg.xml配置文件
		Configuration cfg = new Configuration().configure();
		//读取user.hbm.xml文件,并创建session工厂
		SessionFactory sessionFactory = cfg.buildSessionFactory();
		//获取session对象,相当于jdbc的connection对象。可以通过session完成CURD操作
		Session session = sessionFactory.openSession();
		//修改数据
		Transaction transaction = session.beginTransaction();
		UserDTO userDto = new UserDTO();
		userDto.setUserId(6L);//因为是修改,所以必须指定一个已经存在的Id
		userDto.setUserName("javen333");
		userDto.setPassword("33333");
		userDto.setCreateTime(new Date(System.currentTimeMillis()));
		
		BookDTO bookDto = new BookDTO();
		bookDto.setBookId(4L);//因为是修改,所以必须指定一个已经存在的Id
		bookDto.setBookName("Android九阴真经3");
		bookDto.setBookPrice(500);
		
		bookDto.setUserDto(userDto);
		session.update(bookDto);
		transaction.commit();
		session.close();
		sessionFactory.close();		
}

4、多对一关联删除

多对一的关联删除执行session.delete方法即可。多对一的删除是不会将“一”对应的表中的数据删掉的。只有在一对多关系中,将主表中的数据删除,会将从表中相关的数据一并删除。


最后

以上就是多对一的基本操作。其实多对一反过来就是一对多,但是在实际项目开发中,为什么要分多对一和一对多这2中情况呢,因为我们业务逻辑操作过程中,又是是以多的一段进行主要操作,这就也需要多对一关联;又是是以“一”这端作为主要操作,所以又需要一对多关联。

本系列案例中的代码仅仅是在main方法中进行的测试,也是为了简化代码,让Hibernate的特征不受到其他东西的干扰。

唧唧复唧唧,鸡鸡何其多。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杨景文Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值