一对一:一张A表中的一条记录与另一张B表的一条记录关联(字段一样),并且B表中关联的那个字段(外键)受到A表主键的影响(删除、更新,创建)
实现方式:类(持久化类),映射文件,配置文件
单向:唯一外键关联(建议使用)、主键关联
持久化类:
public class User implements java.io.Serializable {
private Integer userid;
private String username;
//多对一单向就没有
private Card card;//一对一
private Set card;//一对多或者多对一
}
public class Card implements java.io.Serializable {
private Integer cardid;
private Integer cardnum;
//单向就没有其他对象的引用
private User user;//一对一双向 或者一对多双向
prvate Set user;//多对多双向
}
操作类
public class HibernateUtil{
public static final SessionFactory sessionFactory;
static {
try{
sessionFactory=new Configuration().configure.buildSessionFactory();
}catch(Throwable ex){
}
}
public static final ThreadLocal session=new ThreadLocal();
public Staic Session currenSession()throws HibernateException{
Session s=(Session)session.get();
if(s==null){
s=sessionFactory.openSession();
session.set(s);
}
return s;
}
public static void closeSession()throws HibernateException{
Session s=(Session)session.get();
if(s!=null){
s.close();
session.set(null);
}
}
public class Test{
public static void main(String args[]){
Session session=Hibernate.currenSession();
Transaction tx=session.beginTransaction();
//增删改查
tx.commit();
session.close;
}??
一对一映射文件
主键关联
<hibernate-mapping>
<class name="Person" table="person">
<id name="id" column="personId">
<gernerator class="native"/>
</id>
</class>
<class name="Address" table="address">
<id name="id" column="addressId">
<gernerator class="foreign">
<param name="property">person</param>
</gernerator>
</id>
<one-to-one name="person" constrained="true"/> //constrained表示主键的值改变会影响外键
</class>??
</hibernate-mapping>
唯一外键关联
<class name="Person">
<id name="id" column="personId">
<gernerator class="native"/>
</id>
<many-to-one name="address"
column="addressId"
unique="true"
not-null="true"/>
</class>
<class name="Address">
<id name="id" column="addressId">
<gernerator class="native"/>
</id>
</class>??
配置文件
hibernate.cfg.xml
<!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="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- 设置数据库URL -->
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_first</property>
<!-- 数据库用户名 -->
<property name="hibernate.connection.username">root</property>
<!-- 数据库密码 -->
<property name="show_sql">true</property>//是否显示SQL
<property name="format_sql">false</property>//是否格式化sql
<property name="hibernate.hbm2ddl.auto">update</property>
<!--create: 先删表,再建表。
create-drop: 启动时建表,退出前删表。
update: 如果表结构不一致,就创建或更新。
validate: 启动时验证表结构,如果不致就抛异常-->
<property name="hibernate.connection.password">123456</property>
<!-- 指定对应数据库的方言,hibernate为了更好适配各种关系数据库,针对每种数据库都指定了一个方言dialect -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 映射文件 -->
<mapping resource="com/liang/hibernate/User.hbm.xml"/>
一对多:一张A表中的一条记录与另一张B表的多条记录关联
多对一:一张A表中的多条条记录与另一张B表的一条记录关联
多对多“:一张A表中的多条条记录与另一张B表的多条记录关联
注意:多对多关联不管单向还是双向都只能使用连接表(创建第三个表),容易造成数据冗余。其他一对一、多对一、一对多都可以选择是否使用单向或者双向连接表。
映射文件解释:
1
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<!-- 映射文件开始 -->
<hibernate-mapping>
<!-- 下面的class节点定义了Province类和对应数据库表之间的关联关系 -->
<class name="com.xxx.hibernate.Province" table="Province" >
<!-- 下面的两个节点定义了Province类中的属性和该类对应数据库表中的字段之间的关联关系,其中Guid为对应数据库表的主键 -->
<id name="guid" type="int" column="Guid">
<generator class="native" /> //主键外键
</id>
<property
name="provincename"
type="java.lang.String" //对象属性映射关系字段
column="Provincename"
not-null="true"
length="16">
</property>
<!-- 下面的set节点定义了Province类和City类之间的”一对多“型关联关系 -->
<set
table="" 连接表
name="cities"<!-- 集合属性的名称 -->
lazy="true"<!-- 是否允许延迟加载 -->
inverse="true"<!-- 定义这个集合是否为双向关联关系中的方向一端 如果教给对方,对方对外键所做的修改就不影响对方的主键 -->
cascade="delete"<!-- 定义有关操作是否关联到子实体(此处指City类对象) -->
>
<key>
<column name="ProvinceID" /><!-- 是Province表主键,是city外键-->
</key>
<one-to-many
class="City"<!-- 定义集合所属的类-->
/>
</set>
</class>
</hibernate-mapping>
2
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"
>
<!-- 映射文件开始 -->
<hibernate-mapping>
<!-- 下面的class节点定义了City类和对应数据库表之间的关联关系 -->
<class
name="com.xxx.hibernate.City"
table="City"
>
<!-- 下面的两个节点定义了City类中的属性和该类对应数据库表中的字段之间的关联关系,其中Guid为对应数据库表的主键-->
<id
name="guid"
type="int"
column="Guid"
>
<generator class="native" />
</id>
<property
name="cityname"
type="java.lang.String"
column="Cityname"
not-null="true"
length="32"
>
</property>
<!-- 下面的many-to-one节点定义了Province类和City类之间的”一对多“型关联关系 -->
<many-to-one
name="province"<!-- 属性名称 -->
class="com.xxx.hibernate.Province"<!-- 属性所属的类 -->
cascade="none"<!-- 指定哪些操作会从父对象(此处指City类对象)级联到子对象(此处指Province类对象) -->
outer-join="auto"<!-- 设置父子对象之间是否存在外连接 -->
not-null="true"<!-- 指定该属性是否一定为非空 -->
>
<column name="ProvinceID" /><!-- 定义父对象(此处指City类对象)所对应的数据库表的外键 -->
</many-to-one>
</class>
</hibernate-mapping>
注意: inverse只能设置一个
采用数据库中创建表
create table Person(personId bigint not null primary)
create table PersonAddress(personId bigint not null,addrssId bigint not null,primary key(personId,addressId)
create table Address(addressId bigint not null primary key)