Hibernate继承注解
hibernate应用中,继承的用途或目的主要有两点:
- 组件化:故明思义,把重复性的代码抽取成组件,以便重用和维护。hibernate应用中,一些重复的字段,重复的映射配置,就需要抽取成组件。
- 多态性:类的多态性是指下层业务所需一个父类对象,而上层业务根据所需的父类对象,传递一个子类对象。hibernate应用中,下层业务操作父类对象进行持久操作,如增删改查,上层业务则传递一个子类对象。
所以,在应用hibernate的继承时,需要明确设计所需,即究竟是组件化需求,还是多态性需求。
- @MappedSuperclass:组件化需求的继承注解。虽然它可以应用于类的多态性业务中,但它不能应用于hibernate持久操作的多态性业务中。
- @Inheritance:多态性需求的继承注解。虽然它可以达到组件化的目的,但它要比@MappedSuperclass多负出一些代价。
@MappedSuperclass定义:
@Documented
@Target({TYPE})
@Retention(RUNTIME)
public @interface MappedSuperclass {
}
@Inheritance定义:
@Target({TYPE})
@Retention(RUNTIME)
public @interface Inheritance {
InheritanceType strategy() default SINGLE_TABLE;
}
InheritanceType定义:
public enum InheritanceType {
SINGLE_TABLE,
TABLE_PER_CLASS,
JOINED
}
从定义看出,@Inheritance的默认继承策略为SINGLE_TABLE,三种继承策略的区别在于:
- SINGLE_TABLE:公共属性公共表,独立属性公共表。
需要使用监别器区分具体的子类,注解@DiscriminatorColumn设置监别器列,注解@DiscriminatorValue设置监别器值。
子类的属性映射配置时,需要设置为允许为空或默认值。 - JOINED:公共属性公共表,独立属性独立表。
子类的独立表生成后,其主键是一个共享主键,意味着这是一对一的关联,默认名称与父类的主键一致,使用注解@PrimaryKeyJoinColumn可改变名称。 - TABLE_PER_CLASS:公共属性独立表,独立属性独立表。
主键生成策略不能使用GenerationType.IDENTITY。
对于子类而言,公共属性就是父类的属性,公共表就是父类对应的表,而独立属性就是自己定义的属性,独立表就是自己对应的表。
示例1:继承注解@MappedSuperclass
User.java
@MappedSuperclass
public class User<ID extends Serializable> {
//---------------------------------------------------------------
// Field
//--------------------------------------------------------------- @Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private ID id; @Column(name = "loginName",
length = 20,
unique = true,
nullable = false,
updatable = false)
private String loginName; @Column(name = "loginPass",
length = 20,
nullable = false)
private String loginPass; //---------------------------------------------------------------
// Method
//--------------------------------------------------------------- public ID getId() {
return id;
} public void setId(ID id) {
this.id = id;
} public String getLoginName() {
return loginName;
} public void setLoginName(String loginName) {
this.loginName = loginName;
} public String getLoginPass() {
return loginPass;
} public void setLoginPass(String loginPass) {
this.loginPass = loginPass;
}
}
Admin.java
@Entity
@Table
public class Admin extends User<Integer> {
@Column(name = "role", length = 20, nullable = false)
private String role; public String getRole() {
return role;
} public void setRole(String role) {
this.role = role;
}
}
Member.java
@Entity
@Table
public class Member extends User<Long> {
@Column(name = "name", length = 20, nullable = false)
private String name; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}
test.java
public class Test {
public static void main(String[] params){
// 继承注解:@MappedSuperclass
new Test().test();
/*
Hibernate:
drop table if exists Admin
Hibernate:
drop table if exists Member
Hibernate:
create table Admin (
id integer not null auto_increment,
loginName varchar(20) not null,
loginPass varchar(20) not null,
role varchar(20) not null,
primary key (id)
)
Hibernate:
create table Member (
id bigint not null auto_increment,
loginName varchar(20) not null,
loginPass varchar(20) not null,
name varchar(20) not null,
primary key (id)
)
Hibernate:
alter table Admin
add constraint UK_bdsh7mq6s6xad6ohm08u18uxr unique (loginName)
Hibernate:
alter table Member
add constraint UK_jxtse8o1c6l89j39lilw5e2rs unique (loginName)
Hibernate:
insert
into
Admin
(loginName, loginPass, role)
values
(?, ?, ?)
Hibernate:
select
last_insert_id()
Hibernate:
drop table if exists Admin
Hibernate:
drop table if exists Member
*/
}
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml", this.getClass());
SessionFactory factory = null;
boolean success = true;
Session session = null;
try {
factory = (SessionFactory) context.getBean("sessionFactory");
session = factory.openSession();
success = false;
session.beginTransaction();
User<?> user = new Admin();
user.setLoginName("loginName");
user.setLoginPass("loginPass");
((Admin)user).setRole("role");
session.save(user);
session.getTransaction().commit();
success = true;
} finally {
if(session != null){
if(!success)
session.getTransaction().rollback();
session.close();
session = null;
}
if(factory != null){
factory.close();
factory = null;
}
}
}
}
示例2:继承注解@Inheritance,继承策略InheritanceType.SINGLE_TABLE。
User.java
@Entity
@Table
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
name = "type",
discriminatorType = DiscriminatorType.STRING,
length = 30)
@DiscriminatorValue("User")
public class User {
//---------------------------------------------------------------
// Field
//--------------------------------------------------------------- @Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; @Column(name = "loginName",
length = 20,
unique = true,
nullable = false,
updatable = false)
private String loginName; @Column(name = "loginPass",
length = 20,
nullable = false)
private String loginPass; //---------------------------------------------------------------
// Method
//--------------------------------------------------------------- public Long getId() {
return id;
} public void setId(Long id) {
this.id = id;
} public String getLoginName() {
return loginName;
} public void setLoginName(String loginName) {
this.loginName = loginName;
} public String getLoginPass() {
return loginPass;
} public void setLoginPass(String loginPass) {
this.loginPass = loginPass;
}
}
Admin.java
@Entity
@DiscriminatorValue("Admin")
public class Admin extends User {
// 需要允许为空或设置默认值
@Column(name = "role", length = 20, nullable = true)
private String role; public String getRole() {
return role;
} public void setRole(String role) {
this.role = role;
}
}
Member.java
@Entity
@DiscriminatorValue("Member")
public class Member extends User {
// 需要允许为空或设置默认值
@Column(name = "name", length = 20, nullable = false, columnDefinition="VARCHAR(20) DEFAULT 'admin'")
private String name; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}
Test.java
public class Test {
public static void main(String[] params){
// 继承注解:@Inheritance
// 继承策略:InheritanceType.SINGLE_TABLE
// 公共属性公共表,独立属性公共表
new Test().test();
/*
Hibernate:
drop table if exists User
Hibernate:
create table User (
type varchar(30) not null,
id bigint not null auto_increment,
loginName varchar(20) not null,
loginPass varchar(20) not null,
role VARCHAR(20) DEFAULT 'member' not null,
name VARCHAR(20) DEFAULT 'admin' not null,
primary key (id)
)
Hibernate:
alter table User
add constraint UK_5iebj9qwxsnoshbaq6w834t0y unique (loginName)
Hibernate:
insert
into
User
(loginName, loginPass, role, type)
values
(?, ?, ?, 'Admin')
Hibernate:
select
last_insert_id()
Hibernate:
select
user0_.id as id2_0_0_,
user0_.loginName as loginNam3_0_0_,
user0_.loginPass as loginPas4_0_0_,
user0_.role as role5_0_0_,
user0_.name as name6_0_0_,
user0_.type as type1_0_0_
from
User user0_
where
user0_.id=?
多态性读取成功:study.t2.Admin@dc3aae
Hibernate:
drop table if exists User
*/
}
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml", this.getClass());
SessionFactory factory = null;
try {
factory = (SessionFactory) context.getBean("sessionFactory");
// 多态性添加
boolean success = true;
Session session = null;
Long id = null;
try {
session = factory.openSession();
success = false;
session.beginTransaction();
User user = new Admin();
user.setLoginName("loginName");
user.setLoginPass("loginPass");
((Admin)user).setRole("role");
session.save(user);
session.getTransaction().commit();
id = user.getId();
success = true;
} finally {
if(session != null){
if(!success)
session.getTransaction().rollback();
session.close();
session = null;
}
}
// 多态性读取
if(success){
try {
session = factory.openSession();
session.beginTransaction();
success = false;
User user = session.load(User.class, id);
System.out.println("多态性读取成功:" + user);
session.getTransaction().commit();
success = true;
} finally {
if(session != null){
if(!success)
session.getTransaction().rollback();
session.close();
session = null;
}
}
}
} finally {
if(factory != null){
factory.close();
factory = null;
}
}
}
}
示例3:继承注解@Inheritance,继承策略InheritanceType.JOINED。
User.java
@Entity
@Table
@Inheritance(strategy = InheritanceType.JOINED)
public class User { //---------------------------------------------------------------
// Field
//---------------------------------------------------------------
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; @Column(name = "loginName",
length = 20,
unique = true,
nullable = false,
updatable = false)
private String loginName; @Column(name = "loginPass",
length = 20,
nullable = false)
private String loginPass; //---------------------------------------------------------------
// Method
//--------------------------------------------------------------- public Long getId() {
return id;
} public void setId(Long id) {
this.id = id;
} public String getLoginName() {
return loginName;
} public void setLoginName(String loginName) {
this.loginName = loginName;
} public String getLoginPass() {
return loginPass;
} public void setLoginPass(String loginPass) {
this.loginPass = loginPass;
}
}
Admin.java
@Entity
@Table
// 可选,设置共享主键的名称,默认的主键名称与父类一致。
@PrimaryKeyJoinColumn(name = "userId")
public class Admin extends User {
@Column(name = "role", length = 20, nullable = false)
private String role; public String getRole() {
return role;
} public void setRole(String role) {
this.role = role;
}
}
Member.java
@Entity
@Table
// 可选,设置共享主键的名称,默认的主键名称与父类一致。
@PrimaryKeyJoinColumn(name = "userId")
public class Member extends User {
@Column(name = "name", length = 20, nullable = false)
private String name; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}
Test.java
public class Test {
public static void main(String[] params){
// 继承注解:@Inheritance
// 继承策略:InheritanceType.JOINED
// 公共属性公共表,独立属性独立表
new Test().test();
/*
Hibernate:
alter table Admin
drop
foreign key FKjoav33p64suikub3369fpajy4
注:这里可能报一个异常,因为表Admin不存在!
Hibernate:
alter table Member
drop
foreign key FKnj6wlxlj0cc3993su1qaykn42
注:这里可能报一个异常,因为表Member不存在!
Hibernate:
drop table if exists Admin
Hibernate:
drop table if exists Member
Hibernate:
drop table if exists User
Hibernate:
create table Admin (
role varchar(20) not null,
userId bigint not null,
primary key (userId)
)
Hibernate:
create table Member (
name varchar(20) not null,
userId bigint not null,
primary key (userId)
)
Hibernate:
create table User (
id bigint not null auto_increment,
loginName varchar(20) not null,
loginPass varchar(20) not null,
primary key (id)
)
Hibernate:
alter table User
add constraint UK_5iebj9qwxsnoshbaq6w834t0y unique (loginName)
Hibernate:
alter table Admin
add constraint FKjoav33p64suikub3369fpajy4
foreign key (userId)
references User (id)
Hibernate:
alter table Member
add constraint FKnj6wlxlj0cc3993su1qaykn42
foreign key (userId)
references User (id)
Hibernate:
insert
into
User
(loginName, loginPass)
values
(?, ?)
Hibernate:
select
last_insert_id()
Hibernate:
insert
into
Admin
(role, userId)
values
(?, ?)
Hibernate:
select
user0_.id as id1_2_0_,
user0_.loginName as loginNam2_2_0_,
user0_.loginPass as loginPas3_2_0_,
user0_1_.role as role1_0_0_,
user0_2_.name as name1_1_0_,
case
when user0_1_.userId is not null then 1
when user0_2_.userId is not null then 2
when user0_.id is not null then 0
end as clazz_0_
from
User user0_
left outer join
Admin user0_1_
on user0_.id=user0_1_.userId
left outer join
Member user0_2_
on user0_.id=user0_2_.userId
where
user0_.id=?
多态性读取成功:study.t3.Admin@1f9407e
Hibernate:
alter table Admin
drop
foreign key FKjoav33p64suikub3369fpajy4
Hibernate:
alter table Member
drop
foreign key FKnj6wlxlj0cc3993su1qaykn42
Hibernate:
drop table if exists Admin
Hibernate:
drop table if exists Member
Hibernate:
drop table if exists User
*/
}
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml", this.getClass());
SessionFactory factory = null;
try {
factory = (SessionFactory) context.getBean("sessionFactory");
// 多态性添加
boolean success = true;
Session session = null;
Long id = null;
try {
session = factory.openSession();
success = false;
session.beginTransaction();
User user = new Admin();
user.setLoginName("loginName");
user.setLoginPass("loginPass");
((Admin)user).setRole("role");
session.save(user);
session.getTransaction().commit();
id = user.getId();
success = true;
} finally {
if(session != null){
if(!success)
session.getTransaction().rollback();
session.close();
session = null;
}
}
// 多态性读取
if(success){
try {
session = factory.openSession();
session.beginTransaction();
success = false;
User user = session.load(User.class, id);
System.out.println("多态性读取成功:" + user);
session.getTransaction().commit();
success = true;
} finally {
if(session != null){
if(!success)
session.getTransaction().rollback();
session.close();
session = null;
}
}
}
} finally {
if(factory != null){
factory.close();
factory = null;
}
}
}
}
示例4:继承注解@Inheritance,继承策略InheritanceType.TABLE_PER_CLASS。
User.java
@Entity
@Table
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class User {
//---------------------------------------------------------------
// Field
//--------------------------------------------------------------- @Id
@Column(name = "id")
// 不能使用 GenerationType.IDENTITY,可以使用AUTO,或其它。
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="genId")
@TableGenerator(
name = "genId",
table="GeneratorId",
pkColumnName="genName",
valueColumnName="genValue",
pkColumnValue="nextUserId",
allocationSize=1
)
private Long id; @Column(name = "loginName",
length = 20,
unique = true,
nullable = false,
updatable = false)
private String loginName; @Column(name = "loginPass",
length = 20,
nullable = false)
private String loginPass; //---------------------------------------------------------------
// Method
//--------------------------------------------------------------- public Long getId() {
return id;
} public void setId(Long id) {
this.id = id;
} public String getLoginName() {
return loginName;
} public void setLoginName(String loginName) {
this.loginName = loginName;
} public String getLoginPass() {
return loginPass;
} public void setLoginPass(String loginPass) {
this.loginPass = loginPass;
}
}
Admin.java
@Entity
@Table
public class Admin extends User {
@Column(name = "role", length = 20, nullable = false)
private String role; public String getRole() {
return role;
} public void setRole(String role) {
this.role = role;
}
}
Member.java
@Entity
@Table
public class Member extends User {
@Column(name = "name", length = 20, nullable = false)
private String name; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}
Test.java
public class Test {
public static void main(String[] params){
// 继承注解:@Inheritance
// 继承策略:InheritanceType.TABLE_PER_CLASS
// 公共属性独立表,独立属性独立表
new Test().test();
/*
Hibernate:
drop table if exists Admin
Hibernate:
drop table if exists GeneratorId
Hibernate:
drop table if exists Member
Hibernate:
drop table if exists User
Hibernate:
create table Admin (
id bigint not null,
loginName varchar(20) not null,
loginPass varchar(20) not null,
role varchar(20) not null,
primary key (id)
)
Hibernate:
create table GeneratorId (
genName varchar(255) not null,
genValue bigint,
primary key (genName)
)
Hibernate:
create table Member (
id bigint not null,
loginName varchar(20) not null,
loginPass varchar(20) not null,
name varchar(20) not null,
primary key (id)
)
Hibernate:
create table User (
id bigint not null,
loginName varchar(20) not null,
loginPass varchar(20) not null,
primary key (id)
)
Hibernate:
alter table Admin
add constraint UK_bdsh7mq6s6xad6ohm08u18uxr unique (loginName)
Hibernate:
alter table Member
add constraint UK_jxtse8o1c6l89j39lilw5e2rs unique (loginName)
Hibernate:
alter table User
add constraint UK_5iebj9qwxsnoshbaq6w834t0y unique (loginName)
Hibernate:
select
tbl.genValue
from
GeneratorId tbl
where
tbl.genName=? for update
Hibernate:
insert
into
GeneratorId
(genName, genValue)
values
(?,?)
Hibernate:
update
GeneratorId
set
genValue=?
where
genValue=?
and genName=?
Hibernate:
insert
into
Admin
(loginName, loginPass, role, id)
values
(?, ?, ?, ?)
Hibernate:
select
user0_.id as id1_2_0_,
user0_.loginName as loginNam2_2_0_,
user0_.loginPass as loginPas3_2_0_,
user0_.role as role1_0_0_,
user0_.name as name1_1_0_,
user0_.clazz_ as clazz_0_
from
( select
id,
loginName,
loginPass,
null as role,
null as name,
0 as clazz_
from
User
union
select
id,
loginName,
loginPass,
role,
null as name,
1 as clazz_
from
Admin
union
select
id,
loginName,
loginPass,
null as role,
name,
2 as clazz_
from
Member
) user0_
where
user0_.id=?
多态性读取成功:study.t4.Admin@12bf0e2
Hibernate:
drop table if exists Admin
Hibernate:
drop table if exists GeneratorId
Hibernate:
drop table if exists Member
Hibernate:
drop table if exists User
*/
}
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml", this.getClass());
SessionFactory factory = null;
try {
factory = (SessionFactory) context.getBean("sessionFactory");
// 多态性添加
boolean success = true;
Session session = null;
Long id = null;
try {
session = factory.openSession();
success = false;
session.beginTransaction();
User user = new Admin();
user.setLoginName("loginName");
user.setLoginPass("loginPass");
((Admin)user).setRole("role");
session.save(user);
session.getTransaction().commit();
id = user.getId();
success = true;
} finally {
if(session != null){
if(!success)
session.getTransaction().rollback();
session.close();
session = null;
}
}
// 多态性读取
if(success){
try {
session = factory.openSession();
session.beginTransaction();
success = false;
User user = session.load(User.class, id);
System.out.println("多态性读取成功:" + user);
session.getTransaction().commit();
success = true;
} finally {
if(session != null){
if(!success)
session.getTransaction().rollback();
session.close();
session = null;
}
}
}
} finally {
if(factory != null){
factory.close();
factory = null;
}
}
}
}
Hibernate继承注解的更多相关文章
- Java、Hibernate(JPA)注解大全
1.@Entity(name=”EntityName”) 必须,name为可选,对应数据库中一的个表 2.@Table(name=””,catalog=””,schema=””) 可选,通常和@Ent ...
- 转Hibernate继承
hibernate继承映射 以下测试是在mysql中进行的. 1.单表方式 Animal.java @Entity @Inheritance(strategy=InheritanceType.SING ...
- hibernate annotation注解方式来处理映射关系
在hibernate中,通常配置对象关系映射关系有两种,一种是基于xml的方式,另一种是基于annotation的注解方式,熟话说,萝卜青菜,可有所爱,每个人都有自己喜欢的配置方式,我在试了这两种方式 ...
- 批量产生ssh2项目中hibernate带注解的pojo类的快捷方法
近几个月一直在忙于项目组的ios应用项目的开发,没有太多时间去研究web应用方面的问题了.刚好,昨天有网友问到如何批量产生hibernate带注解的pojo类的快捷方法,所谓批量就是指将当前数据库中所 ...
- Hibernate Annotations 注解
Hibernate Annotations 注解 对于org.hibernate.annotations与org.hibernate.persistence,它的注释比如Columns,可是不知道怎么 ...
- Hibernate中用注解配置一对多双向关联和多对一单向关联
Hibernate中用注解配置一对多双向关联和多对一单向关联 Hibernate提供了Hibernate Annotations扩展包,使用注解完成映射.在Hibernate3.3之前,需单独下载注解 ...
- Hibernate基于注解annotation的配置
Annotation在框架中是越来越受欢迎了,因为annotation的配置比起XML的配置来说方便了很多,不需要大量的XML来书写,方便简单了很多,只要几个annotation的配置,就可以完成我们 ...
- 【JavaEE】Hibernate继承映射,不用多态查询只查父表的方法
几个月前,我在博问里面发了一个问题:http://q.cnblogs.com/q/64900/,但是一直没有找到好的答案,关闭问题以后才自己解决了,在这里分享一下. 首先我重复一下场景,博问里面举的动 ...
- Hibernate基于注解方式配置来实现实体和数据库之间存在某种映射关系
实体和数据库之间存在某种映射关系,hibernate根据这种映射关系完成数据的存取.在程序中这种映射关系由映射文件(*.hbm.xml)或者java注解(@)定义. 本文以java注解的形式总结映射关 ...
随机推荐
- MME、PGW、SGW和PCRF的介绍
1.简介原文连接:https://blog.csdn.net/Rong_Toa/article/details/94983607 用户面和控制面板分离2.什么是HSS?HSS有什么主要功能?HSS与H ...
- Spring事物管理机制简单学习
首先spring并不直接管理事物,而是提供了多种事物管理器,他们将事务管理的职责委托给Hibernate或者JTA等持久化机制所提供的相关平台框架的事务来实现. Spring管理事物的接口是org.s ...
- Django框架中session存储到redis中的配置
本文链接:https://blog.csdn.net/linqunbin/article/details/94786313————————————————版权声明:本文为CSDN博主「linqunbi ...
- java ajax长连接请求服务器数据
Servlet 3.0笔记之异步请求Comet推送长轮询(long polling)篇 Comet另一种形式为长轮询(long polling),客户端会与服务器建立一个持久的连接,直到服务器端有数据 ...
- android中实现监听的四种方法
(1)自身类作为事件监听器 package cn.edu.gdmec.s07150745.work5; import android.support.v7.app.AppCompatActivity; ...
- jQuery.event.move
http://stephband.info/jquery.event.move/ Move events movestart Fired following touchmove or mousemov ...
- signed main()
主函数由int main()改成signed main() 好处:把int改成long long 的时候不用单独把它改成int了,懂的人都懂(滑稽
- jQuery实现contains方法不区分大小写的方法教程
jQuery.expr[':'].Contains = function(a, i, m){ return jQuery(a).text().toUpperCase() .indexOf(m[3].t ...
- Vim操作 -- 按列
1, 拷贝行 Y y 拷贝当前光标字符 如果需要拷贝整个单词,可以用 ye,e表示跳到词尾 2, 粘贴 P(大写) 粘贴到光标前 p(小写)粘贴到光标后 3, 进入快操作模式 ctrl+q 4, 用 ...
- Eureka服务治理学习笔记(摘抄)
1.简介 EureKa在Spring Cloud全家桶中担任着服务的注册与发现的落地实现.Netflix在设计EureKa时遵循着AP原则,它基于R EST的服务,用于定位服务,以实现云端中间层服务发 ...