在实际开发中,数据库表之间关系有很多种情况,其中共有一个是联合主键,就是中由两个以上的属性同时担任主键,
今天我们就来学习一下,联合主键怎么设计实体类,以及怎么写实体类对应的配置文件*.hbm.xml,
新建一个项目名称为:06hibernate_composite_id,结构如下:
项目以分数实体类为例,
导入jar包,参见《Hibernate环境搭建和配置》
hibernate.cfg.xml配置文件代码:
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 配置数据库连接信息 -->
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="connection.url">jdbc:mysql:///hibernate4</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<!-- 数据库方言 -->
<property name="hibernate.dialect">
org.hibernate.dialect.MySQL5Dialect
</property>
<!-- 是否打印sql语句 -->
<property name="show_sql">true</property>
<!-- 格式化sql语句 -->
<property name="format_sql">true</property>
<!-- 数据库更新方式:
1、create:每次更新都先把原有数据库表删除,然后创建该表;
2、create-drop:使用create-drop时,在显示关闭SessionFacroty时(sessionFactory.close()),将drop掉数据库Schema(表)
3、validate:检测;
4、update(常用):如果表不存在则创建,如果存在就不创建
-->
<property name="hbm2ddl.auto">update</property>
<!-- 加载User实体类对应的配置文件 -->
<mapping resource="com/robert/pojo/Score.hbm.xml" />
</session-factory>
</hibernate-configuration>
新建实体类:
Score类代码:
package com.robert.pojo;
public class Score {
private ScoreId scoreId ;
private double result ;//成绩
public double getResult() {
return result;
}
public void setResult(double result) {
this.result = result;
}
public ScoreId getScoreId() {
return scoreId;
}
public void setScoreId(ScoreId scoreId) {
this.scoreId = scoreId;
}
}
ScoreId代码:
package com.robert.pojo;
import java.io.Serializable;
public class ScoreId implements Serializable{
private int stuId;// 学生编码
private int subjectId;// 科目编号
public int getStuId() {
return stuId;
}
public void setStuId(int stuId) {
this.stuId = stuId;
}
public int getSubjectId() {
return subjectId;
}
public void setSubjectId(int subjectId) {
this.subjectId = subjectId;
}
}
Score.hbm.xml配置文件代码:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.robert.pojo">
<class name="Score" table="score">
<!-- 联合主键 composite-id中的配置如下:
name:是class是Score中的主键,这里是:scoreId
class:是scoreId主键对应的联合主键的类,这里是ScoreId类
key-property:是联合主键所在的类ScoreId中的两个主键
-->
<composite-id name="scoreId" class="ScoreId">
<key-property name="stuId"></key-property>
<key-property name="subjectId"></key-property>
</composite-id>
<property name="result"></property>
</class>
</hibernate-mapping>
Score.hbm.xml中联合主键和实体类的对应关系图:
在hibernate.cfg.xml配置文件中,加入实体类对应的配置文件,如图:
HibernateUtil类封装了Hibernate获得Session和关闭Session的操作,代码如下:
package com.robert.util;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static Configuration cfg = null;
private static SessionFactory factory = null;
private static Session session = null ;
static {
init();
}
public static void init() {
cfg = new Configuration().configure();
factory = cfg.buildSessionFactory(new StandardServiceRegistryBuilder()
.applySettings(cfg.getProperties()).build());
}
public static Session getSession() {
if (factory != null){
return session = factory.openSession();
}
init();
return session = factory.openSession();
}
public static void closeSession() {
if(session!=null && session.isOpen())
session.close();
}
}
测试类HibernateTest类的代码如下:
package com.robert.test;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.Test;
import com.robert.pojo.Score;
import com.robert.pojo.ScoreId;
import com.robert.util.HibernateUtil;
public class HibernateTest {
/**
* 根据*.hbm.xml文件对应的生成数据库表
*/
@Test
public void testCreateDB() {
Configuration cfg = new Configuration().configure() ;
SchemaExport se = new SchemaExport(cfg) ;
//第一个参数:是否生成ddl脚本
//第二个参数:是否执行到数据库中
se.create(true, true) ;
}
@Test
public void testSave() throws HibernateException{
Session session = null ;
Transaction tx = null ;
try {
session = HibernateUtil.getSession() ;
tx = session.beginTransaction();
Score s = new Score();
ScoreId sid = new ScoreId() ;
sid.setStuId(2) ;
sid.setSubjectId(7) ;
s.setResult(89) ;
s.setScoreId(sid) ;
session.save(s) ;
tx.commit();
} catch (HibernateException e) {
if(tx!=null) {
tx.rollback();
}
e.printStackTrace();
throw e ;
}finally {
HibernateUtil.closeSession() ;
}
}
}
使用Junit4运行测试方法,如图:
看到是Junit4是绿色的条,说明运行成功,看控制台有insert的sql语句,如图:
查看数据库,数据已经进入,如图: