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,这里就不多说了,有兴趣的朋友找其他资料学习学习。
最后放上全部代码:







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