• 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;
                }
            }
        }
    }
  • 相关阅读:
    taotao订单系统
    使用JMeter进行一次简单的带json数据的post请求测试
    taotao购物车2 解决购物车本地cookie和服务器redis不同步的问题
    Dubbo入门介绍---搭建一个最简单的Demo框架
    关于地图模糊
    二维纹理 Texture 2D
    TexturePacker
    Unity3D实现3D立体游戏原理及过程,需偏振眼镜3D显
    解决RegexKitLite编译报错
    QualitySettings 3d模型质量显示设置
  • 原文地址:https://www.cnblogs.com/hvicen/p/6337871.html
Copyright © 2020-2023  润新知