博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Hibernate多对多两种情况
阅读量:6508 次
发布时间:2019-06-24

本文共 9148 字,大约阅读时间需要 30 分钟。

hot3.png

Hibernate在做多对多映射的时候,除了原先的两张表外,会多出一个中间表做关联,根据中间表的会有两种不同的配置情况:

1.中间表不需要加入额外数据。

2.中间表有其他字段,需记录额外数据。

下面,我们就以address、person这两张表根据这两种情况做下相应的配置:

情况1:

我们需要建三张表,一张address表,一张person表,一张中间表(其实中间表可以不用建,配置好后运行会自动生成),如下:

delimiter $$CREATE TABLE `address` (  `address_id` int(11) NOT NULL,  `address_name` varchar(50) default NULL,  PRIMARY KEY  (`address_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8$$delimiter $$CREATE TABLE `person` (  `person_id` int(11) NOT NULL,  `person_name` varchar(20) default NULL,  PRIMARY KEY  (`person_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8$$delimiter $$CREATE TABLE `person_address` (  `person_id` int(11) NOT NULL,  `address_id` int(11) NOT NULL,  PRIMARY KEY  (`address_id`,`person_id`),  KEY `FK23F8B90AAAA29DA8` (`person_id`),  KEY `FK23F8B90AB52F16EC` (`address_id`),  CONSTRAINT `FK23F8B90AB52F16EC` FOREIGN KEY (`address_id`) REFERENCES `address` (`address_id`),  CONSTRAINT `FK23F8B90AAAA29DA8` FOREIGN KEY (`person_id`) REFERENCES `person` (`person_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8$$

表建好后,我们需要写相应的实体类:

public class Address {        private int addressId;    private String addressName;    private Set
 person;        public int getAddressId() {        return addressId;    }    public void setAddressId(int addressId) {        this.addressId = addressId;    }    public String getAddressName() {        return addressName;    }    public void setAddressName(String addressName) {        this.addressName = addressName;    }    public Set
 getPerson() {        return person;    }    public void setPerson(Set
 person) {        this.person = person;    }    }public class Person {        private int personId;    private String personName;    private Set
 address;        public int getPersonId() {        return personId;    }    public void setPersonId(int personId) {        this.personId = personId;    }        public String getPersonName() {        return personName;    }    public void setPersonName(String personName) {        this.personName = personName;    }    public Set
 getAddress() {        return address;    }    public void setAddress(Set
 address) {        this.address = address;    }        }

在这里,我们只需要配置两个实体类与相应配置文件即可,中间表无须建实体类与配置文件,hibernate会帮你自动关连。

    
        
            
                 
            
                
            
            
            
    
        
            
                 
            
                
            
            
            

测试类:

public void insert() {                Person p = new Person();        p.setPersonId(1);        p.setPersonName("newUser");        Address ad = new Address();        ad.setAddressId(2);        ad.setAddressName("here");        Set
 setAd = new HashSet
();        setAd.add(ad);         p.setAddress(setAd);        sf.getCurrentSession().persist(p);}

以上,便是一般的多对多关系。

情况2:

  当需要向中间表写数据时,单纯的多对多已经满足不了了,所以在这里,我们可以将其设成两个一对多的关系,即person表与 person_address是一对多关系,address与person_address表也是一对多关系,这样,但可以完成相应的多对多功能了。在情 况2中,我们不单单需要对person表与address表写相应的实体类与配置文件,还需要对person_address表写实体类与配置文件。

     在第二种情况中,我们又可以分成两种小的情况:

  1)中间表新增主键,另有两个字段做为外键对应另外两张表。

      2)中间表采用复合主键,同时做为外键分别对应另外两张表。

下面我们分别对两种情况做相应配置。

情况1)中间表新增主键,另有两个字段做为外键对应另外两张表。数据表结构为:

delimiter $$CREATE TABLE `address` (  `address_id` int(11) NOT NULL,  `address_name` varchar(50) default NULL,  PRIMARY KEY  (`address_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8$$delimiter $$CREATE TABLE `person` (  `person_id` int(11) NOT NULL,  `person_name` varchar(20) default NULL,  PRIMARY KEY  (`person_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8$$delimiter $$CREATE TABLE `person_address` (  `pa_id` int(11) NOT NULL,  `person_id` int(11) default NULL,  `address_id` int(11) default NULL,  `pa_describe` varchar(50) default NULL,  PRIMARY KEY  (`pa_id`),  KEY `FK23F8B90AAAA29DA8` (`person_id`),  KEY `FK23F8B90AB52F16EC` (`address_id`),  CONSTRAINT `FK23F8B90AB52F16EC` FOREIGN KEY (`address_id`) REFERENCES `address` (`address_id`),  CONSTRAINT `FK23F8B90AAAA29DA8` FOREIGN KEY (`person_id`) REFERENCES `person` (`person_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8$$

对应的类为:

public class Address {        private int addressId;    private String addressName;    private Set
 pa;        public int getAddressId() {        return addressId;    }    public void setAddressId(int addressId) {        this.addressId = addressId;    }    public String getAddressName() {        return addressName;    }    public void setAddressName(String addressName) {        this.addressName = addressName;    }    public Set
 getPa() {        return pa;    }    public void setPa(Set
 pa) {        this.pa = pa;    }    }public class Person {        private int personId;    private String personName;    private Set
 personAddress;        public int getPersonId() {        return personId;    }    public void setPersonId(int personId) {        this.personId = personId;    }        public String getPersonName() {        return personName;    }    public void setPersonName(String personName) {        this.personName = personName;    }    public Set
 getPersonAddress() {        return personAddress;    }    public void setPersonAddress(Set
 personAddress) {        this.personAddress = personAddress;    }    }public class PersonAddress{        private int paid;    private String paDescribe;    private Person person;    private Address address;            public int getPaid() {        return paid;    }    public void setPaid(int paid) {        this.paid = paid;    }    public String getPaDescribe() {        return paDescribe;    }    public void setPaDescribe(String paDescribe) {        this.paDescribe = paDescribe;    }    public Person getPerson() {        return person;    }    public void setPerson(Person person) {        this.person = person;    }    public Address getAddress() {        return address;    }    public void setAddress(Address address) {        this.address = address;    }    }

配置文件:

    
        
            
                 
            
                
            
            
            
    
        
            
                 
            
                
            
            
            
    
        
            
                
            
                
            
                
            
            

以上,便完成了相应的配置,进行数据插入时,只需应对相应的保存即可,如:

public void insert() {                Person p = new Person();        p.setPersonId(1);        p.setPersonName("newUser");        Address ad = new Address();        ad.setAddressId(2);        ad.setAddressName("here");        PersonAddress pa = new PersonAddress();        pa.setPaid(1);        pa.setPerson(p);        pa.setAddress(ad);        pa.setPaDescribe("this is a test");        sf.getCurrentSession().persist(pa);}

 情况2)中间表采用复合主键,同时做为外键分别对应另外两张表。由于采用复合主键,在hibernate模型中,需要有另一个类来对应,并实现Serializable接口:

public class PersonAddressPK implements Serializable{        /**     *      */    private static final long serialVersionUID = 1L;        private int person;    private int address;    public int getPerson() {        return person;    }    public void setPerson(int person) {        this.person = person;    }    public int getAddress() {        return address;    }    public void setAddress(int address) {        this.address = address;    }    }

Person表与address表不变,主要是在person_address表上做修改,如下:

delimiter $$
 
CREATE    
TABLE    
`person_address` (
      
`person_id`    
int    
(11)    
NOT    
NULL    
,
      
`address_id`    
int    
(11)    
NOT    
NULL    
,
      
`pa_describe`    
varchar    
(50)    
default    
NULL    
,
      
PRIMARY    
KEY     
(`person_id`,`address_id`),
      
KEY    
`FK23F8B90AAAA29DA8` (`person_id`),
      
KEY    
`FK23F8B90AB52F16EC` (`address_id`),
      
CONSTRAINT    
`FK23F8B90AB52F16EC`    
FOREIGN    
KEY    
(`address_id`)    
REFERENCES    
`address` (`address_id`),
      
CONSTRAINT    
`FK23F8B90AAAA29DA8`    
FOREIGN    
KEY    
(`person_id`)    
REFERENCES    
`person` (`person_id`)
) ENGINE=InnoDB    
DEFAULT    
CHARSET=utf8$$

相应的类:

public class PersonAddress{            private String paDescribe;    private PersonAddressPK paPK;    private Person person;    private Address address;        public String getPaDescribe() {        return paDescribe;    }    public void setPaDescribe(String paDescribe) {        this.paDescribe = paDescribe;    }    public PersonAddressPK getPaPK() {        return paPK;    }    public void setPaPK(PersonAddressPK paPK) {        this.paPK = paPK;    }    public Person getPerson() {        return person;    }    public void setPerson(Person person) {        this.person = person;    }    public Address getAddress() {        return address;    }    public void setAddress(Address address) {        this.address = address;    }        }

配置文件:

    
        
            
                
                        
                
                            
            
                
          
    

插入的时候,需先保存person与address表,再保存person_address表:

public void insert() {                Person p = new Person();        p.setPersonId(1);        p.setPersonName("newUser");        Address ad = new Address();        ad.setAddressId(2);        ad.setAddressName("here");        sf.getCurrentSession().persist(p);        sf.getCurrentSession().persist(ad);        PersonAddress pa = new PersonAddress();        PersonAddressPK paPK = new PersonAddressPK();        paPK.setPerson(p.getPersonId());        paPK.setAddress(ad.getAddressId());        pa.setPaPK(paPK);        pa.setPaDescribe("this is a test");        sf.getCurrentSession().persist(pa);}

 以上,便是hibernate多对多时可采用的几种方法了。

转载于:https://my.oschina.net/u/2402401/blog/633915

你可能感兴趣的文章
java SpringUtil获取bean
查看>>
赛门铁克开启“容灾即服务”时代
查看>>
复杂度归纳--小结
查看>>
PHP学习笔记 第八讲 Mysql.简介和创建新的数据库
查看>>
js获取鼠标位置
查看>>
Mysql
查看>>
跨越企业的“中等收入陷阱”
查看>>
Android 开发者必知的开发资源
查看>>
软件工程技术基础-(软件复用技术)
查看>>
luogu P1280 尼克的任务 序列DP
查看>>
sys.check_constraints
查看>>
vue问题
查看>>
php 引入其他文件中的变量
查看>>
mysql的基本知识
查看>>
webpack入门(二)what is webpack
查看>>
学习C语言必须知道的理论知识(第一章)
查看>>
眠眠interview Question
查看>>
RPC-client异步收发核心细节?
查看>>
#define WIN32_LEAN_AND_MEAN 的作用
查看>>
仿余额宝数字跳动效果 TextCounter
查看>>