zoukankan      html  css  js  c++  java
  • Hibernate基于注解annotation的配置

    Annotation在框架中是越来越受欢迎了,因为annotation的配置比起XML的配置来说方便了很多,不需要大量的XML来书写,方便简单了很多,只要几个annotation的配置,就可以完成我们以前需要书写的大量的XML文件。当然annotation的配置也有缺陷的,那就是annotation一般都是配置在代码中的,如果要修改的话,需要动源代码,丧失了灵活性,违背了OCP(增加开放,修改关闭)原则,但是在真实的项目开发中,我们只是动配置文件,而不修改源代码的情况实在是太少见了,所以现在annotation已经被广泛的运用到了编程中,各种框架都提供了基于annotation的配置。

    hibernate的注解配置和Jpa中的注解使用基本上都差不多。

    参考博客:

    https://blog.csdn.net/ervinbao/article/details/52861000

    https://www.cnblogs.com/liangxinxinbo/p/6092664.html

    http://www.ilt.me/dmfx/89.html

     

    导入jar包:

    还有mysql的驱动

    ----------------------

    简单的插入测试小案例:

    实体:User

    package org.model;
    
    import java.util.Date;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.Table;
    
    import org.hibernate.annotations.GenericGenerator;
    
    @Entity
    // @Table(name="t_user")//表名 默认不写的话 就是类名
    public class User {
        private int id;
        private String username;
        private String password;
        private String nickname;
        private Date bornDate;
    
        public User() {
        }
    
        public User(int id, String username, String password, String nickname, Date bornDate) {
            super();
            this.id = id;
            this.username = username;
            this.password = password;
            this.nickname = nickname;
            this.bornDate = bornDate;
        }
    
        public User(String username, String password, String nickname, Date bornDate) {
            super();
            this.username = username;
            this.password = password;
            this.nickname = nickname;
            this.bornDate = bornDate;
        }
    
        @Id
        @GeneratedValue()//默认native @GeneratedValue()
        //@GeneratedValue(generator = "x") //  使用uuid id的类型必须是String类型
        //@GenericGenerator(name = "x", strategy = "uuid") // 使用hibernate的uuid策略
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        @Column(length = 5, nullable = false)
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        @Column(length = 10, nullable = false)//nullable属性:默认是true  允许空值
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        @Column(length = 5, nullable = true)
        public String getNickname() {
            return nickname;
        }
    
        public void setNickname(String nickname) {
            this.nickname = nickname;
        }
    
        @Column(name = "born_date")
        public Date getBornDate() {
            return bornDate;
        }
    
        public void setBornDate(Date bornDate) {
            this.bornDate = bornDate;
        }
    
        @Override
        public String toString() {
            return "User [id=" + id + ", username=" + username + ", password=" + password + ", nickname=" + nickname
                    + ", bornDate=" + bornDate + "]";
        }
    
    }

    测试类:

    package org.execute;
    
    import java.util.Date;
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    import org.junit.Test;
    import org.model.User;
    
    public class Exe {
        static Configuration config = null;
        static SessionFactory sessionFactory = null;
    
        // 初始化
        static {
            // 加载核心配置文件 默认加载类路径下的hibernate.cfg.xml
            config = new Configuration();
            config.configure();
            // 创建工厂
            sessionFactory = config.buildSessionFactory();
        }
    
        // 返回session
        public Session rtn() {
            return sessionFactory.openSession();
        }
    
        // 保存测试
        @Test
        public void insert() {
            Session session = rtn();
            session.getTransaction().begin();
            User u = new User("laomu", "123", "老孙", new Date());
            session.save(u);
            session.getTransaction().commit();
        }
    
    }

    我们发现在对实体进行注解配置的时候  导入的包和JPA配置时一样

    在测试类中进行插入时,使用的不是JPA中的EntityManager对象,

    EntityManagerFactory factory=Persistence.createEntityManagerFactory("simple");
    EntityManager em = factory.createEntityManager();

    而还是hibernate中的session对象。

    配置文件:类路径下的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="dialect">
                org.hibernate.dialect.MySQLDialect
            </property>
            <property name="hibernate.hbm2ddl.auto">update</property>
                <!--控制台打印sql语句-->
            <property name="connection.url">
                jdbc:mysql://localhost:3308/annotationhibernate
            </property>
            <property name="connection.username">root</property>
            <property name="connection.password">jay571018</property>
            <property name="connection.driver_class">
                com.mysql.jdbc.Driver
            </property>
        
            <property name="show_sql">true</property>
            <!--     
            <mapping resource="org/model/Course.hbm.xml" />
            <mapping resource="org/model/Student.hbm.xml" /> 
            -->
            
            <mapping class="org.model.User"/>
        </session-factory>
    
    </hibernate-configuration>
    View Code

    下面观察数据库:

    插入的数据:

    -------------------------------------------------

    annotation配置many-to-one双向

    先看有问题的代码:(明明配置了级联  但是却没有进行级联保存的问题)

    多方:Student

    package org.model;
    
    import javax.persistence.CascadeType;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.ManyToOne;
    import javax.persistence.Table;
    
    //多方  由该方维护外键
    @Entity
    @Table(name = "t_student")
    public class Student {
        private int id;
        private String name;
        private String stuNo;
        // 一方的属性
        private ClassRoom room;
    
        @Id
        @GeneratedValue()
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        @Column(length = 5, nullable = false)
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Column(length = 10, nullable = false)
        public String getStuNo() {
            return stuNo;
        }
    
        public void setStuNo(String stuNo) {
            this.stuNo = stuNo;
        }
    
        // optional=false 外键字段不能为空 即每个学生都必须有对应的班级 默认为true
        // ManyToOne 查询student 默认使用即时加载
        @ManyToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH })
        // 在维护端 指定外键字段名 也可以不写 默认属性_id
        @JoinColumn(name = "r_id")
        public ClassRoom getRoom() {
            return room;
        }
    
        public void setRoom(ClassRoom room) {
            this.room = room;
        }
    
        public Student() {
        }
    
        // 互相关联的方法
        public Student(String name, String stuNo) {
            this.name = name;
            this.stuNo = stuNo;
        }
    
        @Override
        public String toString() {
            return "Student [id=" + id + ", name=" + name + ", stuNo=" + stuNo + ", classRoom=" + room.toString() + "]";
        }
    
    }

    一方:ClassRoom

    package org.model;
    
    import java.util.HashSet;
    import java.util.Set;
    
    import javax.persistence.CascadeType;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.OneToMany;
    import javax.persistence.Table;
    
    //一方  被维护端
    @Entity
    @Table(name = "t_classroom")
    public class ClassRoom {
        private int id;
        private String name;
        // 多方的集合属性
        private Set<Student> students = new HashSet<Student>();
    
        @Id
        @GeneratedValue()
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        @Column(length = 10, nullable = false)
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        // mappedBy属性:由集合中对应的实体Student中的classroom属性来维护外键 声明mappedBy的实体为被维护方
        // 抓取方式 onetoMany 默认为lazy加载
        @OneToMany(cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH }, mappedBy = "room")
        public Set<Student> getStudents() {
            return students;
        }
    
        public void setStudents(Set<Student> students) {
            this.students = students;
        }
    
        public ClassRoom(String name) {
            this.name = name;
        }
        
        public ClassRoom() {}
        /*
         * public ClassRoom(int id,String name) { this.id=id; this.name = name; }
         */
    
        
        // 互相关联的方法
        public void addStudent(Student student) {
            student.setRoom(this);
            this.students.add(student);
        }
    
        @Override
        public String toString() {
            return "ClassRoom [id=" + id + ", name=" + name + "]";
        }
    
    }

    测试类:

        //一对多插入测试
        @Test
        public void oneToManyInsert() {
            Session session=rtn();
            session.getTransaction().begin();
            //创建对象
            Student s1=new Student("乔克","A01010");
            Student s2=new Student("小明","A01012");
            ClassRoom classRoom=new ClassRoom("就业班");
            //进行互相关联
            classRoom.addStudent(s1);
            classRoom.addStudent(s2);//在addStudent()中进行了互相关联   这里直接调用这个方法即完成了互相关联
            //进行持久化操作
            session.save(classRoom);
            session.getTransaction().commit();
        }

    然后查看数据库:

    可以看到  只对classRoom表进行了数据的插入   可以我们在实体中明明配置了级联保存的操作啊   同时也进行了互相的关联  为啥会出现这种情况呢?

    还记得学习JPA时级联操作触发的时机吗?----》如果使用javax.persistence.*里面的注解,只有调用相应的方法才生效,如PERSIST,只有调用persist方法才生效

    所以这里当然不能实现级联了

    https://blog.csdn.net/l1028386804/article/details/17686229

    https://blog.csdn.net/z69183787/article/details/22327725

     第一种测试:

    根据网上说的情况  我了试试  如果把ClassRoom中的级联属性配置为以下的情况:

    CascadeType.PESIST,CascadeType.REMOVE,CascadeType.MERGE,CascadeType.REFRESH

    也不能进行级联保存,但是,如果配置为CascadeType.All则可以级联保存成功,说明

    JPA中的CascadeType.ALL并不等于{CascadeType.PESIST,CascadeType.REMOVE,CascadeType.MERGE,CascadeType.REFRESH}

     第二种测试:

    然后我把级联属性设置成了上面说的那种方式save_update   注意  导入的是hibernate.annotation中的包  而不再是jpa中的级联包了

     roomClass中的级联方式修改为:

     

    测试结果:

    级联保存成功,所以这里需要明白,hibernate注解开发 设置级联时不能使用jpa规范中的级联方式,而只能是使用自己提供的级联方式,如下:

    ---------------------------------------

    上面进行了插入测试,下面我们进行查询测试:

    可见只查询了一次数据库,在查询student对象(多方)  立即查询一方数据

    因为我们在student中是这样配置的

    抓取方式  在ManyToOne情况下  默认直接加载了一方属性  如果改为下面的配置方式:

    执行查询  观察打印的sql

    可以看到  是发送了两次sql查询  同样  在执行查询一方属性时  不指定查询方式时   默认是懒加载多方属性的  这里就不再执行了

    需要注意的一点是:在查询某个实体的时候  需要在该实体中配置一个无参数的构造方法    比如  我把student实体中的无参构造删除掉  然后执行查询

    所以  因为框架中好多地方都会用到无参构造  在我们创建有参构造的时候  记得把无参构造也写出来。

    ---------------------------------------------------------------

    annotation配置many-to-one单向

    student

    package org.model.om.danxiang;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.ManyToOne;
    import javax.persistence.Table;
    
    @Entity
    @Table(name = "danxiang_student")
    public class Student {
        private int id;
        private String name;
        private String stuNo;
        // 一方的属性
        private ClassRoom room;
    
        @Id
        @GeneratedValue()
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        @Column(length = 5, nullable = false)
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Column(length = 10, nullable = false)
        public String getStuNo() {
            return stuNo;
        }
    
        public void setStuNo(String stuNo) {
            this.stuNo = stuNo;
        }
    
        // optional=false 外键字段不能为空 即每个学生都必须有对应的班级 默认为true
        // ManyToOne 查询student 默认使用即时加载
        //使用hibernate自己的级联方式
        @ManyToOne()
        //@Cascade({CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REFRESH})
        // 在维护端 指定外键字段名 也可以不写 默认属性_id
        @JoinColumn(name = "cid")
        public ClassRoom getRoom() {
            return room;
        }
    
        public void setRoom(ClassRoom classRoom) {
            this.room = classRoom;
        }
        
        public Student() {
        }
    
        // 互相关联的方法
        public Student(String name, String stuNo) {
            this.name = name;
            this.stuNo = stuNo;
        }
    
        @Override
        public String toString() {
            return "Student [id=" + id + ", name=" + name + ", stuNo=" + stuNo + ", classRoom=" + room.toString() + "]";
        }
    
    }

    classRoom

    package org.model.om.danxiang;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.Table;
    
    //一方  被维护端
    @Entity
    @Table(name = "danxiang_classroom")
    public class ClassRoom {
        private int id;
        private String name;
        /*
        // 多方的集合属性
        private Set<Student> students = new HashSet<Student>();*/
    
        @Id
        @GeneratedValue()
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        @Column(length = 10, nullable = false)
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
        /*
        // mappedBy属性:由集合中对应的实体Student中的classroom属性来维护外键 声明mappedBy的实体为被维护方
        // 抓取方式 onetoMany 默认为lazy加载
        //使用hibernate自己的级联方式
        @OneToMany(mappedBy = "room")
        @Cascade({CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REFRESH})
        public Set<Student> getStudents() {
            return students;
        }
    
        public void setStudents(Set<Student> students) {
            this.students = students;
        }*/
    
        public ClassRoom(String name) {
            this.name = name;
        }
        
        public ClassRoom() {}
        /*
         * public ClassRoom(int id,String name) { this.id=id; this.name = name; }
         */
    
        /*
        // 互相关联的方法
        public void addStudent(Student student) {
            student.setRoom(this);
            this.students.add(student);
        }*/
    
        @Override
        public String toString() {
            return "ClassRoom [id=" + id + ", name=" + name + "]";
        }
    
    }

    测试:

        //单向  一方classroom中不创建集合   只在多方student中创建一方对象 ---》 测试成功
        //所以  单向方式操作时  只能是:在多方对象中创建一方对象属性   在一方中省略创建多方的集合属性    反之则不行  比如测试2
        @Test
        public void oneToManyInsertDanXiang() {
            Session session=rtn();
            session.getTransaction().begin();
            //创建对象
            org.model.om.danxiang.Student s1=new org.model.om.danxiang.Student("乔克","A01010");
            org.model.om.danxiang.Student s2=new org.model.om.danxiang.Student("乔克2","A01012");
            
            org.model.om.danxiang.ClassRoom classRoom=new org.model.om.danxiang.ClassRoom("就业班");
            //进行互相关联
            s1.setRoom(classRoom);
            s2.setRoom(classRoom);
            //保存
            session.save(classRoom);//保存的顺序无关
            session.save(s1);
            session.save(s2);
            
            //classRoom.addStudent(s1);
            //classRoom.addStudent(s2);//在addStudent()中进行了互相关联   这里直接调用这个方法即完成了互相关联
            //进行持久化操作
            session.save(classRoom);
            session.getTransaction().commit();
        }

    查询测试:

        //单向查询
        @Test
        public void oneToManyInsertDanXiangQuery() {
            Session session=rtn();
            //查询多方   观察是否同时查询一方数据
            org.model.om.danxiang.Student student = session.get(org.model.om.danxiang.Student.class,67);
            System.out.println(student);
        }

    单向关系,查询多方的时候,可以顺带查询一方的数据   但是不能通过查询一方同时获得多方的数据   但是双向关系就可以  查询ClassRoom时  可以选择即使加载或者懒加载多方属性   然后通过ClassRoom中的students属性就可以得到多方集合数据

    -----------------------------------------------

    openSession和getCurrentSession的区别:

    使用getCurrentSession时  出现下面错误  是因为没有开启事务

    开启事务  就可以解决该问题

    ---------------------------------------------------

     annotation配置many-to-one双向

    Person

    package org.model;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.OneToOne;
    import javax.persistence.Table;
    import org.hibernate.annotations.Cascade;
    import org.hibernate.annotations.CascadeType;
    
    //一对一双向实体  person作为维护方
    @Entity
    @Table(name = "t_person")
    public class Person {
        private int id;// 主键
        private String name;// 姓名
        private IDCard idCard;
    
        @Id
        @GeneratedValue
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        // 这里暂时不配置 数据库默认字段为name 可以为空 长度255
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @OneToOne
        @JoinColumn(name = "cardid")
        @Cascade(value = { CascadeType.ALL })
        public IDCard getIdCard() {
            return idCard;
        }
    
        public void setIdCard(IDCard idCard) {
            this.idCard = idCard;
        }
    
        @Override
        public String toString() {
            return "Person [id=" + id + ", name=" + name + ", idCard=" + idCard + "]";
        }
    
    }

    IDCard

    package org.model;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.OneToOne;
    import javax.persistence.Table;
    import org.hibernate.annotations.Cascade;
    import org.hibernate.annotations.CascadeType;
    
    //一对一双向实体
    @Entity
    @Table(name = "t_card")
    public class IDCard {
        private int id;// 主键
        private String no;// 编号
        private Person person;
    
        @Id
        @GeneratedValue
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getNo() {
            return no;
        }
    
        public void setNo(String no) {
            this.no = no;
        }
    
        @OneToOne(mappedBy = "idCard")
        @Cascade(value = { CascadeType.ALL })
        public Person getPerson() {
            return person;
        }
    
        public void setPerson(Person person) {
            this.person = person;
        }
    
        @Override
        public String toString() {
            return "IDCard [id=" + id + ", no=" + no + ", person=" + person + "]";
        }
    
    }

    测试

    //一对一双向关联
        @Test
        public void oneToOne() {
            Session session=rtn();
            session.getTransaction().begin();
            //创建person对象
            Person p=new Person();
            p.setName("张三");
            //创建IDCard对象
            IDCard idCard=new IDCard();
            idCard.setNo("xx1");
            //进行相互关联
            /**
             * 如果没有配置级联保存的话  那么需要相互关联  并且还要分别保存
            p.setIdCard(idCard);
            idCard.setPerson(p);
            session.save(idCard);
            session.save(p);
            */
            //配置级联之后 
            p.setIdCard(idCard);
            session.save(p);
            session.getTransaction().commit();
            session.close();
        }

    数据库:

    -------------------------------------

    annotation配置many-to-many

    user

    package org.model.mm.shuangxiang;
    
    import java.util.Date;
    import java.util.Set;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.ManyToMany;
    import javax.persistence.Table;
    import javax.persistence.Temporal;
    import javax.persistence.TemporalType;
    import org.hibernate.annotations.Cascade;
    import org.hibernate.annotations.CascadeType;
    @Entity
    @Table(name="mm_user")
    //规定该实体为外键维护方
    public class User {
        private int id;
        private String username;
        private String password;
        private String nickname;
        private Date bornDate;
        private Set<Role> roles;
        @Id
        @GeneratedValue
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        @Column(length=10,nullable=false)
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        @Column(length=10,nullable=false)
        public String getPassword() {
            return password;
        }
        public void setPassword(String password) {
            this.password = password;
        }
        @Column(length=10,nullable=false)
        public String getNickname() {
            return nickname;
        }
        public void setNickname(String nickname) {
            this.nickname = nickname;
        }
        @Temporal(TemporalType.TIMESTAMP)//日期 时间 yyyy-dd-mm HH:MM:SS
        public Date getBornDate() {
            return bornDate;
        }
        public void setBornDate(Date bornDate) {
            this.bornDate = bornDate;
        }
        //以m打头   默认加载方式为lazy
        @ManyToMany()
        @Cascade(value= {CascadeType.ALL})
        /**
        @JoinTable(
        name="u_r",//中间表名称
        joinColumns=@JoinColumn(name="uid"),//本实体在中间表中创建的字段名
        inverseJoinColumns= @JoinColumn(name="rid"))//关联实体在中间表中创建的字段名 
        //以上内容可以省略不写  有默认值
        */
        public Set<Role> getRoles() {
            return roles;
        }
        public void setRoles(Set<Role> roles) {
            this.roles = roles;
        }
        public User(String username, String password, String nickname, Date bornDate) {
            super();
            this.username = username;
            this.password = password;
            this.nickname = nickname;
            this.bornDate = bornDate;
        }
        public User() {}
        
    }

    role

    package org.model.mm.shuangxiang;
    
    import java.util.Set;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.ManyToMany;
    import javax.persistence.Table;
    import org.hibernate.annotations.Cascade;
    import org.hibernate.annotations.CascadeType;
    
    @Entity
    @Table(name = "mm_role")
    public class Role {
        private int id;
        private String name;
        private Set<User> users;
        @Id
        @GeneratedValue
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
        @Column(length=10,nullable=false)
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
        @ManyToMany(mappedBy="roles")
        @Cascade(value= {CascadeType.ALL})
        public Set<User> getUsers() {
            return users;
        }
    
        public void setUsers(Set<User> users) {
            this.users = users;
        }
    
        @Override
        public String toString() {
            return "Role [id=" + id + ", name=" + name + ", users=" + users + "]";
        }
    
        public Role(String name) {
            super();
            this.name = name;
        }
        public Role() {}
        
    
    }

    测试:

    //多对多不拆分
        @Test
        public void manyToMany() {
            Session session=rtn();
            session.getTransaction().begin();
            //创建user对象
            org.model.mm.shuangxiang.User user1=new org.model.mm.shuangxiang.User("zhang","123","小张",new Date());
            //org.model.mm.shuangxiang.User user2=new org.model.mm.shuangxiang.User("wang","123","小王",new Date());
            //org.model.mm.shuangxiang.User user3=new org.model.mm.shuangxiang.User("sun","123","小孙",new Date());
        
            //创建role对象
            Role role1=new Role("总监");
            Role role2=new Role("保安");
            Role role3=new Role("菜鸟");
            //创建集合
            Set<Role> roles=new HashSet<Role>();
            roles.add(role1);
            roles.add(role2);
            roles.add(role3);
            //进行关联  
            user1.setRoles(roles);
            //保存user对象
            session.save(user1);
            session.getTransaction().commit();
            session.close();
        }

    数据库:

     

    -----------------------------------------

     annotation配置many-to-many变种  拆分为两个一对多

    Student

    package org.model.mm.shuangxiang2;
    
    import java.util.Set;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.OneToMany;
    import javax.persistence.Table;
    import org.hibernate.annotations.Cascade;
    import org.hibernate.annotations.CascadeType;
    
    @Entity
    @Table(name = "mm_student")
    public class Student {
        private int id;
        private String name;
        private String stuNo;
        private Set<StudentCourse> tcs;
    
        @Id
        @GeneratedValue
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        @Column(length = 10, nullable = false)
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Column(length = 10, nullable = false)
        public String getStuNo() {
            return stuNo;
        }
    
        public void setStuNo(String stuNo) {
            this.stuNo = stuNo;
        }
    
        // 与中间表相比 是一方 被维护端
        @OneToMany(mappedBy = "student")
        @Cascade(value = { CascadeType.ALL })
        public Set<StudentCourse> getTcs() {
            return tcs;
        }
    
        public void setTcs(Set<StudentCourse> tcs) {
            this.tcs = tcs;
        }
    
        public Student() {
        }
    
        public Student(String name, String stuNo) {
            this.name = name;
            this.stuNo = stuNo;
        }
    }

    Course

    package org.model.mm.shuangxiang2;
    
    import java.util.Set;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.OneToMany;
    import javax.persistence.Table;
    import org.hibernate.annotations.Cascade;
    import org.hibernate.annotations.CascadeType;
    
    @Entity
    @Table(name = "mm_course")
    public class Course {
        private int id;
        private String name;
        private Set<StudentCourse> tcs;
    
        @Id
        @GeneratedValue
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        @Column(length = 10, nullable = false)
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        // 是一方 被维护端
        @OneToMany(mappedBy = "course")
        @Cascade(value = { CascadeType.ALL })
        public Set<StudentCourse> getTcs() {
            return tcs;
        }
    
        public void setTcs(Set<StudentCourse> tcs) {
            this.tcs = tcs;
        }
    
        public Course() {
        }
    
        public Course(String name) {
            this.name = name;
        }
    
    }

    中间实体  StudentCourse

    package org.model.mm.shuangxiang2;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.ManyToOne;
    import javax.persistence.Table;
    import org.hibernate.annotations.Cascade;
    import org.hibernate.annotations.CascadeType;
    
    @Entity
    @Table(name = "mm_SC") // 指定中间表名称
    public class StudentCourse {
        private int id;
        private double score;
        private Student student;
        private Course course;
    
        @Id
        @GeneratedValue
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        @Column(length = 5, nullable = false)
        public double getScore() {
            return score;
        }
    
        public void setScore(double score) {
            this.score = score;
        }
    
        // 多方维护外键 指定中间表外键名称为student_ID
        @ManyToOne()
        @Cascade(value = { CascadeType.ALL })
        @JoinColumn(name = "student_ID")
        public Student getStudent() {
            return student;
        }
    
        public void setStudent(Student student) {
            this.student = student;
        }
    
        // 多方维护外键 指定中间表外键名称为course_ID
        @ManyToOne()
        @Cascade(value = { CascadeType.ALL })
        @JoinColumn(name = "course_ID") // 多方作为维护端
        public Course getCourse() {
            return course;
        }
    
        public void setCourse(Course course) {
            this.course = course;
        }
    
        public StudentCourse(double score, Student student, Course course) {
            super();
            this.score = score;
            this.student = student;
            this.course = course;
        }
    
        public StudentCourse() {
        }
    
    }

    配置文件中引入:

    测试:

    //多对多  拆分为两个一对多
        @Test
        public void manyToMany2() {
            Session session=rtn();
            session.getTransaction().begin();
            //创建2个student对象
            org.model.mm.shuangxiang2.Student student1=new org.model.mm.shuangxiang2.Student("zhang","141164000");
            org.model.mm.shuangxiang2.Student student2=new org.model.mm.shuangxiang2.Student("wang","141164888");
            //创建2个course对象
            Course course1=new Course("java");
            Course course2=new Course("php");
            //创建studentCourse对象  把创建的student course加入进去
            //学生1的两门课成绩
            StudentCourse sc1=new StudentCourse(88.5,student1,course1);
            StudentCourse sc2=new StudentCourse(99.5,student1,course2);
            //学生2的两门课成绩
            StudentCourse sc3=new StudentCourse(66.5,student2,course1);
            StudentCourse sc4=new StudentCourse(49.5,student2,course2);
            //保存维护端对象  studentcourse
            session.save(sc1);
            session.save(sc2);
            session.save(sc3);
            session.save(sc4);
            session.getTransaction().commit();
            session.close();
        }

    数据库:

    -------------------------------------

  • 相关阅读:
    Python 面向对象 —— super 的使用(Python 2.x vs Python 3.x)
    安全移除驱动器、弹出、卸载的差别及详细查看设备的运行前后的异同
    java中不常见的keyword:strictfp,transient
    textarea文本域宽度和高度(width、height)自己主动适应变化处理
    Android 输入框弹出样式
    .net下载优酷1080P视频
    Oracle Hints具体解释
    关于成本核算方法、步骤、成本分析的简单回复
    程序猿接私活经验总结,来自csdn论坛语录
    Android getResources的作用和须要注意点
  • 原文地址:https://www.cnblogs.com/Joke-Jay/p/8920504.html
Copyright © 2011-2022 走看看