一个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接口,它不允许集合中出现重复的元素
欢迎大家评论,点赞!!!