突然感覺接觸到了流幣的知識,完全不懂。數(shù)據(jù)庫方面的很多東西以前都沒接觸過召烂。等今年開課在認真學一遍吧,暫時按照教程把我學到的東西整理下垄懂。
第一節(jié) 一對多映射列表(XML)
對于沒有系統(tǒng)學習過數(shù)據(jù)庫的我而言一開始并不明白這是什么意思骑晶。教程給的例子使用的聯(lián)系人痛垛,感覺還是很好理解的。一個客戶可以擁有多個用戶桶蛔,客戶就是一聯(lián)系人就是多匙头,即一對多。
- 創(chuàng)建用戶實體類 Customer.java
package cn.lkangle.entity;
import java.util.HashSet;
import java.util.Set;
public class Customer {
private Integer cid;
private String name;
private String attr;
// 將聯(lián)系人保存于set集合中
private Set<LinkMan> linkMans = new HashSet<LinkMan>();
...
}
- 創(chuàng)建聯(lián)系人實體類 LinkMan.java
package cn.lkangle.entity;
public class LinkMan {
private Integer lid;
private String name;
private String tel;
// 用于保存所屬客戶
private Customer customer;
...
}
- XML映射配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!-- 一對多的客戶映射配置 -->
<class name="cn.lkangle.entity.Customer" table="t_customer">
<id name="cid" column="cid">
<generator class="native"></generator>
</id>
<property name="name" column="cname"></property>
<property name="attr" column="cattr"></property>
<set name="linkMans" cascade="save-update,delete">
<key column="clid"></key>
<one-to-many class="cn.lkangle.entity.LinkMan"></one-to-many>
</set>
</class>
<!-- 一對多的聯(lián)系人映射配置 -->
<class name="cn.lkangle.entity.LinkMan" table="t_linkman">
<id name="lid" column="lid">
<generator class="native"></generator>
</id>
<property name="name" column="lname"></property>
<property name="tel" column="ltel"></property>
<many-to-one name="customer" class="cn.lkangle.entity.Customer" column="clid" cascade="save-update"></many-to-one>
</class>
</hibernate-mapping>
客戶的set標簽與聯(lián)系人的many-to-one標簽是配置一對多的關鍵仔雷,其中的cascade屬性設置級聯(lián)操作蹂析。
級聯(lián)具有方向性,在客戶中添加只有在對客戶進行操作時才會產生級聯(lián)碟婆,在聯(lián)系人中添加只有對聯(lián)系人進行操作時才產生級聯(lián)
cascade屬性取值:
- update-save 在更新和保存時進行級聯(lián)
- delete 在刪除時進行級聯(lián)
- all 任何操作都進行級聯(lián)
- 一對多級聯(lián)的CRUD操作
package cn.lkangle.threeday;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import cn.lkangle.entity.Customer;
import cn.lkangle.entity.LinkMan;
import cn.lkangle.util.HbmUtil;
public class OnetoManyTest {
/**
* 雙重級聯(lián)效果 配置文件中客戶和聯(lián)系人都要設置級聯(lián)屬性 只是試試
*/
@Test
public void testSave2() {
Session session = null;
Transaction tx = null;
try {
session = HbmUtil.getSession();
System.out.println(session);
tx = session.beginTransaction();
Customer customer = new Customer();
customer.setName("客戶一");
customer.setAttr("北京");
LinkMan linkMan = new LinkMan();
linkMan.setName("聯(lián)系人一");
linkMan.setTel("3333333333");
LinkMan linkMan2= new LinkMan();
linkMan2.setName("聯(lián)系人二");
linkMan2.setTel("865432222");
customer.getLinkMans().add(linkMan);
customer.getLinkMans().add(linkMan2);
linkMan.setCustomer(customer);
linkMan2.setCustomer(customer);
session.save(linkMan);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
}
}
/**
* 級聯(lián)查詢操作
*/
@Test
public void testSelect() {
Session session = null;
Transaction tx = null;
try {
session = HbmUtil.getSession();
System.out.println(session);
tx = session.beginTransaction();
// Customer customer = session.get(Customer.class, 9);
// System.out.println(customer);
// Set<LinkMan> linkMans = customer.getLinkMans();
// for (LinkMan linkMan : linkMans) {
// System.err.println(linkMan);
// }
LinkMan linkMan = session.get(LinkMan.class, 2);
System.out.println(linkMan);
System.out.println(linkMan.getCustomer());
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
}
}
/**
* 級聯(lián)刪除
*/
@Test
public void testDelete() {
Session session = null;
Transaction tx = null;
try {
session = HbmUtil.getSession();
System.out.println(session);
tx = session.beginTransaction();
// LinkMan linkMan = session.get(LinkMan.class, 6);
// session.delete(linkMan);
Customer customer = session.get(Customer.class, 6);
session.delete(customer);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
}
}
/**
* 級聯(lián)修改 直接操作實體類就可以
*/
@Test
public void testUpdate() {
Session session = null;
Transaction tx = null;
try {
session = HbmUtil.getSession();
System.out.println(session);
tx = session.beginTransaction();
/**
* 在這里如果設置了雙向級聯(lián)修改時會出現(xiàn)對外鍵進行兩次修改电抚,這是雙向維護外鍵導致的,這樣的效率就不高
* 推薦在客戶中設置inverse="true"讓其放棄對外鍵的維護竖共,解決修改時會修改兩次外鍵
*/
Customer customer = session.get(Customer.class, 9);
LinkMan linkMan = session.get(LinkMan.class, 2);
LinkMan linkMan2 = session.get(LinkMan.class, 7);
// 因為放棄了客戶對外鍵的維護 這里要更新聯(lián)系人
linkMan.setCustomer(customer);
linkMan2.setCustomer(customer);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
}
}
/**
* 級聯(lián)保存
*/
@Test
public void testSave() {
Session session = null;
Transaction tx = null;
try {
session = HbmUtil.getSession();
System.out.println(session);
tx = session.beginTransaction();
Customer customer = new Customer();
customer.setName("客戶一");
customer.setAttr("地址");
LinkMan linkMan = new LinkMan();
linkMan.setName("聯(lián)系人一");
linkMan.setTel("55555555");
LinkMan linkMan2= new LinkMan();
linkMan2.setName("聯(lián)系人二");
linkMan2.setTel("9999999999");
customer.getLinkMans().add(linkMan);
customer.getLinkMans().add(linkMan2);
session.save(customer); // 客戶要設置級聯(lián)屬性為save-update才能成功保存
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
}
}
}
XMl配置中set標簽的inverse屬性值
?? inverse="false" 默認 不放棄級聯(lián)
?? inverse="true" 放棄級聯(lián)
好處在進行update操作時可以提高效率減少一次數(shù)據(jù)庫操作
第二節(jié) 多對多映射列表(XML)
多對多使用的人和角色的關系舉例蝙叛,即一個人可以同時有多個角色,一個角色同時可以是多個人的公给。
- 創(chuàng)建人實體類 Man.java
package cn.lkangle.entity;
import java.util.HashSet;
import java.util.Set;
public class Man {
private Integer man_id;
private String man_name;
private String man_attr;
private Set<Role> roles = new HashSet<>();
...
}
- 創(chuàng)建角色實體類 Role.java
package cn.lkangle.entity;
import java.util.HashSet;
import java.util.Set;
public class Role {
private Integer role_id;
private String role_name;
private Set<Man> mans = new HashSet<>();
...
}
- XML映射配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!-- 多對多用戶映射配置 -->
<class name="cn.lkangle.entity.Man" table="t_man">
<id name="man_id" column="man_id">
<generator class="native"></generator>
</id>
<property name="man_name" column="man_name"></property>
<property name="man_attr" column="man_attr"></property>
<set name="roles" table="mans_role" cascade="save-update,delete">
<key column="man_id_3"></key>
<many-to-many class="cn.lkangle.entity.Role" column="role_id_3"></many-to-many>
</set>
</class>
<!-- 多對多角色映射配置 -->
<class name="cn.lkangle.entity.Role" table="t_role">
<id name="role_id" column="role_id">
<generator class="native"></generator>
</id>
<property name="role_name"></property>
<set name="mans" table="mans_role">
<key column="role_id_3"></key>
<many-to-many class="cn.lkangle.entity.Man" column="man_id_3"></many-to-many>
</set>
</class>
</hibernate-mapping>
set集合屬性
table: 第三個表的表名
key屬性
column: 本表外鍵在第三張表中的字段名
many-to-many屬性
class: 另一個實體類的路徑
column: 另一個表外鍵在第三張表中的字段名
兩個實體類的配置對應關系如圖:
- 多對多的CRUD操作
package cn.lkangle.threeday;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import cn.lkangle.entity.Man;
import cn.lkangle.entity.Role;
import cn.lkangle.util.HbmUtil;
public class ManyToMany {
/**
* 查詢
*/
@Test
public void testManySelect() {
Session session = null;
Transaction tx = null;
try {
session = HbmUtil.getSession();
tx = session.beginTransaction();
Man man = session.get(Man.class, 2);
System.out.println(man);
Set<Role> roles = man.getRoles();
for (Role role : roles) {
System.out.println(role);
}
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
}
}
/**
* 修改 通過維護第三張表實現(xiàn)
*/
@Test
public void testManyUpdate() {
Session session = null;
Transaction tx = null;
try {
session = HbmUtil.getSession();
tx = session.beginTransaction();
Man man = session.get(Man.class, 2);
Role role = session.get(Role.class, 3);
man.getRoles().add(role);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
}
}
/**
* 直接性級聯(lián)刪除 不推薦
*/
@Test
public void testManyDelete0() {
Session session = null;
Transaction tx = null;
try {
session = HbmUtil.getSession();
tx = session.beginTransaction();
Man man = session.get(Man.class, 1);
session.delete(man);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
}
}
/**
* 刪除 通過維護第三張表實現(xiàn)
*/
@Test
public void testManyDelete() {
Session session = null;
Transaction tx = null;
try {
session = HbmUtil.getSession();
tx = session.beginTransaction();
Man man = session.get(Man.class, 1);
Role role = session.get(Role.class, 1);
man.getRoles().remove(role);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
}
}
/**
* 多對多級聯(lián)保存
*/
@Test
public void testMany() {
Session session = null;
Transaction tx = null;
try {
session = HbmUtil.getSession();
tx = session.beginTransaction();
Man man = new Man();
man.setMan_name("嚴老");
man.setMan_attr("兔斯基");
Man man2 = new Man();
man2.setMan_name("葉老");
man2.setMan_attr("土耳其");
Role role = new Role();
role.setRole_name("老板");
Role role2 = new Role();
role2.setRole_name("秘書");
Role role3 = new Role();
role3.setRole_name("保安");
man.getRoles().add(role);
man.getRoles().add(role2);
man2.getRoles().add(role);
man2.getRoles().add(role3);
session.save(man);
session.save(man2);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
}
}
}
實話我還沒寫過用到相關操作的項目借帘、、淌铐、數(shù)據(jù)庫也沒系統(tǒng)學習過對此感覺很是生疏肺然,看過教程也就會這一些基礎的知識,更細節(jié)深入的知識還需要以后繼續(xù)學習~~