Hibernate框架之多表查詢
阿新 • • 發佈:2019-02-08
1、多表設計(總結)
(1)多表關係
1)一對一:
表的設計原則(分表原則):
優化表的效能
基於語意化分表
一對一的兩張表 之間的關係怎麼維護?
主外來鍵
相同主鍵值
2)一對多:
建表原則:
在一的一方有主鍵 主表
多的一方有與主表的主鍵相關聯外來鍵 從表
3)多對多
建表原則:
兩種主表(業務表) 中間存在一張中間表
中間表內部維護兩個外來鍵
中間表分為兩種:
僅僅維護關係的中間表
不僅存在維護關係的外來鍵 還有其他業務欄位 例如:訂單表 訂單項表 商品表
(2)多表設計
1)根據業務設計表模型
2)分析表的關係: 分方向 看一條(起始表)
3)一對一設計:
學生表 學籍表
4)一對多設計:
客戶表 聯絡人表
百度 張三
jd 李四
google 王武
趙六
田七
孫八
5)多對多設計(許可權5張表):
1、通過使用者名稱和密碼才能登陸
2、系統有不同的職務
3、不同的職務可以有不同的許可權
使用者表 職務表(角色表) 許可權表(選單表、功能表) 張三 CEO 查下自己薪資 李四 CTO 檢視全部人薪資 王武 CFO 請假 田七 COO 批假 程式設計師 檢視專案進度 檢視專案金額 使用者角色關係表 角色許可權關係表
2、Hibernate一對多的操作
實體類結構:
//客戶表: private long cust_id;//客戶編號(主鍵) private String cust_name;//客戶名稱(公司名稱) private String cust_source;//客戶資訊來源 private String cust_industry;//客戶所屬行業 private String cust_level;//客戶級別 private String cust_phone;//固定電話 private String cust_mobile;//行動電話 private Set<Linkman> linkmanSet = new HashSet<Linkman>();//多的一方集合 //聯絡人表 private long lkm_id;//'聯絡人編號(主鍵)', private String lkm_name;// '聯絡人姓名', private String lkm_gender;//'聯絡人性別', private String lkm_phone;//'聯絡人辦公電話', private String lkm_mobile;//'聯絡人手機', private String lkm_email;// '聯絡人郵箱', private String lkm_qq;//'聯絡人qq', private String lkm_position;// '聯絡人職位', private String lkm_memo;//'聯絡人備註', //lkm_cust_id` bigint(32) NOT NULL COMMENT '客戶id', private Customer customer;//一的一方物件
配置對映關係:
<!--客戶表關係對映-->
<hibernate-mapping>
<class name="com.itheima.domain.Customer" table="cst_customer">
<id name="cust_id" column="cust_id">
<generator class="native"></generator>
</id>
<property name="cust_name" column="cust_name"></property>
<property name="cust_source" column="cust_source"></property>
<property name="cust_industry" column="cust_industry"></property>
<property name="cust_level" column="cust_level"></property>
<property name="cust_phone" column="cust_phone"></property>
<property name="cust_mobile" column="cust_mobile"></property>
<!--
配置一對多 一個Customer 對應多個 聯絡人
private Set<Linkman> linkmans = new HashSet<>();
Set標籤name屬性:Set集合的名稱 (當前實體使用哪個變數與對方維護關係)
key標籤的column:外來鍵的名稱
one-to-many標籤的class:對方的全限定名
級聯儲存:在儲存一方時 於此同時儲存與該方有關係的其他物件
cascade="save-update"
級聯刪除:在刪除一方時 於此同時刪除與該方有關係的另一方
cascade="delete"
放棄外來鍵維護權
inverse="true"
inverse直譯:反轉(反轉外來鍵維護權) 該方放棄外來鍵維護權
查詢:延遲載入 lazy="true/false"
查詢一的一方 多的一方預設是延遲載入
結論:
在開發中 習慣在一的一方配置級聯操作(cascade) 在一的一方配置放棄外來鍵維護權
-->
<set name="linkmanSet" cascade="save-update,delete" inverse="true">
<key column="lkm_cust_id"></key>
<one-to-many class="com.itheima.domain.Linkman"></one-to-many>
</set>
</class>
</hibernate-mapping>
<!--聯絡人表關係對映-->
<hibernate-mapping>
<class table="cst_linkman" name="com.itheima.domain.Linkman">
<id name="lkm_id" column="lkm_id">
<generator class="native"></generator>
</id>
<property name="lkm_name" column="lkm_name"></property>
<property name="lkm_gender" column="lkm_gender"></property>
<property name="lkm_phone" column="lkm_phone"></property>
<property name="lkm_mobile" column="lkm_mobile"></property>
<property name="lkm_email" column="lkm_email"></property>
<property name="lkm_qq" column="lkm_qq"></property>
<property name="lkm_position" column="lkm_position"></property>
<property name="lkm_memo" column="lkm_memo"></property>
<!--
配置多對一
private Customer customer;
name:當前實體使用哪個變數與對方維護關係
class:對方的全限定
column:外來鍵名稱
-->
<many-to-one name="customer" column="lkm_cust_id" class="com.itheima.domain.Customer"></many-to-one>
</class>
</hibernate-mapping>
配置核心引數:
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hibernate</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<mapping resource="com/itheima/domain/Customer.hbm.xml"/>
<mapping resource="com/itheima/domain/Linkman.hbm.xml"/>
</session-factory>
</hibernate-configuration>
測試:
public class OneToManyTets {
//物件導航查詢
@Test
public void test3(){
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
Customer customer = session.get(Customer.class, 5l);
Set<Linkman> linkmanSet = customer.getLinkmanSet();
for(Linkman linkman : linkmanSet){
System.out.println(linkman.getLkm_id()+" "+linkman.getLkm_name());
}
//測試導航物件
Linkman linkman = session.get(Linkman.class, 1l);
System.out.println("Customer:"+customer.getCust_name());
System.out.println("Linkman:"+linkman.getLkm_name());
transaction.commit();
HibernateUtils.close(session);
}
//級聯刪除
@Test
public void test2(){
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
//Linkman linkman = session.get(Linkman.class, 6l);
//session.delete(linkman);
Customer customer = session.get(Customer.class, 9l);
session.delete(customer);
transaction.commit();
HibernateUtils.close(session);
}
//一對多儲存、級聯儲存
@Test
public void test1(){
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
Customer customer = new Customer();
Linkman linkman1 = new Linkman();
Linkman linkman2 = new Linkman();
customer.setCust_name("CF");
linkman1.setLkm_name("蓋比");
linkman2.setLkm_name("拉倫多");
//維護關係
customer.getLinkmanSet().add(linkman1);
customer.getLinkmanSet().add(linkman2);
linkman1.setCustomer(customer);
linkman2.setCustomer(customer);
//儲存
session.save(customer);
//session.save(linkman1);
//session.save(linkman2);
transaction.commit();
HibernateUtils.close(session);
}
}
3、Hibernate多對多的操作
實體類結構
//使用者實體類
private long user_id;//'使用者id',
private String user_code;// '使用者賬號',
private String user_name;// '使用者名稱稱',
private String user_password;// '使用者密碼',
private String user_state;// '1:正常,0:暫停',
private Set<Role> roles = new HashSet<Role>();//多對多集合
//角色實體類
private long role_id;
private String role_name;//'角色名稱',
private String role_memo;// '備註',
private Set<User> users = new HashSet<User>();//多對多集合
配置對映關係
<!--使用者關係配置-->
<hibernate-mapping>
<class name="com.itheima.domain.User" table="sys_user">
<id name="user_id" column="user_id">
<generator class="native"></generator>
</id>
<property name="user_code" column="user_code"></property>
<property name="user_name" column="user_name"></property>
<property name="user_password" column="user_password"></property>
<property name="user_state" column="user_state"></property>
<!-- 配置多對多
name:set集合的名稱
key的column:當前實體在中間表中的外來鍵名稱(別人引用我的外來鍵)
many-to-many的class:對方的全限定名
many-to-many的column:代表對方的外來鍵名稱(我引用別人的外來鍵)
table:中間表名稱
-->
<set name="roles" table="sys_user_role" inverse="true">
<key column="user_id"></key>
<many-to-many class="com.itheima.domain.Role" column="role_id"></many-to-many>
</set>
</class>
</hibernate-mapping>
<!--角色關係配置-->
<hibernate-mapping>
<class name="com.itheima.domain.Role" table="sys_role">
<id name="role_id" column="role_id">
<generator class="native"></generator>
</id>
<property name="role_name" column="role_name"></property>
<property name="role_memo" column="role_memo"></property>
<set name="users" table="sys_user_role">
<key column="role_id"></key>
<many-to-many class="com.itheima.domain.User" column="user_id"></many-to-many>
</set>
</class>
</hibernate-mapping>
配置核心配置引數
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hibernate</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<mapping resource="com/itheima/domain/Role.hbm.xml"/>
<mapping resource="com/itheima/domain/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
測試
public class ManyToManyTest {
@Test
public void test02(){
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
//給使用者新增角色
User user = session.get(User.class, 9l);
Role role = session.get(Role.class,13l);
role.getUsers().add(user);
session.save(role);
transaction.commit();
HibernateUtils.close(session);
}
@Test
public void test01(){
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
//新增使用者和角色
User user01 = new User();
User user02 = new User();
Role role01 = new Role();
Role role02 = new Role();
user01.setUser_name("魔獸世界");
user02.setUser_name("LOL");
role01.setRole_name("摩登莫西");
role02.setRole_name("路西多亞");
user01.getRoles().add(role01);
user02.getRoles().add(role02);
role01.getUsers().add(user01);
role02.getUsers().add(user02);
session.save(role01);
session.save(role02);
session.save(user01);
session.save(user02);
transaction.commit();
HibernateUtils.close(session);
}
}