Hibernate基於主鍵的單項,雙向多對多對映關係
阿新 • • 發佈:2019-01-11
今天我們來一起談論下hibernate的基於主鍵的單項,雙向多對多對映關係
首先多對多都是基於主鍵的,沒有基於外來鍵的說法
1.基於主鍵的單項多對多
在這裡就是說中間stuobject是一張關係表,將兩張表的主鍵進行關聯,形成了多對多的關係
程式碼如下:
public class StuObject {
private int stuobjectid;
private String objectname;
private StuObject(){}
public StuObject(String objectname){
this.objectname=objectname;
}
public int getStuobjectid() {
return stuobjectid;
}
public void setStuobjectid(int stuobjectid) {
this.stuobjectid = stuobjectid;
}
public String getObjectname() {
return objectname;
}
public void setObjectname(String objectname) {
this.objectname = objectname;
}
}
public class YoungStu {
private int stuid;
private String youngname;
private Set<StuObject > stuobject;
public YoungStu(){
}
public YoungStu(String youngname){
this.youngname=youngname;
}
public int getStuid() {
return stuid;
}
public void setStuid(int stuid) {
this.stuid = stuid;
}
public String getYoungname() {
return youngname;
}
public void setYoungname(String youngname) {
this.youngname = youngname;
}
public Set<StuObject > getStuobject() {
return stuobject;
}
public void setStuobject(Set<StuObject> stuobject) {
this.stuobject = stuobject;
}
}
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>
<!--
session:會話 當前呼叫者與資料庫之間的一個連線
factory:工廠
其他概念:
struts2中的session是指當前使用者與伺服器之間的一個連線
-->
<session-factory>
<!-- 配置資料庫連線資訊 -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property><!-- 資料庫驅動 -->
<property name="connection.url">jdbc:mysql://localhost:3306/hibernate4</property><!--資料庫地址 -->
<property name="connection.username">**</property><!-- 使用者名稱 -->
<property name="connection.password">****</property><!-- 密碼 -->
<!--
dialect資料庫方言:指明用什麼資料庫
driver_class指定的是引用的驅動
兩者不是一碼事
-->
<!--
dialect:指連線什麼資料庫
connection.driver_class:連線資料庫所需要的驅動
-->
<property name="dialect">
org.hibernate.dialect.MySQL5Dialect
</property>
<!-- 是否列印sql -->
<property name="show_sql">true</property>
<!-- 格式化sql語句 -->
<property name="format_sql">true</property>
<mapping resource="hibernatedemo1/pojo/stuobject.hbm.xml"></mapping>
<mapping resource="hibernatedemo1/pojo/Youngstu.hbm.xml"></mapping>
</session-factory>
</hibernate-configuration>
youngstu.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>
<class name="hibernatedemo1.pojo.YoungStu" table="youngstu">
<!--
id標籤必須有
id:主鍵只是hibernate在操作資料庫表的時候的一個概念,並不要求此列也為資料庫規範意義上的主鍵
-->
<!-- id標籤對應的是實體類的屬性,表中可以沒有主鍵-->
<id name="stuid">
<!--
generator:主鍵生成策略
native:自增長(對映檔案生成策略為native,且表中相應的列設為自增)
assigned:自定義(如果此列在資料庫中是主鍵的話,那麼程式在save時,必須保證此列對應的物件屬性有值)
increment:由hibernate從資料庫中取出主鍵的最大值(每個session只取一次),以該值為基礎,每次增量為1,在記憶體 中生成主鍵
不依賴於底層的資料庫,因此可以跨資料庫
sequence:採用資料庫提供的sequence機制生成主鍵,需要資料庫支援sequence
所以:native和sequence都有各自的資料庫選型的侷限性
-->
<generator class="increment"></generator>
</id>
<!--這裡的name必須和對映類裡的欄位名一致-->
<property name="youngname"/>
<!--這裡的name是你對映類裡的set的別名 後面是重新建立一個關係表-->
<set name="stuobject" table="stuobject">
<!--**表示當前類對映到關係表stuobject中的列,這個column是table所指引的列名,不一定要和對映類裡的id名稱一樣**-->
<key column="stuid"></key>
<!--所對應的另一個表(與yongstu產生關係的一方) column是table所指引的列名,不一定要和對映類裡的id名稱一樣-->
<many-to-many class="hibernatedemo1.pojo.StuObject" column="stuobjectid"></many-to-many>
</set>
</class>
</hibernate-mapping>
stuobject.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>
<class name="hibernatedemo1.pojo.StuObject" table="object">
<!--
id標籤必須有
id:主鍵只是hibernate在操作資料庫表的時候的一個概念,並不要求此列也為資料庫規範意義上的主鍵
-->
<!-- id標籤對應的是實體類的屬性,表中可以沒有主鍵-->
<id name="stuobjectid">
<!--
generator:主鍵生成策略
native:自增長(對映檔案生成策略為native,且表中相應的列設為自增)
assigned:自定義(如果此列在資料庫中是主鍵的話,那麼程式在save時,必須保證此列對應的物件屬性有值)
increment:由hibernate從資料庫中取出主鍵的最大值(每個session只取一次),以該值為基礎,每次增量為1,在記憶體 中生成主鍵
不依賴於底層的資料庫,因此可以跨資料庫
sequence:採用資料庫提供的sequence機制生成主鍵,需要資料庫支援sequence
所以:native和sequence都有各自的資料庫選型的侷限性
-->
<generator class="increment"></generator>
</id>
<property name="objectname"/>
</class>
</hibernate-mapping>
測試程式碼
HibernateUtil.java
public class HibernateUtil {
private static final Configuration cfg;
private static final SessionFactory sessionFactory;
static{
cfg = new Configuration().configure();
ServiceRegistry registry = new StandardServiceRegistryBuilder()
.applySettings(cfg.getProperties()).build();
sessionFactory=cfg.buildSessionFactory(registry);
}
public static Session openSession(){
return sessionFactory.openSession();
}
}
Demo.java
//基於主鍵的單項多對多對映
@Test
public void fkmanytomanyTest(){
Session session=HibernateUtil.openSession();
Transaction tx=session.beginTransaction();
YoungStu youngstu=new YoungStu("Align");
session.saveOrUpdate(youngstu);
youngstu.setStuobject(new HashSet());
for(int i=0;i<5;i++){
StuObject stuobject=new StuObject("高數"+i);
youngstu.getStuobject().add(stuobject);
session.saveOrUpdate(stuobject);
}
tx.commit();
session.close();
}
2.雙向多對多對映關係
Role.java
public class Role {
private int id;
private String name;
private Set<Function> function;
public Role(){}
public Role(String name){
this.name=name;
}
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<Function> getFunction() {
return function;
}
public void setFunction(Set<Function> function) {
this.function = function;
}
}
Function.java
public class Function {
private int funid;
private String code;
private String url;
private Set<Role> role;
public Function(){}
public Function(String code,String url){
this.code=code;
this.url=url;
}
public int getFunid() {
return funid;
}
public void setFunid(int funid) {
this.funid = funid;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Set<Role> getRole() {
return role;
}
public void setRole(Set<Role> role) {
this.role = role;
}
}
role.hbm.xml
<hibernate-mapping>
<class name="hibernatedemo1.pojo.Role" table="role">
<id name="id">
<generator class="increment"></generator>
</id>
<property name="name"/>
<set name="function" table="rolefunction">
<key column="roleid"></key>
<many-to-many class="hibernatedemo1.pojo.Function" column="funid"></many-to-many>
</set>
</class>
</hibernate-mapping>
function.hbm.xml
<hibernate-mapping>
<class name="hibernatedemo1.pojo.Function" table="function">
<id name="funid">
<generator class="increment"></generator>
</id>
<property name="code"/>
<property name="url"></property>
<set name="role" table="rolefunction">
<key column="funid"></key>
<many-to-many class="hibernatedemo1.pojo.Role" column="roleid"></many-to-many>
</set>
</class>
</hibernate-mapping>
這兩個hbm.xml裡面要注意
<set name="function" table="rolefunction">
<key column="roleid"></key>
<many-to-many class="hibernatedemo1.pojo.Function" column="funid"></many-to-many>
</set>
<!--這兩個裡面的column一定要一一對應,不能隨便-->
<set name="role" table="rolefunction">
<key column="funid"></key>
<many-to-many class="hibernatedemo1.pojo.Role" column="roleid"></many-to-many>
</set>