Hibernate关系篇


一个Product(产品)对应一个 Factory(工厂)
一个Factory(工厂)能生产出多个Product (产品)
一种Product(产品)可以被多个User(用户)购买
一个User(用户)可以购买多种Product (产品)

Product和 Factory是多对一的关系 (many-to-one 标签设置多对一关系)
Factory和Product是一对多的关系
Product和User是多对多的关系

多对一

  • 目录结构

在这里插入图片描述
Factory.java

package com.Product;

public class Factory {
	int factoryID;  //工厂号
	String name;    //工厂名
 
	public int getFactoryID() {
		return factoryID;
	}
	public void setFactoryID(int factoryID) {
		this.factoryID = factoryID;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

Product.java

package com.Product;

public class Product {
    int id;
    String name;        //产品名
    float price;        //价格
    Factory factory;    //出厂商
    
    public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public float getPrice() {
		return price;
	}
	public void setPrice(float price) {
		this.price = price;
	}
	public Factory getFactory() {
		return factory;
	}
	public void setFactory(Factory factory) {
		this.factory = factory;
	}

}

Factory.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.Product">  <!--映射所在位置  -->
    <class name="Factory" table="factory_">   <!-- factory_表 -->
        <id name="factoryID" column="factoryID">
            <generator class="native">
            </generator>
        </id>
        <property name="name" />
    </class>
     
</hibernate-mapping>

Product.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.Product">
    <class name="Product" table="product_">
        <id name="id" column="id">
            <generator class="native">
            </generator>
        </id>
 
        <property name="name" />
        <property name="price" />
        
        <many-to-one name="factory" class="Factory" column="cid" />  
                                                                  
    </class>
     
</hibernate-mapping>

                                    <!-- 
                                       many-to-one 标签设置多对一关系
                                       column="cid"表示指向 factory_表的外键
                                       name="factory" 对应Product类中的factory属性
                                       class="Factory" 表示对应Factory类       -->  

坑点:上面column选项内容若是开头大写会报错,小弟也不晓得为何?这是通过反复检验出来的经验,搞了我一晚上,气死我了!!!
还有就是尽量在属性较多的那张表里面设置外键;

hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-configuration PUBLIC
       "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
 
    <!-- 在hibernate.cfg.xml中增加Factory的映射 -->
    <session-factory>
        <!-- Database connection settings -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/mysql?characterEncoding=UTF-8</property>
        <property name="connection.username">root</property>
        <property name="connection.password">123456</property>
        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="current_session_context_class">thread</property>
        <property name="show_sql">true</property>
        <property name="hbm2ddl.auto">update</property>
        <mapping resource="com/Product/Product.hbm.xml" />      <!-- 用作外键的表要放在前面 -->
        <mapping resource="com/Product/Factory.hbm.xml" />
    </session-factory>
 
</hibernate-configuration>

测试:

package Test;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import com.Product.Factory;
import com.Product.Product;
public class Test {
	public static void main(String[] args) {
        SessionFactory sf = new Configuration().configure().buildSessionFactory();
  
        Session s = sf.openSession();
        s.beginTransaction();
               
        Factory c =new Factory(); 
        c.setName("1"); 
        s.save(c);//存值到工厂表
        
        for (int i = 0; i < 10; i++) {
            Product p = new Product();
            p.setName("iphone"+i);
            p.setPrice(i);
            s.save(p);         
        }
        
		 Product p = (Product) s.get(Product.class, 8); //拿主键值为8的对象(那一行)
		 p.setFactory(c); //给工厂属性赋值 
		 s.update(p); //更新产品表(即存值到产品表)
    
        s.getTransaction().commit();
        s.close();
        sf.close();
    }
}

注:
1. product_表的外键自动关联到factory_表的主键
2. 在mysql数据库删除表时,因为product_表有外键,所以应该先删除product_表再删factory_,否则顺序不对会报错

效果:
在这里插入图片描述
在这里插入图片描述

一对多(缺陷:结果一次查询完,无法进行分页查询)

延用上面的product_表、factory_表(因为表之前已创建所以不会再重新创建)、Product.java、Product.hbm.xml、hibernate.cfg.xml

Factory.java

package com.Product;

import java.util.Set;

public class Factory {
	int factoryID;  //工厂号
	String name;    //工厂名
    Set<Product> products;  //由产品组成的Set集合
    
	public int getFactoryID() {
		return factoryID;
	}
	public void setFactoryID(int factoryID) {
		this.factoryID = factoryID;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
    
    public Set<Product> getProducts() {
        return products;
    }
    public void setProducts(Set<Product> products) {
        this.products = products;
    }
}

Factory.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.Product">  <!--映射所在位置  -->
    <class name="Factory" table="factory_">   <!-- factory_表 -->
        <id name="factoryID" column="factoryID">
            <generator class="native">
            </generator>
        </id>
        <property name="name" />
        
        <set name="products" lazy="false">        <!-- 对应 Factory类中的products属性,lazy="false" 表示不使用延迟加载 -->
            <key column="cid" not-null="false" />     <!-- 表示外键是cid,可以为空 -->
            <one-to-many class="Product" />           <!-- 表示一对多所对应的类是Product -->
        </set>
    </class>
     
</hibernate-mapping>

set 用于设置一对多(多对多也是他)关系,也可以用list,设置稍复杂点,这里使用简单的set来入门

Test.java

package Test;

import java.util.Set;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import com.Product.Factory;
import com.Product.Product;
public class Test {
	public static void main(String[] args) {
        SessionFactory sf = new Configuration().configure().buildSessionFactory();
  
        Session s = sf.openSession();
        s.beginTransaction();
               
        Factory c = (Factory) s.get(Factory.class, 1);
        Set<Product> ps = c.getProducts();
        for (Product p : ps) {
            System.out.println(p.getName());
        }
    
        s.getTransaction().commit();
        s.close();
        sf.close();
    }
}

在这里插入图片描述


  • 试着直接对表中cid进行修改:

在这里插入图片描述
测试结果:
在这里插入图片描述
思考:为啥结果是倒序输出?(希望评论区有大神给小弟解答!!!)

多对多(必须有一张中间表 user_product 用于维护 User和Product之间的关系)

Factory.java与Factory.hbm.xml不变

  • 目录结构
    在这里插入图片描述
  • Product.java
package com.Product;

import java.util.Set;

import com.Product.User;

public class Product {
    int id;
    String name;        //产品名
    float price;        //价格
    Factory factory;    //出厂商
    Set<User> users;    //由使用者组成的Set集合
    
    public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public float getPrice() {
		return price;
	}
	public void setPrice(float price) {
		this.price = price;
	}
	public Factory getFactory() {
		return factory;
	}
	public void setFactory(Factory factory) {
		this.factory = factory;
	}
	public Set<User> getUsers() {
		return users;
	}
	public void setUsers(Set<User> users) {
		this.users = users;
	}
	

}

  • User.java
package com.Product;
 
import java.util.Set;
 
public class User {

    int id;                //用户id
    String name;           //用户名
    Set<Product> products; //用户所购买的产品集合

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Set<Product> getProducts() {
        return products;
    }
    public void setProducts(Set<Product> products) {
        this.products = products;
    }
}
  • Product.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.Product">
    <class name="Product" table="product_">
        <id name="id" column="id">
            <generator class="native">
            </generator>
        </id>
 
        <property name="name" />
        <property name="price" />
        
        <many-to-one name="factory" class="Factory" column="cid" />  
                             
        <set name="users" table="user_product" lazy="false">
            <key column="pid" />   <!-- 产品表对应第三张表外键的名称 -->
            <many-to-many column="uid" class="User" />
        </set> 
    </class>
     
</hibernate-mapping>
  • User.hbm.xml
<?xml version="1.0"?>
<!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.Product">
    <class name="User" table="user_">
        <id name="id" column="id">
            <generator class="native">
            </generator>
        </id>
        <property name="name" />
 
        <set name="products" table="user_product" lazy="false">   <!-- 没有延时加载 -->
            <key column="uid" />                   <!-- 用户表对应第三张表外键的名称 -->
            <many-to-many column="pid" class="Product" />   <!-- 配置多对多关系 -->
        </set>        
         
    </class>
     
</hibernate-mapping>
  • hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-configuration PUBLIC
       "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
 
    <!-- 在hibernate.cfg.xml中增加Factory的映射 -->
    <session-factory>
        <!-- Database connection settings -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/mysql?characterEncoding=UTF-8</property>
        <property name="connection.username">root</property>
        <property name="connection.password">123456</property>
        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="current_session_context_class">thread</property>
        <property name="show_sql">true</property>
        <property name="hbm2ddl.auto">update</property>
        <mapping resource="com/Product/Product.hbm.xml" />      <!-- 用作外键的表要放在前面 -->
        <mapping resource="com/Product/Factory.hbm.xml" />
        <mapping resource="com/Product/User.hbm.xml" />
    </session-factory>
  • Test.java(测试)
package Test;

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

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import com.Product.Factory;
import com.Product.Product;
import com.Product.User;
public class Test {
	public static void main(String[] args) {
        SessionFactory sf = new Configuration().configure().buildSessionFactory();
  
        Session s = sf.openSession();
        s.beginTransaction();
               
        //增加3个用户
        Set<User> users = new HashSet();
        for (int i = 0; i < 3; i++) {
            User u =new User();
            u.setName("user"+i);
            users.add(u);
            s.save(u);
        }
          
        //产品1、2被用户1,2,3购买
        Product p1 = (Product) s.get(Product.class, 1);
        Product p2 = (Product) s.get(Product.class, 2);
        p1.setUsers(users);
        p2.setUsers(users);
        s.save(p1);
        s.save(p2);
    
        s.getTransaction().commit();
        s.close();
        sf.close();
    }
}

  • 效果:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    为了便于大家理解这里引用了别人的一张图:
    在这里插入图片描述

注:之所以用set不用list是为了防止用户重复
HashSet实现了Set接口,它不允许集合中出现重复的元素

欢迎大家评论,点赞!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值