Hiberate之数据对象关联关系
来源:互联网 发布:mac rar解压软件 编辑:程序博客网 时间:2024/05/17 07:45
数据对象之间的3种关联关系:一对一,一对多,多对多。
一对一,又有两种方式:主键关联,外键关联。
主键关联,两个表共享主表的主键,比如顾客(Customer)和登陆(Login)。
此例中,以Customer为主,Login为辅,也就是将Login的id的生成方式设置为foreign。
如此双向关联后,save/get谁都可以;因两边都设置了cascade="all",delete谁都可以。
Customer.hbm.xml
Login.hbm.xml
Customer.java
Login.java
test.java
外键关联,两表有各自的主键,主表中有个外键,引用辅表的主键。它实际上是一对多的一种退化。
还以顾客(Customer)和登陆(Login)为例,主表需要增加一个字段(login),它作为外键来引用辅表的主键。
表结构改变后,可以简单理解为:多个顾客(实际上,却是全局唯一),共用一个登陆名。
Customer.hbm.xml
Login.hbm.xml
Customer.hbm.xml
Order.hbm.xml
Customer.java
Order.java
test.java
这里建立了顾客和订单的双向关联,并且双方都是级联的,delete(order1)也能删除顾客及order2。
另外,要注意:建立Mysql数据库表时,不能将订单表(orders)命名为order(关键字?),否则报错:
ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not execute statement
Item.hbm.xml
Order.hbm.xml
Item.java
Order.java
test.java
一对一,又有两种方式:主键关联,外键关联。
主键关联,两个表共享主表的主键,比如顾客(Customer)和登陆(Login)。
此例中,以Customer为主,Login为辅,也就是将Login的id的生成方式设置为foreign。
如此双向关联后,save/get谁都可以;因两边都设置了cascade="all",delete谁都可以。
- mysql> desc customer;
- +-------+-------------+------+-----+---------+----------------+
- | Field | Type | Null | Key | Default | Extra |
- +-------+-------------+------+-----+---------+----------------+
- | id | int(4) | NO | PRI | NULL | auto_increment |
- | name | varchar(32) | YES | | NULL | |
- +-------+-------------+------+-----+---------+----------------+
- mysql> desc login;
- +----------+----------+------+-----+---------+----------------+
- | Field | Type | Null | Key | Default | Extra |
- +----------+----------+------+-----+---------+----------------+
- | id | int(4) | NO | PRI | NULL | auto_increment |
- | username | char(20) | YES | | NULL | |
- | password | char(20) | YES | | NULL | |
- +----------+----------+------+-----+---------+----------------+
- <hibernate-mapping>
- <class name="PO.Customer" table="customer" catalog="test">
- <id name="id" type="int">
- <column name="id" />
- <generator class="identity" />
- </id>
- <property name="name" type="string">
- <column name="name" length="32" />
- </property>
- <!--映射Customer与Login的一对一的主键关联 -->
- <one-to-one name="login" class="PO.Login" cascade="all" />
- </class>
- </hibernate-mapping>
- <hibernate-mapping>
- <class name="PO.Login" table="login" catalog="test">
- <id name="id" type="int">
- <column name="id" />
- <generator class="foreign">
- <param name="property">customer</param>
- </generator>
- </id>
- <property name="username" type="string">
- <column name="username" length="20" />
- </property>
- <property name="password" type="string">
- <column name="password" length="20" />
- </property>
- <!--映射Customer与Login的一对一关联 -->
- <one-to-one name="customer" class="PO.Customer" cascade="all"/>
- </class>
- </hibernate-mapping>
- package PO;
- public class Customer implements java.io.Serializable {
- private static final long serialVersionUID = 1L;
- private Integer id;
- private String name;
- private Login login;
- public Customer() {
- }
- public Customer(String name) {
- this.name = name;
- }
- public Integer getId() {
- return this.id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- public String getName() {
- return this.name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public Login getLogin() {
- return login;
- }
- public void setLogin(Login login) {
- this.login = login;
- }
- }
- package PO;
- public class Login implements java.io.Serializable {
- private static final long serialVersionUID = 1L;
- private Integer id;
- private String username;
- private String password;
- private Customer customer;
- public Login() {
- }
- public Login(String username, String password) {
- this.username = username;
- this.password = password;
- }
- public Integer getId() {
- return this.id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- public String getUsername() {
- return this.username;
- }
- public void setUsername(String username) {
- this.username = username;
- }
- public String getPassword() {
- return this.password;
- }
- public void setPassword(String password) {
- this.password = password;
- }
- public Customer getCustomer() {
- return customer;
- }
- public void setCustomer(Customer customer) {
- this.customer = customer;
- }
- }
- package test;
- import java.io.File;
- import org.hibernate.Session;
- import org.hibernate.SessionFactory;
- import org.hibernate.Transaction;
- import org.hibernate.cfg.Configuration;
- import PO.Customer;
- import PO.Login;
- public class test {
- @SuppressWarnings("deprecation")
- public static void main(String[] args) throws Exception {
- File file = new File("src/hibernate.cfg.xml");
- System.out.println("file path:" + file.getAbsolutePath());
- Configuration cfg = new Configuration().configure(file);
- SessionFactory sf = cfg.buildSessionFactory();
- Session session = sf.openSession();
- Transaction tx = session.beginTransaction();
- Customer customer = new Customer();
- customer.setName("customer");
- Login login = new Login();
- login.setUsername("test");
- login.setPassword("password");
- // PO对象之间相互设置关联关系
- customer.setLogin(login);
- login.setCustomer(customer);
- Integer id = (Integer) session.save(customer);
- // Integer id = (Integer) session.save(login);
- System.out.println("save() id:" + id);
- Customer new_customer = (Customer) session.get(Customer.class, id);
- if (new_customer != null) {
- Login tmp_login = new_customer.getLogin();
- System.out.println("id:" + new_customer.getId() + ",name:"
- + new_customer.getName());
- System.out.println("id:" + tmp_login.getId() + ",username:"
- + tmp_login.getUsername() + ",password:"
- + tmp_login.getPassword());
- }
- Login new_login = (Login) session.get(Login.class, id);
- if (new_login != null) {
- Customer tmp_customer = new_login.getCustomer();
- System.out.println("id:" + tmp_customer.getId() + ",name:"
- + tmp_customer.getName());
- System.out.println("id:" + new_login.getId() + ",username:"
- + new_login.getUsername() + ",password:"
- + new_login.getPassword());
- }
- // session.delete(customer);
- session.delete(login);
- tx.commit();
- session.close();
- System.out.println("done.");
- }
- }
外键关联,两表有各自的主键,主表中有个外键,引用辅表的主键。它实际上是一对多的一种退化。
还以顾客(Customer)和登陆(Login)为例,主表需要增加一个字段(login),它作为外键来引用辅表的主键。
表结构改变后,可以简单理解为:多个顾客(实际上,却是全局唯一),共用一个登陆名。
- mysql> desc customer;
- +-------+-------------+------+-----+---------+----------------+
- | Field | Type | Null | Key | Default | Extra |
- +-------+-------------+------+-----+---------+----------------+
- | id | int(4) | NO | PRI | NULL | auto_increment |
- | name | varchar(32) | YES | | NULL | |
- | login | int(4) | NO | MUL | NULL | 新增字段,作为外键|
- +-------+-------------+------+-----+---------+----------------+
- <hibernate-mapping>
- <class name="PO.Customer" table="customer" catalog="test">
- <id name="id" type="int">
- <column name="id" />
- <generator class="identity" />
- </id>
- <property name="name" type="string">
- <column name="name" length="32" />
- </property>
- <!--映射Customer与Login的一对一关联 -->
- <!--<one-to-one name="login" class="PO.Login" cascade="all"/> -->
- <many-to-one name="login" class="PO.Login" cascade="all"
- column="login" unique="true" />
- </class>
- </hibernate-mapping>
- <hibernate-mapping>
- <class name="PO.Login" table="login" catalog="test">
- <id name="id" type="int">
- <column name="id" />
- <generator class="identity" />
- <!--<generator class="foreign">-->
- <!--<param name="property">customer</param>-->
- <!--</generator>-->
- </id>
- <property name="username" type="string">
- <column name="username" length="20" />
- </property>
- <property name="password" type="string">
- <column name="password" length="20" />
- </property>
- <!--映射Customer与Login的一对一关联 -->
- <!--<one-to-one name="customer" class="PO.Customer" cascade="all" />-->
- <one-to-one name="customer" class="PO.Customer" cascade="all"
- property-ref="login" />
- </class>
- </hibernate-mapping>
PO对象以及测试代码,都跟主键关联的相同;测试结果,也相同。
一对一的关联关系,上一篇已经讲过了,这一篇只讲一对多。
下面以顾客(Customer)和订单(Order)为例,这是个典型的一对多的案例。
因为,每个顾客可以有多个订单,而每个订单只属于唯一的一个顾客。
- mysql> desc customer;
- +-------+-------------+------+-----+---------+----------------+
- | Field | Type | Null | Key | Default | Extra |
- +-------+-------------+------+-----+---------+----------------+
- | id | int(4) | NO | PRI | NULL | auto_increment |
- | name | varchar(32) | YES | | NULL | |
- +-------+-------------+------+-----+---------+----------------+
- mysql> desc orders;
- +----------+--------------+------+-----+---------+----------------+
- | Field | Type | Null | Key | Default | Extra |
- +----------+--------------+------+-----+---------+----------------+
- | id | int(4) | NO | PRI | NULL | auto_increment |
- | money | double(10,2) | YES | | NULL | |
- | customer | int(4) | YES | MUL | NULL | |
- +----------+--------------+------+-----+---------+----------------+
- <hibernate-mapping>
- <class name="PO.Customer" table="customer" catalog="test">
- <id name="id" type="int">
- <column name="id" />
- <generator class="identity" />
- </id>
- <property name="name" type="string">
- <column name="name" length="32" />
- </property>
- <!--映射Customer与Orders的一对多的关联 -->
- <set name="orders" table="orders" cascade="all" inverse="true">
- <key column="customer" />
- <one-to-many class="PO.Order" />
- </set>
- </class>
- </hibernate-mapping>
- <hibernate-mapping>
- <class name="PO.Order" table="orders">
- <id name="id" type="int">
- <column name="id" />
- <generator class="identity" />
- </id>
- <property name="money" type="double">
- <column name="money" />
- </property>
- <many-to-one name="customer" class="PO.Customer" cascade="all"
- column="customer" />
- </class>
- </hibernate-mapping>
- package PO;
- import java.util.HashSet;
- import java.util.Set;
- public class Customer implements java.io.Serializable {
- private static final long serialVersionUID = 1L;
- private Integer id;
- private String name;
- private Set<Order> orders = new HashSet<Order>();
- public Customer() {
- }
- public Customer(String name) {
- this.name = name;
- }
- public Integer getId() {
- return this.id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- public String getName() {
- return this.name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public Set<Order> getOrders() {
- return orders;
- }
- public void setOrders(Set<Order> orders) {
- this.orders = orders;
- }
- }
- package PO;
- public class Order implements java.io.Serializable {
- private static final long serialVersionUID = 1L;
- private Integer id;
- private Double money;
- private Customer customer;
- public Order() {
- }
- public Order(Double money) {
- this.setMoney(money);
- }
- public Integer getId() {
- return this.id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- public Double getMoney() {
- return money;
- }
- public void setMoney(Double money) {
- this.money = money;
- }
- public Customer getCustomer() {
- return customer;
- }
- public void setCustomer(Customer customer) {
- this.customer = customer;
- }
- }
- package test;
- import java.io.File;
- import org.hibernate.Session;
- import org.hibernate.SessionFactory;
- import org.hibernate.Transaction;
- import org.hibernate.cfg.Configuration;
- import PO.Customer;
- import PO.Order;
- public class test {
- @SuppressWarnings("deprecation")
- public static void main(String[] args) throws Exception {
- File file = new File("src/hibernate.cfg.xml");
- System.out.println("file path:" + file.getAbsolutePath());
- Configuration cfg = new Configuration().configure(file);
- SessionFactory sf = cfg.buildSessionFactory();
- Session session = sf.openSession();
- Transaction tx = session.beginTransaction();
- Customer customer = new Customer("customer");
- Integer id = (Integer) session.save(customer);
- System.out.println("save(customer) id:" + id);
- Order order1 = new Order(1.1);
- // PO对象之间相互设置关联关系
- order1.setCustomer(customer);
- customer.getOrders().add(order1);
- Integer id1 = (Integer) session.save(order1);
- System.out.println("save(order1) id:" + id1);
- Order order2 = new Order(2.2);
- // PO对象之间相互设置关联关系
- order1.setCustomer(customer);
- customer.getOrders().add(order2);
- Integer id2 = (Integer) session.save(order2);
- System.out.println("save(order2) id:" + id2);
- Customer new_customer = (Customer) session.get(Customer.class, id);
- if (new_customer != null) {
- System.out.println("id:" + new_customer.getId() + ",name:"
- + new_customer.getName());
- for (Order tmp_order : new_customer.getOrders()) {
- System.out.println("id:" + tmp_order.getId() + ",money:"
- + tmp_order.getMoney());
- }
- }
- Order new_order = (Order) session.get(Order.class, id1);
- if (new_order != null) {
- Customer tmp_customer = new_order.getCustomer();
- System.out.println("id:" + tmp_customer.getId() + ",name:"
- + tmp_customer.getName());
- System.out.println("id:" + new_order.getId() + ",money:"
- + new_order.getMoney());
- }
- session.delete(customer);
- // session.delete(order1);
- // session.delete(order2);
- tx.commit();
- session.close();
- System.out.println("done.");
- }
- }
另外,要注意:建立Mysql数据库表时,不能将订单表(orders)命名为order(关键字?),否则报错:
ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not execute statement
以商品(Item)和订单(Order)为例,这是个典型的多对多的案例。
因为,每个订单可以包含多种不同的商品,每种商品也可以拥有多个不同的订单。
多对多的关系,实际上完全可以拆分为两个一对多的关系(通常就这么用,效率高)。
为了实现多对多的关系,还要为它们增加一个关系表(relations),用于保存其关系。
- mysql> desc items;
- +-------+-------------+------+-----+---------+----------------+
- | Field | Type | Null | Key | Default | Extra |
- +-------+-------------+------+-----+---------+----------------+
- | id | int(4) | NO | PRI | NULL | auto_increment |
- | name | varchar(20) | YES | | NULL | |
- +-------+-------------+------+-----+---------+----------------+
- mysql> desc orders;
- +-------+--------------+------+-----+---------+----------------+
- | Field | Type | Null | Key | Default | Extra |
- +-------+--------------+------+-----+---------+----------------+
- | id | int(4) | NO | PRI | NULL | auto_increment |
- | money | double(10,2) | YES | | NULL | |
- +-------+--------------+------+-----+---------+----------------+
- mysql> desc relations;
- +----------+--------+------+-----+---------+-------+
- | Field | Type | Null | Key | Default | Extra |
- +----------+--------+------+-----+---------+-------+
- | item_id | int(4) | NO | PRI | 0 | |
- | order_id | int(4) | NO | PRI | 0 | |
- +----------+--------+------+-----+---------+-------+
- <hibernate-mapping>
- <class name="PO.Item" table="items" catalog="test">
- <id name="id" type="int">
- <column name="id" />
- <generator class="identity" />
- </id>
- <property name="name" type="string">
- <column name="name" length="32" />
- </property>
- <!--映射Items与Orders的多对多的关联 -->
- <set name="orders" table="relations" cascade="all" inverse="true">
- <key column="item_id" />
- <many-to-many class="PO.Order" column="order_id" />
- </set>
- </class>
- </hibernate-mapping>
- <hibernate-mapping>
- <class name="PO.Order" table="orders">
- <id name="id" type="int">
- <column name="id" />
- <generator class="identity" />
- </id>
- <property name="money" type="double">
- <column name="money" />
- </property>
- <!--映射Orders与Items的多对多的关联 -->
- <set name="items" table="relations" cascade="all">
- <key column="order_id" />
- <many-to-many class="PO.Item" column="item_id" />
- </set>
- </class>
- </hibernate-mapping>
- package PO;
- import java.util.HashSet;
- import java.util.Set;
- public class Item implements java.io.Serializable {
- private static final long serialVersionUID = 1L;
- private Integer id;
- private String name;
- private Set<Order> orders = new HashSet<Order>();
- public Item() {
- }
- public Item(String name) {
- this.name = name;
- }
- public Integer getId() {
- return this.id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- public String getName() {
- return this.name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public Set<Order> getOrders() {
- return orders;
- }
- public void setOrders(Set<Order> orders) {
- this.orders = orders;
- }
- }
- package PO;
- import java.util.HashSet;
- import java.util.Set;
- public class Order implements java.io.Serializable {
- private static final long serialVersionUID = 1L;
- private Integer id;
- private Double money;
- private Set<Item> items = new HashSet<Item>();
- public Order() {
- }
- public Order(Double money) {
- this.setMoney(money);
- }
- public Integer getId() {
- return this.id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- public Double getMoney() {
- return money;
- }
- public void setMoney(Double money) {
- this.money = money;
- }
- public Set<Item> getItems() {
- return items;
- }
- public void setItems(Set<Item> items) {
- this.items = items;
- }
- }
- package test;
- import java.io.File;
- import java.util.HashSet;
- import org.hibernate.Session;
- import org.hibernate.SessionFactory;
- import org.hibernate.Transaction;
- import org.hibernate.cfg.Configuration;
- import PO.Item;
- import PO.Order;
- public class test {
- @SuppressWarnings("deprecation")
- public static void main(String[] args) throws Exception {
- File file = new File("src/hibernate.cfg.xml");
- System.out.println("file path:" + file.getAbsolutePath());
- Configuration cfg = new Configuration().configure(file);
- SessionFactory sf = cfg.buildSessionFactory();
- Session session = sf.openSession();
- Transaction tx = session.beginTransaction();
- Item item1 = new Item("item1");
- Integer id1 = (Integer) session.save(item1);
- System.out.println("save(item1) id:" + id1);
- Item item2 = new Item("item2");
- Integer id2 = (Integer) session.save(item2);
- System.out.println("save(item2) id:" + id2);
- Order order1 = new Order(1.1);
- // PO对象之间相互设置关联关系
- HashSet<Item> items1 = new HashSet<Item>();
- items1.add(item1);
- order1.setItems(items1);
- item1.getOrders().add(order1);
- Integer oid1 = (Integer) session.save(order1);
- System.out.println("save(order1) id:" + oid1);
- Order order2 = new Order(2.2);
- // PO对象之间相互设置关联关系
- HashSet<Item> items2 = new HashSet<Item>();
- items2.add(item2);
- order2.setItems(items2);
- item2.getOrders().add(order2);
- Integer oid2 = (Integer) session.save(order2);
- System.out.println("save(order2) id:" + oid2);
- Order order3 = new Order(3.3);
- // PO对象之间相互设置关联关系
- HashSet<Item> items3 = new HashSet<Item>();
- items3.add(item1);
- items3.add(item2);
- order3.setItems(items3);
- item1.getOrders().add(order3);
- item2.getOrders().add(order3);
- Integer oid3 = (Integer) session.save(order3);
- System.out.println("save(order3) id:" + oid3);
- Item new_item = (Item) session.get(Item.class, id1);
- if (new_item != null) {
- System.out.println("item id:" + new_item.getId() + ",name:"
- + new_item.getName());
- for (Order tmp_order : new_item.getOrders()) {
- System.out.println("id:" + tmp_order.getId() + ",money:"
- + tmp_order.getMoney());
- }
- }
- Order new_order = (Order) session.get(Order.class, oid3);
- if (new_order != null) {
- System.out.println("order id:" + new_order.getId() + ",money:"
- + new_order.getMoney());
- for (Item tmp_item : new_order.getItems()) {
- System.out.println("id:" + tmp_item.getId() + ",name:"
- + tmp_item.getName());
- }
- }
- // session.delete(item1);
- // session.delete(item2);
- // session.delete(order1);
- // session.delete(order2);
- // session.delete(order3);
- tx.commit();
- session.close();
- System.out.println("done.");
- }
- }
0 0
- Hiberate之数据对象关联关系
- Hiberate对象关系映射(一)
- Hibernate,JPA 对象关系映射之关联关系映射策略
- JPA 对象关系映射之关联关系映射策略
- Hibernate,JPA 对象关系映射之关联关系映射策略
- JPA 对象关系映射之关联关系映射策略
- 数据关系和关联
- (笔记)SSH之Hiberate
- ORM对象关系映射之GreenDAO建立多表关联
- ORM对象关系映射之GreenDAO建立多表关联
- Hibernate之对象关系映射01一对一单向关联
- Hibernate之对象关系映射02一对一单向主键关联
- Hibernate之对象关系映射04一对一双向关联
- Hibernate之对象关系映射05一对一双向主键关联
- Hibernate之对象关系映射07一对一多单向关联
- 【UML】关系之关联关系
- 利用关联关系操作对象
- 关联关系操纵对象总结
- Oracle结构化查询语言(Structured Query Language)
- Web framework之Mybatis3
- golang udp
- 杭电 HDU ACM 1330 Deck
- 10
- Hiberate之数据对象关联关系
- ORACLE_基础九(Tables)
- 【学习笔记】Navigation
- 数据定义语言(DDL)
- 8
- poj 3881 区间交判断
- 闭包专题 -- 简单易懂
- Web framework之Strust2配置详解
- 第二章第二十题