0.pom.xml
...... <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <hibernate-version>3.6.10.Final</hibernate-version> <javassist-version>3.12.1.GA</javassist-version> <slf4j-nop-version>1.6.6</slf4j-nop-version> <mysql-connector-version>5.1.21</mysql-connector-version> </properties> <dependencies> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>${hibernate-version}</version> </dependency> <dependency> <groupId>javassist</groupId> <artifactId>javassist</artifactId> <version>${javassist-version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-nop</artifactId> <version>${slf4j-nop-version}</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql-connector-version}</version> </dependency> </dependencies> ......
1.schema.sql
drop table if exists idcard; drop table if exists student; create table idcard ( iid integer not null, num integer, primary key (iid) ); create table student ( sid integer not null auto_increment, name varchar(255), primary key (sid) );
表结构如下图所示
2.hibernate.cfg.xml
<?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.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost:3306/test</property> <property name="connection.username">root</property> <property name="connection.password">123456</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="show_sql">true</property> <property name="format_sql">false</property> <!-- <mapping resource="org/fool/model/Student.hbm.xml" /> --> <!-- <mapping resource="org/fool/model/IdCard.hbm.xml" /> --> <mapping class="org.fool.model.Student" /> <mapping class="org.fool.model.IdCard" /> </session-factory> </hibernate-configuration>
这里使用Student表和IdCard表进行一对一关联
3.Student.java
package org.fool.model; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToOne; import javax.persistence.Table; import org.hibernate.annotations.Fetch; import org.hibernate.annotations.FetchMode; @Entity @Table(name = "student") public class Student { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "sid") private int id; @Column(name = "name") private String name; @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "student") @Fetch(FetchMode.SELECT) private IdCard idCard; 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 IdCard getIdCard() { return idCard; } public void setIdCard(IdCard idCard) { this.idCard = idCard; } }
以上的annotation就相当于以下的Student.hbm.xml文件,可以进行对比一下
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="org.fool.model.Student" table="student"> <id name="id" column="sid" type="integer"> <generator class="identity"> </generator> </id> <property name="name" column="name" type="string" /> <one-to-one name="idCard" class="org.fool.model.IdCard" cascade="all" fetch="select"></one-to-one> </class> </hibernate-mapping>
4.IdCard.java
package org.fool.model; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToOne; import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.Table; import org.hibernate.annotations.Fetch; import org.hibernate.annotations.FetchMode; import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.Parameter; @Entity @Table(name = "idcard") public class IdCard { @Id @GenericGenerator(name = "generator", strategy = "foreign", parameters = @Parameter(name = "property", value = "student")) @GeneratedValue(generator = "generator") @Column(name = "iid") private int id; @Column(name = "num") private int num; @OneToOne(fetch = FetchType.LAZY) @PrimaryKeyJoinColumn @Fetch(FetchMode.SELECT) private Student student; public int getId() { return id; } public void setId(int id) { this.id = id; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } public Student getStudent() { return student; } public void setStudent(Student student) { this.student = student; } }
以上的annotation就相当于以下的IdCard.hbm.xml文件,可以进行对比一下
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="org.fool.model.IdCard" table="idcard"> <id name="id" column="iid" type="integer"> <generator class="foreign"> <param name="property">student</param> </generator> </id> <property name="num" column="num" type="integer" /> <one-to-one name="student" class="org.fool.model.Student" fetch="select"></one-to-one> </class> </hibernate-mapping>
5.HibernateUtil.java
package org.fool.util; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUtil { private static SessionFactory sessionFactory; static { try { sessionFactory = new Configuration().configure() .buildSessionFactory(); } catch (Exception ex) { System.err.println("构造SessionFactory异常发生: " + ex.getMessage()); } } public static Session openSession() { Session session = sessionFactory.openSession(); return session; } public static void closeSession(Session session) { if (null != session) { session.close(); } } }
6.HibernateTest.java
package org.fool.test; import org.fool.model.IdCard; import org.fool.model.Student; import org.fool.util.HibernateUtil; import org.hibernate.Session; import org.hibernate.Transaction; public class HibernateTest { public static void main(String[] args) throws Exception { // insert(); // selectStudent(); // updateStudent(); // delete(); } /** * 添加信息 */ public static void insert() { Session session = HibernateUtil.openSession(); Transaction tx = null; try { tx = session.beginTransaction(); Student student = new Student(); student.setName("zhangsan"); IdCard idCard = new IdCard(); idCard.setNum(123456); student.setIdCard(idCard); idCard.setStudent(student); session.save(student); tx.commit(); } catch (Exception e) { e.printStackTrace(); if (null != tx) { tx.rollback(); } } finally { HibernateUtil.closeSession(session); } } /** * 查询学生信息 */ public static void selectStudent() { Session session = HibernateUtil.openSession(); Transaction tx = null; Student student = null; try { tx = session.beginTransaction(); student = (Student) session.get(Student.class, 1); tx.commit(); } catch (Exception e) { e.printStackTrace(); if (null != tx) { tx.rollback(); } } finally { HibernateUtil.closeSession(session); } System.out.println(student.getName()); System.out.println(student.getIdCard().getNum()); } /** * 更新学生信息 */ public static void updateStudent() { Session session = HibernateUtil.openSession(); Transaction tx = null; Student student = null; try { tx = session.beginTransaction(); student = (Student) session.get(Student.class, 1); student.setName("lisi"); tx.commit(); } catch (Exception e) { e.printStackTrace(); if (null != tx) { tx.rollback(); } } finally { HibernateUtil.closeSession(session); } System.out.println(student.getName()); } /** * 级联删除 */ public static void delete() { Session session = HibernateUtil.openSession(); Transaction tx = null; Student student = null; try { tx = session.beginTransaction(); student = (Student) session.get(Student.class, 1); session.delete(student); tx.commit(); } catch (Exception e) { e.printStackTrace(); if (null != tx) { tx.rollback(); } } finally { HibernateUtil.closeSession(session); } } }
7.总结
主键关联:一对一默认使用的是立即加载,如果需要使用延迟加载,那么需要在one-to-one元素中将constrained属性设为true,并且将待加载的一方的class元素中lazy属性设为true(或者不去设置,因为该属性默认值是true);一对一加载时默认 使用左外连接,可以通过修改fetch属性为select,修改成每次发送一条select语句的形式。