hibernate5簡單入門一對多,多對一,多對多的配置及註解實現

Hibernate是一個開放源代碼的對象關係映射框架,它對JDBC進行了非常輕量級的對象封裝,它將POJO與數據庫表建立映射關係,是一個全自動的orm框架,hibernate可以自動生成SQL語句,自動執行,使得Java程序員可以隨心所欲的使用對象編程思維來操縱數據庫。 Hibernate可以應用在任何使用JDBC的場合,既可以在Java的客戶端程序使用,也可以在Servlet/JSP的Web應用中使用,最具革命意義的是,Hibernate可以在應用EJB的J2EE架構中取代CMP,完成數據持久化的重任。--百度百科

hibernate的優點:1.面向對象 2.效率的提高(開發效率和測試效率)3.代碼的可移植性 4.hibernate是輕量級框架,它沒有傾入性。

一:hibernate的簡單入門

在入門之前,我們先下載一個插件。Help->Eclipse Marketplace->hibernate 
兩個選一個install下,當然不安裝也可以。
我們創建一個maven java工程:hibernate。
pom.xml文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.julyday</groupId>
	<artifactId>hibernate</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>hibernate</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>5.0.1.Final</version>
		</dependency>

		<!-- mysql連接 -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.34</version>
		</dependency>

	</dependencies>
</project>
開始建個Account類:
package com.julyday.hibernate;

import java.io.Serializable;

@SuppressWarnings("serial")
public class Account implements Serializable {
	private int id;
	private String name;

	public Account(String name) {
		this.name = name;
	}

	public Account() {
	}

	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;
	}
}
右鍵Account.java->new->other->Hibernate->Hibernate XML Mapping file->next 選中account finish

會得到一個Account.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2016-9-22 17:20:19 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="com.julyday.hibernate.Account" table="ACCOUNT">
        <id name="id" type="int">
            <column name="ID" />
            <generator class="assigned" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
    </class>
</hibernate-mapping>
上面的配置文件:class裏面name就是你的類的全路徑,table是你數據庫表的名稱。id表示的是主鍵type="int",我們可以寫Hibernate的類型,也可以寫java的類型,類型對照表網上很多,這裏就不纖細說了,<generator class="assigned" />表示的是主鍵的生成策略,assigned表示我們自己賦值,這裏我們用的是mysql數據庫我們可以選擇increment,就是mysql的自增長,自增長的數據類型必須是數值型。當然我們可以選擇native,表示採用數據門默認的主鍵生成策略。

同樣的,我們右鍵Account.java->new->other->Hibernate->Hibernate Configuration File
我們把路徑選到hibernate/src/main/resources

可以直接finish,參數我們等下配置,得到hibernate.cfg.xml(後面簡稱cfg文件):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
		"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
		"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
    </session-factory>
</hibernate-configuration>
接着我們增加字段:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
		"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
		"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
    	<!-- 數據庫信息 -->
    	<property name="connection.username">root</property>
    	<property name="connection.password">root</property>
    	<property name="connection.url">jdbc:mysql://localhost:3306/hibernate</property>
    	<!-- 數據庫驅動 -->
    	<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    	<!-- 方言 -->
    	<property name="dialect">org.hibernate.dialect.MySQLDialect</property>

    	<!-- 顯示執行的sql -->
    	<property name="show_sql">true</property>
    	<!-- 格式化sql -->
    	<property name="format_sql">true</property>
    	<!-- ddl語句生成策略 -->
    	<property name="hbm2ddl.auto">create</property>
		
		<mapping resource="com/julyday/hibernate/Account.hbm.xml"></mapping>
    </session-factory>
</hibernate-configuration>
數據庫連接:如果下次我們改成oracle 直接把connection.url 改成 jdbc:oracle:thin:@localhost:1521:hibernate,最後的hibernate都表示的是用的數據庫名稱。connection.driver_class表示數據庫驅動:oracle爲oracle.jdbc.driver.OracleDriver,ddl語句生成策略hbm2ddl.auto:四個,1.validate 加載hibernate時,驗證創建數據庫表結構。2.create每次加載hibernate,重新創建數據庫表結構,這就是導致數據庫表數據丟失的原因。
3.create-drop 加載hibernate時創建,退出是刪除表結構。4.update加載hibernate自動更新數據庫結構,我們常用的是create和update,後面我們會大量用到。最後的mapping是我們把account的配置文件告訴Hibernate。
測試下:
package com.julyday.hibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class TestAccount {
	
	private SessionFactory sessionFactory;
	private Session session;
	private Transaction transaction;
	
	@Before
	public void init(){
		//4.3.0之後的版本
		StandardServiceRegistry  serviceRegistry=new StandardServiceRegistryBuilder().configure().build();
		sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();
		//4.3.0之前版本(不包括4.3.0)
//		Configuration configuration = new Configuration().configure();
//		configuration.addClass(Account.class);
//		ServiceRegistry serviceRegistry =new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
//		sessionFactory = configuration.buildSessionFactory(serviceRegistry);
		//4之前版本sessionFactory創建方式,4標記已過時,5又不過時了
//		Configuration configuration = new Configuration().configure();
//		sessionFactory = configuration.buildSessionFactory();
		session = sessionFactory.openSession();
		transaction = session.beginTransaction();
	}
	
	@After
	public void distory(){
		transaction.commit();
		session.close();
		sessionFactory.close();
	}

	@Test
	public void testAccount(){
		Account a = new Account("zhangsan");
		session.save(a);
	}
}
操作數據庫都必須要session,session又是靠sessionFactory來創建的,Hibernate的sessionFactory創建也是變了多次,在4之前版本很簡單configuration.buildSessionFactory(),在4.3版本之前呢,又來了個ServiceRegistry,configuration.buildSessionFactory()的方式又標記爲過時了,後來出了個StandardServiceRegistry,這下好了ServiceRegistry都沒有了,configuration.buildSessionFactory()又不過時了,5版本上面代碼沒註釋的,和4之前版本的方式都是可以的,這裏我也沒太找原因爲什麼Hibernate會這樣去做。
我們刷新下數據庫,數據是有了0,zhangsan,我們把hbm2ddl.auto(後面我們直接用ddl)改成update,再執行一次,沒有成功,Hibernate告訴我們一個錯誤ERROR: Duplicate entry '0' for key 'PRIMARY'。顯然是主鍵衝突了,第一次我們之所以能成功是因爲我們主鍵生成策略是assigned,我們沒給id,但是id是int類型的,默認值是0,這就是數據庫爲什麼id是0了,我們再次執行,id又是0,當然主鍵衝突了,方案2個,我們給id賦值,或者改主鍵生成策略,大家自己嘗試下(記得修改ddl)。
當然類裏面的變量的類型有很多,除了八種基本類型,String,還有集合,其他類。集合類比較簡單,我們這裏不多說了,我們來講下其他類,也就是Hibernate裏面的組件屬性類。
package com.julyday.hibernate;

import java.io.Serializable;
import java.util.Date;

@SuppressWarnings("serial")
public class User implements Serializable{
	private int id;
	private String name;
	private String password;
	private Date birthday;
	private Address address;
	
	public User() {
	}

	public User(String name, String password, Date birthday,Address address) {
		this.name = name;
		this.password = password;
		this.birthday = birthday;
		this.address = address;
	}

	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 String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	public Address getAddress() {
		return address;
	}

	public void setAddress(Address address) {
		this.address = address;
	}
	
}

package com.julyday.hibernate;

public class Address {
	private String postcode;
	private String phone;
	private String street;
	public Address(String postcode, String phone, String street) {
		super();
		this.postcode = postcode;
		this.phone = phone;
		this.street = street;
	}
	public Address() {
	}
	public String getPostcode() {
		return postcode;
	}
	public void setPostcode(String postcode) {
		this.postcode = postcode;
	}
	public String getPhone() {
		return phone;
	}
	public void setPhone(String phone) {
		this.phone = phone;
	}
	public String getStreet() {
		return street;
	}
	public void setStreet(String street) {
		this.street = street;
	}
	
	
}
這裏我們把User.hbm.xml放到src/main/resources下:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.julyday.hibernate">
    <class name="User" table="USER" >
        <id name="id" type="int">
            <column name="ID" />
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        <property name="password" type="java.lang.String">
            <column name="PASSWORD" />
        </property>
        <property name="birthday" type="java.util.Date">
            <column name="BIRTHDAY" />
        </property>
        <component name="address" class="com.julyday.hibernate.Address">
        	<property name="postcode" column="POSTCODE"/>
        	<property name="phone" column="PHONE"/>
        	<property name="street" column="STREET"/>
        </component>
    </class>
</hibernate-mapping>
那我們的hibernate.cfg.xml添加如下:<mapping resource="User.hbm.xml"/>。
測試下:
package com.julyday.hibernate;

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class TestUser {
	
	private SessionFactory sessionFactory;
	private Session session;
	private Transaction transaction;
	
	@Before
	public void init(){
		StandardServiceRegistry  serviceRegistry=new StandardServiceRegistryBuilder().configure().build();
		sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();
		session = sessionFactory.openSession();
		transaction = session.beginTransaction();
	}
	
	@After
	public void distory(){
		transaction.commit();
		session.close();
		sessionFactory.close();
	}

	@Test
	public void testUser(){
		Address address = new Address("200003","12345678987","shanghai");
		User u = new User("julyday","123456",new Date(),address);
		session.save(u);
	}
	
}
這裏的映射文件只是測試我們可以放很多地方,學習用的,大家還是要養成良好的習慣。ok,簡單的Hibernate我們就算完成了。

二:一對多關係

package com.julyday.hibernate.one2many;

import java.io.Serializable;

@SuppressWarnings("serial")
public class Student implements Serializable {
	private int sid;
	private String name;
	private int age;

	public int getSid() {
		return sid;
	}

	public void setSid(int sid) {
		this.sid = sid;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Student() {

	}

	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}

	@Override
	public String toString() {
		return "Student [sid=" + sid + ", name=" + name + ", age=" + age + "]";
	}

}

	package com.julyday.hibernate.one2many;
	
	import java.io.Serializable;
	import java.util.HashSet;
	import java.util.Set;
	
	@SuppressWarnings("serial")
	public class Grade implements Serializable {
		private int gid;
		private String gname;
		private String gdesc;
		private Set<Student> students = new HashSet<Student>();
	
		public Set<Student> getStudents() {
			return students;
		}
	
		public void setStudents(Set<Student> students) {
			this.students = students;
		}
	
		public int getGid() {
			return gid;
		}
	
		public void setGid(int gid) {
			this.gid = gid;
		}
	
		public String getGname() {
			return gname;
		}
	
		public void setGname(String gname) {
			this.gname = gname;
		}
	
		public String getGdesc() {
			return gdesc;
		}
	
		public void setGdesc(String gdesc) {
			this.gdesc = gdesc;
		}
	
		public Grade() {
			super();
		}
	
		public Grade(String gname, String gdesc) {
			super();
			this.gname = gname;
			this.gdesc = gdesc;
		}
	
		@Override
		public String toString() {
			return "Grade [gid=" + gid + ", gname=" + gname + ", gdesc=" + gdesc
					+ "]";
		}
	
	}

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2016-9-21 17:06:31 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="com.julyday.hibernate.one2many.Student" table="STUDENT">
        <id name="sid" type="int">
            <column name="SID" />
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        <property name="age" type="int">
            <column name="AGE" />
        </property>
    </class>
</hibernate-mapping>

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2016-9-21 17:06:12 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="com.julyday.hibernate.one2many.Grade" table="GRADE">
        <id name="gid" type="int">
            <column name="GID" />
            <generator class="native" />
        </id>
        <property name="gname" type="java.lang.String">
            <column name="GNAME" />
        </property>
        <property name="gdesc" type="java.lang.String">
            <column name="GDESC" />
        </property>
        <set name="students" table="student" cascade="all">
        	<key column="gid"/>
        	<one-to-many class="com.julyday.hibernate.one2many.Student"/>
        </set>
    </class>
</hibernate-mapping>

cfg文件增加:<mapping resource="com/julyday/hibernate/one2many/Grade.hbm.xml"/>
    <mapping resource="com/julyday/hibernate/one2many/Student.hbm.xml"/>

我們這裏用的是set,因爲學生肯定是不會重複的,用set是沒問題的,當然大家也可以測試下list,map這樣的集合,都是大同小異。cascade="all",cascade級聯操作:none: 所有情況下均不進行關聯操作。這是默認值。save-update:在執行save/update/saveOrUpdate時進行關聯操作。delete: 在執行delete 時進行關聯操作。all: 所有情況下均進行關聯操作,即save-update和delete。由於我們是all,所有當我們刪除grade的時候,grade所有的student也會級聯刪除的。

測試下:
package com.julyday.hibernate.one2many;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;


public class TestOne2many {
	private SessionFactory sessionFactory;
	private Session session;
	private Transaction transaction;
	
	@Before
	public void init(){
		StandardServiceRegistry  serviceRegistry=new StandardServiceRegistryBuilder().configure().build();
		sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();
		session = sessionFactory.openSession();
		transaction = session.beginTransaction();
	}
	
	@After
	public void distory(){
		transaction.commit();
		session.close();
		sessionFactory.close();
	}
	
	@Test
	public void testOne2many(){
		Grade g1 = new Grade("java","java學前班");
		Student stu1 = new Student("julyday",18);
		Student stu2 = new Student("lisi",38);
		g1.getStudents().add(stu1);
		g1.getStudents().add(stu2);
		session.save(g1);
		session.save(stu1);
		session.save(stu2);
	}
	
	@Test
	public void delete(){
//		Student stu1 = session.get(Student.class, 2);
//		session.delete(stu1);
		Grade g = session.get(Grade.class, 1);
		session.delete(g);
	}
	
}
記得測試delete的時候修改ddl(update)。

三:多對一關係

package com.julyday.hibernate.many2one;

import java.io.Serializable;

@SuppressWarnings("serial")
public class Grade implements Serializable {
	private int gid;
	private String gname;
	private String gdesc;
	
	public int getGid() {
		return gid;
	}

	public void setGid(int gid) {
		this.gid = gid;
	}

	public String getGname() {
		return gname;
	}

	public void setGname(String gname) {
		this.gname = gname;
	}

	public String getGdesc() {
		return gdesc;
	}

	public void setGdesc(String gdesc) {
		this.gdesc = gdesc;
	}

	public Grade() {
		super();
	}

	public Grade(String gname, String gdesc) {
		super();
		this.gname = gname;
		this.gdesc = gdesc;
	}

	@Override
	public String toString() {
		return "Grade [gid=" + gid + ", gname=" + gname + ", gdesc=" + gdesc
				+ "]";
	}

}

package com.julyday.hibernate.many2one;

import java.io.Serializable;

@SuppressWarnings("serial")
public class Student implements Serializable {
	private int sid;
	private String name;
	private int age;
	private Grade grade;

	public Grade getGrade() {
		return grade;
	}

	public void setGrade(Grade grade) {
		this.grade = grade;
	}

	public int getSid() {
		return sid;
	}

	public void setSid(int sid) {
		this.sid = sid;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Student() {

	}

	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}

	@Override
	public String toString() {
		return "Student [sid=" + sid + ", name=" + name + ", age=" + age + "]";
	}

}

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2016-9-21 17:06:12 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="com.julyday.hibernate.many2one.Grade" table="GRADE">
        <id name="gid" type="int">
            <column name="GID" />
            <generator class="native" />
        </id>
        <property name="gname" type="java.lang.String">
            <column name="GNAME" />
        </property>
        <property name="gdesc" type="java.lang.String">
            <column name="GDESC" />
        </property>
    </class>
</hibernate-mapping>

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2016-9-21 17:06:31 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="com.julyday.hibernate.many2one.Student" table="STUDENT">
        <id name="sid" type="int">
            <column name="SID" />
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        <property name="age" type="int">
            <column name="AGE" />
        </property>
        <many-to-one name="grade" class="com.julyday.hibernate.many2one.Grade" column="gid"></many-to-one>
    </class>
</hibernate-mapping>
cfg文件增加:<mapping resource="com/julyday/hibernate/many2one/Grade.hbm.xml"/>
    <mapping resource="com/julyday/hibernate/many2one/Student.hbm.xml"/>
測試下:
package com.julyday.hibernate.many2one;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class TestMany2one {
	private SessionFactory sessionFactory;
	private Session session;
	private Transaction transaction;
	
	@Before
	public void init(){
		StandardServiceRegistry  serviceRegistry=new StandardServiceRegistryBuilder().configure().build();
		sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();
		session = sessionFactory.openSession();
		transaction = session.beginTransaction();
	}
	
	@After
	public void distory(){
		transaction.commit();
		session.close();
		sessionFactory.close();
	}

	@Test
	public void testMany2one(){
		Grade g1 = new Grade("java","java學前班");
		Student stu1 = new Student("julyday",18);
		Student stu2 = new Student("zhangsan",28);
		stu1.setGrade(g1);
		stu2.setGrade(g1);
		session.save(stu1);
		session.save(stu2);
		session.save(g1);
	}
	
}

四:多對多關係

package com.julyday.hibernate.many2many;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

@SuppressWarnings("serial")
public class Student implements Serializable {
	private int sid;
	private String name;
	private int age;
	private Set<Teacher> teachers = new HashSet<Teacher>();
	
	public Set<Teacher> getTeachers() {
		return teachers;
	}

	public void setTeachers(Set<Teacher> teachers) {
		this.teachers = teachers;
	}

	public int getSid() {
		return sid;
	}

	public void setSid(int sid) {
		this.sid = sid;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Student() {

	}

	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}

	@Override
	public String toString() {
		return "Student [sid=" + sid + ", name=" + name + ", age=" + age + "]";
	}

}

package com.julyday.hibernate.many2many;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

@SuppressWarnings("serial")
public class Teacher implements Serializable{
	private int tid;
	private String name;
	private int age;
	private Set<Student> students = new HashSet<Student>();

	public Set<Student> getStudents() {
		return students;
	}

	public void setStudents(Set<Student> students) {
		this.students = students;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public int getTid() {
		return tid;
	}

	public void setTid(int tid) {
		this.tid = tid;
	}

	public Teacher(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public Teacher() {
		super();
	}

	@Override
	public String toString() {
		return "Teacher [tid=" + tid + ", name=" + name + ", age=" + age + "]";
	}
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2016-9-21 18:42:32 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="com.julyday.hibernate.many2many.Student" table="STUDENT">
        <id name="sid" type="int">
            <column name="SID" />
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        <property name="age" type="int">
            <column name="AGE" />
        </property>
        <set name="teachers" table="teacher_student" inverse="true">
        	<key column="sid"></key>
        	<many-to-many class="com.julyday.hibernate.many2many.Teacher" column="tid"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2016-9-21 18:42:32 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="com.julyday.hibernate.many2many.Teacher" table="TEACHER">
        <id name="tid" type="int">
            <column name="TID" />
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        <property name="age" type="int">
            <column name="AGE" />
        </property>
        <set name="students" table="teacher_student">
        	<key column="tid"></key>
        	<many-to-many class="com.julyday.hibernate.many2many.Student" column="sid"></many-to-many>
        </set>
    </class>
</hibernate-mapping>
cfg文件增加:<mapping resource="com/julyday/hibernate/many2many/Teacher.hbm.xml"/>
    <mapping resource="com/julyday/hibernate/many2many/Student.hbm.xml"/>
我們看到student的映射文件中inverse="true",inverse的真正作用就是指定由哪一方來維護之間的關聯關係。當一方中指定了“inverse=false”(默認),那麼那一方就有責任負責之間的關聯關係,我們這裏是true就是把關聯的關係給teacher維護了,多對多的,有一方必須是false一方爲true,這是因爲,多對多的關係是通過2個多對一來維護的,如果都是false,做插入的時候,兩個都插入就重複了,兩個都爲true,都不去維護關係,就不會插入對應的關係,所有可以按照自己的業務來確定,到底是哪一方維護關係。
測試下:
package com.julyday.hibernate.many2many;

import java.util.HashSet;
import java.util.Set;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class TestMany2many {
	private SessionFactory sessionFactory;
	private Session session;
	private Transaction transaction;
	
	@Before
	public void init(){
		StandardServiceRegistry  serviceRegistry=new StandardServiceRegistryBuilder().configure().build();
		sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();
		session = sessionFactory.openSession();
		transaction = session.beginTransaction();
	}
	
	@After
	public void distory(){
		transaction.commit();
		session.close();
		sessionFactory.close();
	}
	
	@Test
	public void testMany2many(){
		Student stu1 = new Student("julyday",18);
		Student stu2 = new Student("zhangsan",19);
		Teacher tea1 = new Teacher("lisi",48);
		Teacher tea2 = new Teacher("wangwu",49);
		
		Set<Teacher> ts = new HashSet<Teacher>();
		ts.add(tea1);
		ts.add(tea2);
		stu1.setTeachers(ts);
		stu2.setTeachers(ts);
		
		Set<Student> ss = new HashSet<Student>();
		ss.add(stu1);
		ss.add(stu2);
		tea1.setStudents(ss);
		tea2.setStudents(ss);
		
		session.save(tea1);
		session.save(tea2);
		session.save(stu1);
		session.save(stu2);
	}
	
}

五:註解的實現

package com.julyday.hibernate.annotation;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "t_account")
@SuppressWarnings("serial")
public class Account implements Serializable {
	private int id;
	private String name;

	public Account(String name) {
		this.name = name;
	}

	public Account() {
	}
	
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	@Column(name="name")
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}
@Entity告訴Hibernate這是個實體類
@Table表名,catalog表示數據庫,這裏我們的url已經配置了hibernate,我們就不配置了。
@Id 主鍵
@GeneratedValue 主鍵值的策略
@Column 字段,unique 唯一 nullable是否爲空 length長度
package com.julyday.hibernate.annotation;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="t_user")
@SuppressWarnings("serial")
public class User implements Serializable{
	private int id;
	private String name;
	private String password;
	private Date birthday;
	private Address address;
	
	public User() {
	}

	public User(String name, String password, Date birthday,Address address) {
		this.name = name;
		this.password = password;
		this.birthday = birthday;
		this.address = address;
	}
	
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	@Column(name="name",length = 20)
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	@Column(name="password",length = 16)
	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}
	
	@Column(name="birthday")
	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
	
	@Embedded
	@AttributeOverrides(value = { 
			@AttributeOverride(column = @Column(name="a_postcode"), name = "postcode"),
			@AttributeOverride(column = @Column(name="a_phone"), name = "phone"),
			@AttributeOverride(column = @Column(name="a_street"), name = "street") 
	})
	public Address getAddress() {
		return address;
	}

	public void setAddress(Address address) {
		this.address = address;
	}
	
}
package com.julyday.hibernate.annotation;

import javax.persistence.Embeddable;

@Embeddable
public class Address {
	private String postcode;
	private String phone;
	private String street;
	public Address(String postcode, String phone, String street) {
		super();
		this.postcode = postcode;
		this.phone = phone;
		this.street = street;
	}
	public Address() {
	}
	public String getPostcode() {
		return postcode;
	}
	public void setPostcode(String postcode) {
		this.postcode = postcode;
	}
	public String getPhone() {
		return phone;
	}
	public void setPhone(String phone) {
		this.phone = phone;
	}
	public String getStreet() {
		return street;
	}
	public void setStreet(String street) {
		this.street = street;
	}
	
	
}
@Embedded 嵌入 就是我們的組件類
@AttributeOverrides 組件類裏面的字段映射
@Embeddable 告訴Hibernate他是一個組件類
cfg增加:<mapping class="com.julyday.hibernate.annotation.Account"/>
    <mapping class="com.julyday.hibernate.annotation.User"/>
OK 全部測試下:
package com.julyday.hibernate.annotation;

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class TestAccount {
	
	private SessionFactory sessionFactory;
	private Session session;
	private Transaction transaction;
	
	@Before
	public void init(){
		StandardServiceRegistry  serviceRegistry=new StandardServiceRegistryBuilder().configure().build();
		sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();
		session = sessionFactory.openSession();
		transaction = session.beginTransaction();
	}
	
	@After
	public void distory(){
		transaction.commit();
		session.close();
		sessionFactory.close();
	}

	
	@Test
	public void testAccount(){
		Account a = new Account("julyday");
		session.save(a);
	}
	
	@Test
	public void testUser(){
		Address address = new Address("100001","12345678987","beijing");
		User u = new User("julyday","123456",new Date(),address);
		session.save(u);
	}
}
一對多:
package com.julyday.hibernate.one2many.annotation;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;

@Entity
@Table(name="t_grade")
@SuppressWarnings("serial")
public class Grade implements Serializable {
	private int gid;
	private String gname;
	private String gdesc;
	private Set<Student> students = new HashSet<Student>();

	@OneToMany(cascade=CascadeType.ALL)
	@JoinColumn(name="gid")
	public Set<Student> getStudents() {
		return students;
	}

	public void setStudents(Set<Student> students) {
		this.students = students;
	}

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	public int getGid() {
		return gid;
	}

	public void setGid(int gid) {
		this.gid = gid;
	}

	@Column(name="gname",length=20)
	public String getGname() {
		return gname;
	}

	public void setGname(String gname) {
		this.gname = gname;
	}

	@Column(name="gdesc",length=100)
	public String getGdesc() {
		return gdesc;
	}

	public void setGdesc(String gdesc) {
		this.gdesc = gdesc;
	}

	public Grade() {
		super();
	}

	public Grade(String gname, String gdesc) {
		super();
		this.gname = gname;
		this.gdesc = gdesc;
	}

	@Override
	public String toString() {
		return "Grade [gid=" + gid + ", gname=" + gname + ", gdesc=" + gdesc
				+ "]";
	}

}

package com.julyday.hibernate.one2many.annotation;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="t_student")
@SuppressWarnings("serial")
public class Student implements Serializable {
	private int sid;
	private String name;
	private int age;
	
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	public int getSid() {
		return sid;
	}

	public void setSid(int sid) {
		this.sid = sid;
	}

	@Column(name="name",length=20)
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Column(name="age",length=3)
	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Student() {

	}

	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}

	@Override
	public String toString() {
		return "Student [sid=" + sid + ", name=" + name + ", age=" + age + "]";
	}

}
@JoinColumn(name="gid")註釋本表中指向另一個表的外鍵。
cfg增加:<mapping class="com.julyday.hibernate.one2many.annotation.Grade"/>
    <mapping class="com.julyday.hibernate.one2many.annotation.Student"/>

ok測試下:
package com.julyday.hibernate.one2many.annotation;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;


public class TestOne2many {
	private SessionFactory sessionFactory;
	private Session session;
	private Transaction transaction;
	
	@Before
	public void init(){
		StandardServiceRegistry  serviceRegistry=new StandardServiceRegistryBuilder().configure().build();
		sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();
		session = sessionFactory.openSession();
		transaction = session.beginTransaction();
	}
	
	@After
	public void distory(){
		transaction.commit();
		session.close();
		sessionFactory.close();
	}
	
	@Test
	public void testOne2many(){
		Grade g1 = new Grade("java","java學前班");
		Student stu1 = new Student("julyday",18);
		Student stu2 = new Student("lisi",38);
		g1.getStudents().add(stu1);
		g1.getStudents().add(stu2);
		session.save(g1);
		session.save(stu1);
		session.save(stu2);
	}
	
	@Test
	public void delete(){
//		Student stu1 = session.get(Student.class, 2);
//		session.delete(stu1);
		Grade g = session.get(Grade.class, 1);
		session.delete(g);
	}
	
}
多對一差不多就不貼代碼了,有興趣的朋友可以下載代碼自己看。
多對多:
package com.julyday.hibernate.many2many.annotation;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.NamedQuery;
import javax.persistence.Table;

@Entity
@Table(name="t_student")
@SuppressWarnings("serial")
@NamedQuery(name = "findAll", query = " from Student")
public class Student implements Serializable {
	private int sid;
	private String name;
	private int age;
	private Set<Teacher> teachers = new HashSet<Teacher>();
	
	@ManyToMany(cascade=CascadeType.ALL)
	@JoinTable(name="t_teacher_student",
		joinColumns={@JoinColumn(name="sid")},inverseJoinColumns={@JoinColumn(name="tid")})
	public Set<Teacher> getTeachers() {
		return teachers;
	}

	public void setTeachers(Set<Teacher> teachers) {
		this.teachers = teachers;
	}

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	public int getSid() {
		return sid;
	}

	public void setSid(int sid) {
		this.sid = sid;
	}

	@Column(name="name",length=20)
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Column(name="age",length=3)
	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Student() {

	}

	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}

	@Override
	public String toString() {
		return "Student [sid=" + sid + ", name=" + name + ", age=" + age + "]";
	}
}
package com.julyday.hibernate.many2many.annotation;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

@Entity
@Table(name="t_teacher")
@SuppressWarnings("serial")
public class Teacher implements Serializable{
	private int tid;
	private String name;
	private int age;
	private Set<Student> students = new HashSet<Student>();

	@ManyToMany(mappedBy="teachers")
	public Set<Student> getStudents() {
		return students;
	}

	public void setStudents(Set<Student> students) {
		this.students = students;
	}

	@Column(name="name",length=20)
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Column(name="age",length=3)
	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	public int getTid() {
		return tid;
	}

	public void setTid(int tid) {
		this.tid = tid;
	}

	public Teacher(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public Teacher() {
		super();
	}

	@Override
	public String toString() {
		return "Teacher [tid=" + tid + ", name=" + name + ", age=" + age + "]";
	}
}
cfg增加:<mapping class="com.julyday.hibernate.many2many.annotation.Teacher"/>
    <mapping class="com.julyday.hibernate.many2many.annotation.Student"/>
@NamedQuery是一個命名的查詢,本來準備講下簡單的HQL,由於太多,這裏就不多說了。
@ManyToMany 多對多的標誌,這裏我們同樣設置了cascade
@JoinTable,多對多的中間表,joinColumns 關聯關係誰來維護,即誰是主表,inverseJoinColumns交出關聯關係,關聯關係由另一個維護,即從表。
測試下:
package com.julyday.hibernate.many2many.annotation;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

@SuppressWarnings("unchecked")
public class TestMany2many {
	private SessionFactory sessionFactory;
	private Session session;
	private Transaction transaction;
	
	@Before
	public void init(){
		StandardServiceRegistry  serviceRegistry=new StandardServiceRegistryBuilder().configure().build();
		sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();
		session = sessionFactory.openSession();
		transaction = session.beginTransaction();
	}
	
	@After
	public void distory(){
		transaction.commit();
		session.close();
		sessionFactory.close();
	}
	
	@Test
	public void testMany2many(){
		Student stu1 = new Student("julyday",18);
		Student stu2 = new Student("zhangsan",19);
		Teacher tea1 = new Teacher("lisi",48);
		Teacher tea2 = new Teacher("wangwu",49);
		
		Set<Teacher> ts = new HashSet<Teacher>();
		ts.add(tea1);
		ts.add(tea2);
		stu1.setTeachers(ts);
		stu2.setTeachers(ts);
		
//		Set<Student> ss = new HashSet<Student>();
//		ss.add(stu1);
//		ss.add(stu2);
//		tea1.setStudents(ss);
//		tea2.setStudents(ss);
		
		session.save(tea1);
		session.save(tea2);
		session.save(stu1);
		session.save(stu2);
	}
	
	@Test
	public void select(){
		String sql = "from Student";
		List<Student> list = (List<Student>)session.createQuery(sql).list();
		for(Student stu : list){
			System.out.println(stu.toString());
		}
	}
	
	@Test
	public void selectAll(){
//		String sql = "from com.julyday.hibernate.many2many.annotation.Student";
//		List<Student> list = (List<Student>)session.createQuery(sql).list();
//		for(Student stu : list){
//			System.out.println(stu.toString());
//		}
		List<Student> list = (List<Student>)session.getNamedQuery("findAll").list();
		for(Student stu : list){
			System.out.println(stu.toString());
		}
	}
	
	
	@Test
	public void selectWhere(){
		String sql = "from Student s where s.age = 18";
		List<Student> list = (List<Student>)session.createQuery(sql).list();
		for(Student stu : list){
			System.out.println(stu.toString());
		}
	}
	
	@Test
	public void selectWhereGt(){
		String sql = "from Student s where s.age > 18";
		List<Student> list = (List<Student>)session.createQuery(sql).list();
		for(Student stu : list){
			System.out.println(stu.toString());
		}
	}
	
	@Test
	public void selectOrderBy(){
		String sql = "from Student s order by age desc";
		List<Student> list = (List<Student>)session.createQuery(sql).list();
		for(Student stu : list){
			System.out.println(stu.toString());
		}
	}
}

當然這裏有我準備的簡單HQL,這裏就不多說了,有興趣的朋友找其他資料學習學習。
最後放上全部代碼:







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章