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,表示采用数据门默认的主键生成策略。
我们把路径选到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。
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>
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"/>
<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"/>
<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,由于太多,这里就不多说了。
<mapping class="com.julyday.hibernate.many2many.annotation.Student"/>
@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,这里就不多说了,有兴趣的朋友找其他资料学习学习。
最后放上全部代码: