【SSH (八)】hibernate one-to-many例子

7 篇文章 0 订阅
6 篇文章 0 订阅

首先按照【SSH (七)】 struts2整合hibernate3 搭建一个SSH的空框架出来。


下面说一下hibernate的多对一映射。

数据库实体之间通常会存在关联,其中一种就是多对一关联,比如用户User和邮件地址Address两个实体,一个用户会有多个邮件地址,而一个邮件地址只会属于一个用户,也就是说用户会对应多个地址。在这里,用户就是“一”的一方,而地址是“多”的一方。关于多和一的区别,最好是画一个图出来,那么用户会有很多箭头指向不同的地址,用户就是一,地址就是多。


多对一关联进一步可分为单向和双向,先看单向。


1,单向多对一:在数据库建表层面,肯定是两张表一个是User一个是Address,然后Address里面存一个指向User的外键,数据库的表结构肯定是这样的。

然而实体的映射文件却有两种方式,为什么这里会有两种方式呢?这涉及到一个维护映射关系的概念,这个上升到了面向对象层面。比如我这里要为user1添加一个地址,我可以在User类中加一个set,然后set.add(address),也可以在address类中添加一个user的引用,然后就是address.setuser(user),前者是由user来维护关联,后者是address来维护关联,下面具体结合程序来说明:

首先建立数据库:刚才说了,不管采用什么关联方式,数据库底层的表是不变的,关联关系是应用层的话题:

user表:只需要有user自己的信息即可。


address表:不仅要有自己的信息,还有外键。id,address是address表本身的信息字段,userId是外键字段。


(1)由User来维护关联:

User实体类:需要添加一个集合存储拥有的地址。

package com.bean;

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

public class User {

	private int id;
	private String username;
	private String password;
	private String info;
	private Set<Address> addresses = new HashSet<>();
	
	public User(){
		
	}
	
    public User(String username,String password,String info){
		this.username = username;
		this.password = password;
		this.info = info;
	}

	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 String getInfo() {
		return info;
	}
	public void setInfo(String info) {
		this.info = info;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	
	public String toString(){
		return this.username+"  "+this.password+" "+this.info;
	}

	public Set<Address> getAddresses() {
		return addresses;
	}

	public void setAddresses(Set<Address> addresses) {
		this.addresses = addresses;
	}
	
}
映射文件:

<?xml version="1.0" encoding='GBK'?>    
<!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.bean">
	<class name="User" table="[user]">
		<id name="id" column="id">
			<generator class="identity"></generator>
		</id>
		<property name="username" column="username" type="java.lang.String"
			length="16"></property>
		<property name="password" column="password" type="java.lang.String"
			length="16"></property>
		<property name="info" column="info" type="java.lang.String"
			length="16"></property>
		<set name="addresses" cascade="all">
		    <key column="userId" ></key>
		    <one-to-many class="com.bean.Address"></one-to-many>
		</set>
	</class>   
</hibernate-mapping>

<set>就是对集合属性的映射,<key>表示外键的名称,cascade级联设置记得。


Address实体类:既然让User实体类维护关联,那么Address类就只要包含自己本身的信息就可以,好像并不知道关联这回事。

package com.bean;

public class Address {

	private int id;
	private String address;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

}

映射文件:

<?xml version="1.0" encoding='GBK'?>    
<!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.bean">
	<class name="Address" table="address">
		<id name="id" column="id">
			<generator class="identity"></generator>
		</id>
		<property name="address" column="address" type="java.lang.String"
			length="16"></property>
	</class>   
</hibernate-mapping>


应用层调用方法:

Address address1 = new Address();
		address1.setAddress("xianlin");
		Address address2 = new Address();
		address2.setAddress("zhujianglu");
		
		User user1 = new User();
		user1.setUsername("hehehehe");
		//因为由user来维护关联关系,所以,这里要让user自己添加address实例
		user1.getAddresses().add(address1);
		user1.getAddresses().add(address2);
		session.save(user1);
		
		transaction.commit();
	    session.close();
	    sessionFactory.close();

运行结果:



hibernate语句:


(2)由address类维护关联:

User实体类:不维护关联,所以都是自己本身的字段。

public class User{
	private int id;
	private String username;
	private String password;
	private String info;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	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 String getInfo() {
		return info;
	}
	public void setInfo(String info) {
		this.info = info;
	}
	
}
配置文件:

<class name="User" table="[user]">
		<id name="id" column="id">
			<generator class="identity"></generator>
		</id>
		<property name="username" column="username" type="java.lang.String"
			length="16"></property>
			<property name="password" column="password" type="java.lang.String"
			length="16"></property>
			<property name="info" column="info" type="java.lang.String"
			length="16"></property>
	</class>


Address实体类:

public class Address {

	private int id;
	private String address;

	private User user;
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

}
配置文件:

<class name="Address" table="address">
		<id name="id" column="id">
			<generator class="identity"></generator>
		</id>
		<property name="address" column="address" type="java.lang.String"
			length="16"></property>
		<many-to-one name="user" column="userId" cascade="all"></many-to-one>
	</class> 
应用层调用方法:

User user1 = new User();
		user1.setUsername("hehehehe");
		
		Address address1 = new Address();
		address1.setAddress("xianlin");
		//因为由address自己维护,所以address自己设置user
		address1.setUser(user1);
		Address address2 = new Address();
		address2.setAddress("zhujianglu");
		address2.setUser(user1);
		
		session.save(address1);
		session.save(address2);


运行结果:



总结:

对于单向的多对一关联,画图确定哪一方是多哪一方是1。

多对一对于数据库而言只有一种实现方式,就是在多的一方添加外键,至于关联的维护方这是应用层层面要考虑的问题,只是应用层存储关联关系时的方式不同而已。这也是因为hibernate ORM的原因,hibernate是将原生的sql api封装起来,提供了面向对象的访问方式,这才导致了有两种方式的多对一,如果不用ORM,用原生的sql,我们就不会遇到这样的问题了。

两种方式也被称为多对一和一对多。

项目源码:http://pan.baidu.com/s/1c0LReLE


至于双向,就是二者的结合了,配置文件一个加one-to-many另一个加many-to-one,实体类一个加set一个加引用。


更加详细的类图和对比可以参照http://blog.csdn.net/yanmei_yao/article/details/7596163

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为了将SSH密钥添加到SSH代理中,您可以按照以下步骤进行操作: 1. 首先,检查您当前配置的SSH密钥是否是其他账户的。如果是,您可以删除它并重新添加新的SSH密钥到SSH代理中。您可以使用以下命令删除当前配置的SSH密钥: ``` ssh-agent -D ``` 然后,您可以使用以下命令将新的SSH密钥添加到SSH代理中: ``` ssh-agent add your_public_key_file_name ``` 请将"your_public_key_file_name"替换为您的公钥文件名。该文档详细介绍了如何生成新的SSH密钥和将其添加到SSH代理中的步骤。 3. 如果您遇到以下错误提示:"Could not open a connection to your authentication agent",这可能是因为本地SSH代理没有运行。您可以使用以下命令启动SSH代理,并将其添加到环境变量中: ``` eval `ssh-agent -s` ``` 运行此命令后,您应该能够将SSH密钥成功添加到SSH代理中。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [【github | SSH key】配置ssh key过程 & trouble shooting](https://blog.csdn.net/lingfy1234/article/details/127140529)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *3* [将本地的私钥ssh-key添加到ssh-agent](https://blog.csdn.net/weixin_38080573/article/details/104947123)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值