您的位置:首页 > 编程语言 > Java开发

【JavaEE学习笔记】Hibernate_06_注解开发,getCurrentSession(),映射关系

2018-01-22 23:13 736 查看
Hibernate_06

A.注解

1.概述

每个持久化POJO类都是一个实体Bean

通过在类的定义中使用@Entity注解来进行声明

目前定义属性对应的列时有两种定义方法

a.定义在属性上

b.定义在get方法上

两种方法是等价的,目前没有选择标准,但一个类中只能使用一种方法

2.常用字段属性

name="cloumnName"当前属性对应的列名,如果列名称和属性名称一致,可以省略
boolean unique() default false是否在该列上设置唯一约束,一般开发阶段不建议定义大量的约束
boolean nullable() default true设置对应的列是否允许为空
boolean insertable() default true该列是否作为生成insert语句的一个列
boolean updatable() default true该列是否作为生成update语句的一个列
String columnDefinition() default直接定义对应列的配置,但是会导致跨数据库平台性的丢失
String table() default ""定义对应的表  default是主表
int length() default 255针对字串类型的列定义长度
int percision() default 0针对数字类型的列定义数值精度
int scale() default 0针对数值类型的列定义数值精度,这里定义小数位数
3.常用注解

Entity定义实体类
Column定义属性
Temporal用于给日期类型定义获时的精度:Date获取日期,Time获取时间,Timestamp获取日期时间
Transient,Basic所有非static非transient属性都可以被持久化,除非用transient注解,默认都为Basic
Id可以将某个属性定义为主键
GenerateValue定义该标识符的生成策略
AUTO可以是identity column,squence或者table类型,取决于不同底层的数据库
4.使用步骤

导入hibernate,mysql驱动

建立UserBean

package org.wpf.entity;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

// 定义为实体类,数据库中的表名为t_users
@Entity(name = "t_users")
public class UserBean implements Serializable {

private static final long serialVersionUID = -5771488248839932252L;

// 主键
@Id
// 定义标识符生成策略
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

// 长度为20,不能为空,唯一
@Column(length = 20, nullable = false, unique = true)
private String username;

// 长度为20,不能为空
@Column(length = 20, nullable = false)
private String password;

// 获取日期
@Temporal(TemporalType.DATE)
// 设置该列值默认为系统当前时间
@Column(columnDefinition = "timestamp default current_timestamp")
private Date birth;

// 宽度为8,精度为2
@Column(precision = 8, scale = 2)
private Double salary;

// 默认值为1
@Column(columnDefinition = "boolean default 1")
private boolean sex;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public Date getBirth() {
return birth;
}

public void setBirth(Date birth) {
this.birth = birth;
}

public Double getSalary() {
return salary;
}

public void setSalary(Double salary) {
this.salary = salary;
}

public boolean isSex() {
return sex;
}

public void setSex(boolean sex) {
this.sex = sex;
}

}

配置hibernate.cfg.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<!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="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>

<!-- 此处映射为javaBean -->
<mapping class="org.wpf.entity.UserBean" />
</session-factory>
</hibernate-configuration>
测试类
package org.wpf.entity;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.service.ServiceRegistry;

public class Demo01 {
public static void main(String[] args) {
ServiceRegistry sr = new StandardServiceRegistryBuilder().configure().build();
SessionFactory fac = new MetadataSources(sr).buildMetadata().buildSessionFactory();
Session session = fac.openSession();
Transaction tx = session.beginTransaction();
UserBean u1 = new UserBean();
u1.setUsername("zhangsan");
u1.setPassword("123456");
session.save(u1);
tx.commit();
session.close();
fac.close();
}
}
查看控制台



查看数据库表



查看数据



5.annotation主键生成策略

一般情况下都是使用annoation的标准注解

标准的annotation方式的主键生成策略:auto table identity squence

table使用表保存id(创建一张专门保存id的表,记录对应的表的对应最大id值)

@javax.persistence.TableGenerator(

name="EMP_GEN",生成器的名称

table="GENERATOR_TABLE",额外表的名称

pkColumnName="key",额外表的主键列的名称

valueColumnName="hi",额外表的id值对应列的名称

pkColumnValue="EMP",额外表的主键列的值

allocationSize=20,额外表的id增长的步长值

)

package org.wpf.entity;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.TableGenerator;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

// 定义为实体类,数据库中的表名为t_users
@Entity(name = "t_users")
public class UserBean implements Serializable {

private static final long serialVersionUID = -5771488248839932252L;

// 主键生成策略
@TableGenerator(name = "EMP_GEN",
table = "GENERATOR_TABLE",
pkColumnName = "key1",
valueColumnName = "hi",
pkColumnValue = "abc",
allocationSize = 20)
// 主键
@Id
// 定义标识符生成策略
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

// 长度为20,不能为空,唯一
@Column(length = 20, nullable = false, unique = true)
private String username;

// 长度为20,不能为空
@Column(length = 20, nullable = false)
private String password;

// 获取日期
@Temporal(TemporalType.DATE)
// 设置该列值默认为系统当前时间
@Column(columnDefinition = "timestamp default current_timestamp")
private Date birth;

// 宽度为8,精度为2
@Column(precision = 8, scale = 2)
private Double salary;

// 默认值为1
@Column(columnDefinition = "boolean default 1")
private boolean sex;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public Date getBirth() {
return birth;
}

public void setBirth(Date birth) {
this.birth = birth;
}

public Double getSalary() {
return salary;
}

public void setSalary(Double salary) {
this.salary = salary;
}

public boolean isSex() {
return sex;
}

public void setSex(boolean sex) {
this.sex = sex;
}

}


B.getCurrentSession

1.openSession()和getCurrentSession()区别

openSession()每次都会新建一个Session

getCurrentSession首先从上下文中查找是否有session,有则获取,无则新建

getCurrentSession需要有对应的事物支持,当事务结束时会自动关闭session

openSession必须手动关闭

getCurrentSession的使用需要有额外配置

<property name="hibernate.current_session_context_class">thread</property>

2.引入getCurrentSession()后的工具类

package org.wpf.util;

import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.service.ServiceRegistry;

public class HibernateSessionFactory {
private static SessionFactory sessionFactory;

static {
buildSessionFactory();
}

// 私有构造
private HibernateSessionFactory() {
}

// 获取SessionFactory
public static SessionFactory getSessionFactory() {
return sessionFactory;
}

// 创建session工厂
private static void buildSessionFactory() throws HibernateException {
// 如果没有
if (sessionFactory == null) {
ServiceRegistry sr = new StandardServiceRegistryBuilder().configure().build();
sessionFactory = new MetadataSources(sr).buildMetadata().buildSessionFactory();
}
}
}


3.过滤器

package org.wpf.fliter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.wpf.util.HibernateSessionFactory;

public class OpenSessionInViewFilter implements Filter {

@Override
public void destroy() {
}

@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
try {
// 开启事物
HibernateSessionFactory.getSessionFactory().getCurrentSession().beginTransaction();
// 放行
arg2.doFilter(arg0, arg1);
// 提交事物
HibernateSessionFactory.getSessionFactory().getCurrentSession().getTransaction().commit();
} catch (Exception e) {
// 回滚
HibernateSessionFactory.getSessionFactory().getCurrentSession().getTransaction().rollback();
}
}

@Override
public void init(FilterConfig arg0) throws ServletException {
}

}


C.映射关系

1.常见映射关系

一对一

一对多或多对一

多对多

关联关系实际开发中可以分为单向关联和双相关联

2.一对多查询

一对多或多对一的关联在实际开发中用的比较多

一个简单的例子就是客户与订单的关系

一个客户可能发出多个订单,而每个订单只属于一个客户

这样,如果从客户指向订单,这种关系就属于一对多的关系



在关系数据库中,只有存在外键参照关系,而且总是由many方参照one方

因此,在关系数据库中,实际支持多对一或一对一的单项关联即可

3.Oracle中的SQL可以分为4大类

DDL数据定义语言 create drop alter truncate

DML数据操纵语言 insert update delete select

DCL数据控制语言 grant revoke [with admin option 和 with grant option]

TCL事物控制语言 commit rollback savepoint

4.截断操作 truncate table t_users

truncate属于DDL,没有事物的概念,删除后没有办法恢复

不会记录日志信息,所以删除大量数据时,执行效率远高于delete from

5.定义一对多

一方Customer

package org.wpf.entity;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

public class Customer implements Serializable {
private static final long serialVersionUID = 4313768320545350900L;

private Long id;
private String name;
// 这是类中表示1对多关联的方式,表示一个Customer中包含了多个Order
private Set<Order> orders = new HashSet<>(0);

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Set<Order> getOrders() {
return orders;
}

public void setOrders(Set<Order> orders) {
this.orders = orders;
}

@Override
public String toString() {
return "Customer [id=" + id + ", name=" + name + ", orders=" + orders + "]";
}

}

Customer.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">
<hibernate-mapping>
<class name="org.wpf.entity.Customer" table="t_customer">
<id name="id" type="java.lang.Long">
<column name="ID" />
<generator class="identity" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" length="20" not-null="true" />
</property>
<set name="orders" inverse="true" cascade="all">
<key>
<column name="customer_id" not-null="true" />
</key>
<one-to-many class="org.wpf.entity.Order" />
</set>
</class>
</hibernate-mapping>

多方Order

package org.wpf.entity;

import java.io.Serializable;
import java.util.Date;

public class Order implements Serializable {

private static final long serialVersionUID = 5875230206918806994L;

private Long id;
private Customer customer;
private Date oDate;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public Customer getCustomer() {
return customer;
}

public void setCustomer(Customer customer) {
this.customer = customer;
}

public Date getoDate() {
return oDate;
}

public void setoDate(Date oDate) {
this.oDate = oDate;
}

@Override
public String toString() {
return "Order [id=" + id + ", customer=" + customer + ", oDate=" + oDate + "]";
}

}

Order.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">
<hibernate-mapping>
<class name="org.wpf.entity.Order" table="T_ORDER">
<id name="id" type="java.lang.Long">
<column name="ID" />
<generator class="identity" />
</id>
<many-to-one name="customer" class="org.wpf.entity.Customer"
fetch="select">
<column name="customer_id" not-null="true" />
</many-to-one>
<property name="oDate" type="java.util.Date">
<column name="odate" length="19" not-null="true" />
</property>
</class>
</hibernate-mapping>

在配置文件中添加映射

<mapping resource="org/wpf/entity/Customer.hbm.xml"/>
<mapping resource="org/wpf/entity/Order.hbm.xml"/>测试类
package org.wpf.entity;

import java.util.Date;

import org.hibernate.Session;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.wpf.util.HibernateSessionFactory;

class Test01 {

@BeforeEach
void setUp() throws Exception {
HibernateSessionFactory.getSessionFactory().getCurrentSession().beginTransaction();
}

@AfterEach
void tearDown() throws Exception {
HibernateSessionFactory.getSessionFactory().getCurrentSession().getTransaction().commit();
}

@Test
void test() {
// 级联需要互相通知
Customer c1 = new Customer();
c1.setName("Tom");

Order o1 = new Order();
o1.setoDate(new Date());

Order o2 = new Order();
o2.setoDate(new Date());

// 相互通知
c1.getOrders().add(o1);
o1.setCustomer(c1);
c1.getOrders().add(o2);
o2.setCustomer(c1);

Session session = HibernateSessionFactory.getSessionFactory().getCurrentSession();
session.save(c1);
}

}
控制台信息
Hibernate:

create table t_customer (
ID bigint not null auto_increment,
NAME varchar(20) not null,
primary key (ID)
) engine=InnoDB
Hibernate:

create table T_ORDER (
ID bigint not null auto_increment,
customer_id bigint not null,
odate datetime not null,
primary key (ID)
) engine=InnoDB
Hibernate:

alter table T_ORDER
add constraint FKfiait2tmbi08bkn450b9c5i54
foreign key (customer_id)
references t_customer (ID)
Hibernate:
insert
into
t_customer
(NAME)
values
(?)
Hibernate:
insert
into
T_ORDER
(customer_id, odate)
values
(?, ?)
Hibernate:
insert
into
T_ORDER
(customer_id, odate)
values
(?, ?)运行结果



6.inverse和cascade

inverse的真正作用就是指定由哪一方来维护之间的关联关系

当一方中制订了inverse=false默认,那么那一方就有责任负责之间的关联关系

就是hibernate如何生成sql来维护关联的记录

区别:

Inverse负责控制关系,默认为false,也就是两端都能控制

但造成一些问题,更新时会因为两端都控制,于是重复更新

一般有一端要设为true

cascade负责控制关联对象的级联操作,包括更新,删除等

也就是说对一个对象进行更新,删除时,其他对象也受影响

那么跟他是多对一的关系的对象也全部被删除

7.其他属性

<set>元素包括以下属性

name:设定待映射的持久化类的属性名

cascade:当取值为save_update时,表示级联保存和更新

<set>元素还可以包括<key>和<one-to-many>两个子元素

<key>元素设定与所关联的持久化类对应表的外键

<one-to-many>元素设定所关联的持久化类

<many-to-one>元素建立了订单和客户表的外键之间的映射

name:设置待映射的持久化类的属性名

column:设定和持久化类的属性对应的表的外键

class:设定持久化类的属性类型

not-null:如果为true,表示客户属性不允许为空

fetech="select":抓取策略的设置,表示获取订单后如何获取对应的客户信息

将fetch修改为join,表示获取客户信息时不是采用发送额外的select语句进行获取,而是采用inner join的方式直接查询客户信息,不会产生额外的SQL语句,采用这样的方式查询效率会略高于发送额外查询的方式

8.注解定义的方式

customer

package org.wpf.entity;

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.OneToMany;
import javax.persistence.OrderBy;

@Entity(name = "t_customer")
public class Customer implements Serializable {
private static final long serialVersionUID = 4313768320545350900L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(length = 32, nullable = false)
private String name;

@OneToMany(mappedBy = "customer", cascade = CascadeType.ALL)
@OrderBy("id desc")
private Set<Order> orders = new HashSet<>(0);

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Set<Order> getOrders() {
return orders;
}

public void setOrders(Set<Order> orders) {
this.orders = orders;
}

@Override
public String toString() {
return "Customer [id=" + id + ", name=" + name + ", orders=" + orders + "]";
}

}

order

package org.wpf.entity;

import java.io.Serializable;
import java.util.Date;

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.ManyToOne;

@Entity(name = "t_order")
public class Order implements Serializable {

private static final long serialVersionUID = 5875230206918806994L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name = "all_price", precision = 8, scale = 2)
private Double allPrice;

@ManyToOne(optional = false)
@JoinColumn(name = "customer_id")
private Customer customer;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public Customer getCustomer() {
return customer;
}

public void setCustomer(Customer customer) {
this.customer = customer;
}

public Double getAllPrice() {
return allPrice;
}

public void setAllPrice(Double allPrice) {
this.allPrice = allPrice;
}

@Override
public String toString() {
return "Order [id=" + id + ", allPrice=" + allPrice + ", customer=" + customer + "]";
}

}

设置配置文件

<mapping class="org.wpf.entity.Customer"/>
<mapping class="org.wpf.entity.Order"/>运行结果
Hibernate:

create table t_customer (
id bigint not null auto_increment,
name varchar(32) not null,
primary key (id)
) engine=InnoDB
Hibernate:

create table t_order (
id bigint not null auto_increment,
all_price double precision,
customer_id bigint not null,
primary key (id)
) engine=InnoDB
Hibernate:

alter table t_order
add constraint FKesy3n2gc3fa0s3trrk3tvyv9a
foreign key (customer_id)
references t_customer (id)
Hibernate:
insert
into
t_customer
(name)
values
(?)
Hibernate:
insert
into
t_order
(all_price, customer_id)
values
(?, ?)
Hibernate:
insert
into
t_order
(all_price, customer_id)
values
(?, ?)


9.一对一

实现方式:

共享主键和唯一外键



10.共享主键

既是主键,又是外键,主控方和受控方

a.xml

Person主控方

package org.wpf.entity;

import java.io.Serializable;

public class Person implements Serializable {

private static final long serialVersionUID = -6446631496216328660L;
private Long id;
private String name;
private Card card;

public Person() {
super();
}

public Person(Long id, String name, Card card) {
super();
this.id = id;
this.name = name;
this.card = card;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Card getCard() {
return card;
}

public void setCard(Card card) {
this.card = card;
}

}

Person.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 2018-1-22 22:27:49 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="org.wpf.entity.Person" table="t_person">
<id name="id" type="java.lang.Long">
<column name="ID" />
<generator class="identity" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" length="10" not-null="true" />
</property>
<one-to-one name="card" class="org.wpf.entity.Card"
cascade="all"></one-to-one>
</class>
</hibernate-mapping>

Card受控方

package org.wpf.entity;

import java.io.Serializable;

public class Card implements Serializable {

private static final long serialVersionUID = 7490343597638703173L;
private Long id;
private Person person;
private String city;

public Card() {
super();
}

public Card(Long id, Person person, String city) {
super();
this.id = id;
this.person = person;
this.city = city;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public Person getPerson() {
return person;
}

public void setPerson(Person person) {
this.person = person;
}

public String getCity() {
return city;
}

public void setCity(String city) {
this.city = city;
}

}

Card.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 2018-1-22 22:27:49 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="org.wpf.entity.Card" table="t_card" catalog="test">
<id name="id" type="java.lang.Long">
<column name="ID" />
<!-- 表明根据对方的主键来生成自己的主键,自己并不能独立生成主键 ,这里表示身份证的主键值是从它属性person的id值中获取的 -->
<generator class="foreign">
<param name="property">person</param>
</generator>
</id>
<!-- constrained="true"表示当前类是受控方,受Person的控制 -->
<one-to-one name="person" class="org.wpf.entity.Person"
constrained="true" />
<property name="city" type="java.lang.String">
<column name="CITY" length="32" />
</property>
</class>
</hibernate-mapping>


b.注解

Husband主控方

package org.wpf.entity;

import java.io.Serializable;

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;

@Entity(name = "t_husband") // 主控方
public class Husband implements Serializable {
private static final long serialVersionUID = 7204300104344481060L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(length = 20, nullable = false)
private String name;

@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "husband")
private Wife wife;

public Husband() {
super();
}

public Husband(Long id, String name, Wife wife) {
super();
this.id = id;
this.name = name;
this.wife = wife;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Wife getWife() {
return wife;
}

public void setWife(Wife wife) {
this.wife = wife;
}

}

Wife受控方

package org.wpf.entity;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;

import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;

@Entity(name = "t_wife")
public class Wife implements Serializable {
private static final long serialVersionUID = -6685649713801290134L;

@Id
@GenericGenerator(name = "ff1", strategy = "foreign", parameters = {
@Parameter(name = "property", value = "husband") })
@GeneratedValue(generator = "ff1")
private Long id;

@Column(length = 32)
private String name;

@OneToOne(orphanRemoval = true)
@PrimaryKeyJoinColumn
private Husband husband;

public Wife() {
super();
}

public Wife(Long id, String name, Husband husband) {
super();
this.id = id;
this.name = name;
this.husband = husband;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Husband getHusband() {
return husband;
}

public void setHusband(Husband husband) {
this.husband = husband;
}

}
@GenericGenerator(name = "foreignKey"

生成器名称,供GeneratedValue中进行调用

strategy = "foreign"    使用hibernate的外键策略

parameters = @Parameter(value = "article参数值",name = "property参数名称"))//指定成员属性中的article所在类的主键为本类的主键,这里的参数属性name必须为"property"

@GeneratedValue(generator = "foreignKey")//使用上述定义的id生成器

11.唯一外键的关联实现方式

a.xml(bean和上面的一样,省略)

Husband.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 2018-1-22 22:47:11 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="org.wpf.entity.Husband" table="HUSBAND">
<id name="id" type="java.lang.Long">
<column name="ID" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" length="20" not-null="true" />
</property>
<one-to-one name="wife" class="org.wpf.entity.Wife"
cascade="all" property-ref="husband" />
</class>
</hibernate-mapping>


Wife.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 2018-1-22 22:47:11 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="org.wpf.entity.Wife" table="WIFE">
<id name="id" type="java.lang.Long">
<column name="ID" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" length="20" not-null="true" />
</property>
<many-to-one name="husband" class="org.wpf.entity.Husband"
unique="true" column="husband_id" />
</class>
</hibernate-mapping>


b.注解

Person

package org.wpf.entity;

import java.io.Serializable;

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.OneToOne;

@Entity(name = "t1_person")
public class Person implements Serializable {
private static final long serialVersionUID = -6446631496216328660L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(length = 32)
private String name;

@OneToOne(mappedBy = "person", cascade = CascadeType.ALL)
private Card card;

public Person() {
super();
}

public Person(Long id, String name, Card card) {
super();
this.id = id;
this.name = name;
this.card = card;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Card getCard() {
return card;
}

public void setCard(Card card) {
this.card = card;
}

}

Card

package org.wpf.entity;

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.JoinColumn;
import javax.persistence.OneToOne;

@Entity(name = "t1_person")
public class Card implements Serializable {
private static final long serialVersionUID = -5345063387498725762L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(length = 32)
private String name;

@OneToOne(optional = false)
@JoinColumn(name = "person_id")
private Person person;

public Card() {
super();
}

public Card(Long id, String name, Person person) {
super();
this.id = id;
this.name = name;
this.person = person;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Person getPerson() {
return person;
}

public void setPerson(Person person) {
this.person = person;
}

}


12.多对多关联

在关系型数据库中是不能直接表达多对多关联,必须引入一个中间表

注意中间表表中不能包含非键列。中间表没有对应的映射文件



Student

package org.wpf.entity;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

public class Student implements Serializable {
private static final long serialVersionUID = 7767264496828265124L;
private Long id;
private String name;
private Set courses = new HashSet(0);

public Student() {
super();
}

public Student(Long id, String name, Set courses) {
super();
this.id = id;
this.name = name;
this.courses = courses;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Set getCourses() {
return courses;
}

public void setCourses(Set courses) {
this.courses = courses;
}

}

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.wpf.entity.Student" table="t_student">
<id name="id" type="java.lang.Long">
<column name="ID" />
<generator class="identity" />
</id>
<property name="name" type="java.lang.String">
<column name="Name" length="20" not-null="true" />
</property>
<set name="courses" table="t_choice" cascade="all">
<key>
<column name="Student_id" not-null="true" />
</key>
<many-to-many entity-name="org.wpf.entity.Course">
<column name="Course_id" not-null="true" />
</many-to-many>
</set>
</class>
</hibernate-mapping>

Course

package org.wpf.entity;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

public class Course implements Serializable {
private static final long serialVersionUID = -2850799906496654565L;
private Long id;
private String title;
private Set students = new HashSet(0);

public Course() {
super();
}

public Course(Long id, String title, Set students) {
super();
this.id = id;
this.title = title;
this.students = students;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public Set getStudents() {
return students;
}

public void setStudents(Set students) {
this.students = students;
}

}

Course.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 2018-1-22 23:00:29 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="org.wpf.entity.Course" table="t_course">
<id name="id" type="java.lang.Long">
<column name="ID" />
<generator class="native" />
</id>
<property name="title" type="java.lang.String">
<column name="TITLE" length="50" not-null="true" />
</property>
<set name="students" inverse="true" table="t_choice">
<key>
<column name="Course_id" not-null="true" />
</key>
<many-to-many entity-name="org.wpf.entity.Student">
<column name="Student_id" not-null="true" />
</many-to-many>
</set>
</class>
</hibernate-mapping>
控制台信息
Hibernate:

create table t_choice (
Course_id bigint not null,
Student_id bigint not null,
primary key (Student_id, Course_id)
) engine=InnoDB
Hibernate:

create table t_course (
ID bigint not null auto_increment,
TITLE varchar(50) not null,
primary key (ID)
) engine=InnoDB
Hibernate:

create table t_student (
ID bigint not null auto_increment,
Name varchar(20) not null,
primary key (ID)
) engine=InnoDB
Hibernate:

alter table t_choice
add constraint FK93ey2xm8fobois7ev90lrrefd
foreign key (Student_id)
references t_student (ID)
Hibernate:

alter table t_choice
add constraint FKjd0jtvxffqm4e7yi50ed1frju
foreign key (Course_id)
references t_course (ID)查看数据库



13.Hibernate注解规范的文档中提供了三种方法

将组件类注解为@Embeddable,并将组件的属性注解为@Id

public class UserRole implements Serializable {
@EmbeddedId  private UserRolePK pk;
}

将组件的属性注解为@ EmbeddedId
@Embeddable
public class UserId implements Serializable {
@Id
UserId uid;
}将类注解为@IdClass,并将该实体中所有主键属性注解为@Id,最常用的方法
需要根据所有的主键属性,建立一个主键类

主键类必须实现序列化接口(Serializable)

主键类必须有默认的public无参数的构造方法

主键类必须覆盖equals和hashCode方法
@IdClass(IPMapKey.class)
public class IPMap {
@Id @Column(name="IP")
private String ip;
@Id @Column(name="ExamPlaceId")
private String examPlaceId;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hibernate 注解 映射
相关文章推荐