(7)onetomany双向:CURD

来源:互联网 发布:win10usb端口上的电涌 编辑:程序博客网 时间:2024/06/04 18:15

一、Save
Group类

@Entity@Table(name="_Group")//对表重命名(group是关键字,不能作为表名,所以要对其重命名)public class Group {    private int id;    private String name;    private Set<User> user=new HashSet<User>();    /*     * 选set的理由:一个组中含有多个用户,它是不同的用户组成的集合。list与数组很像,可以有重复数据。     * map需要个key,这里不用指定。set元素不能重复,也没key最合适     */    @Id    @GeneratedValue    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    @OneToMany(mappedBy="group")    public Set<User> getUser() {        return user;    }    public void setUser(Set<User> user) {        this.user = user;    }}

User类

@Entity @Table(name="_User")//对表重命名public class User {    private int id;    private String name;    private Group group;    @Id //必须加在getId上面    @GeneratedValue    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    @ManyToOne    public Group getGroup() {        return group;    }    public void setGroup(Group group) {        this.group = group;    }   }

在保存时需要注意的是:要将两侧的关联在类层次设好。并且哪些是应该先存储的,哪些是应该后存储的,比如在该例子中一个组中有多个用户,在用户端有外键,则必须先将组先存储,再存储与该组有关的用户。即要将两侧的基本属性和关联属性(集合或者类对象)设置好

@org.junit.Test    public void GroupSave() {        User u=new User();        u.setName("u1");        User u2=new User();        u2.setName("u2");        Group g=new Group();        g.setName("g1");        g.getUser().add(u);        g.getUser().add(u2);        u.setGroup(g);//存user必须知道所属的组        u2.setGroup(g);        Session session=sf.getCurrentSession();        session.beginTransaction();        session.save(g);        session.save(u);        session.save(u2);        session.getTransaction().commit();    }   

二、Read

/*     * cascade.all影响的是cud,不管r.     * fetch:负责读取     *fetch一般情况,取默认的方式即可。一对多设lazy 多对一设eager     */    @org.junit.Test    public void UserGet() {        GroupSave();        Session session=sf.getCurrentSession();        session.beginTransaction();        User u=(User) session.get(User.class, 1);//manyToOne默认(无论有无cascade={CascadeType.ALL})会把1方取出,也符合常理:取出一个用户,知道他是哪组、组的名称等信息        System.out.println(u.getGroup().getName());        session.getTransaction().commit();        //System.out.println(u.getGroup().getName());//在默认状态,因为get已经获取到了1端的数据,所以写在外面或者写在里面都可以。    }       @org.junit.Test    public void GroupGet() {        GroupSave();        Session session=sf.getCurrentSession();        session.beginTransaction();        Group g=(Group) session.get(Group.class, 1);//默认不会将用户信息取出,若要取出,在@OneToMany(mappedBy="group",cascade={CascadeType.ALL},fetch=FetchType.EAGER)        /*         * 当fetch=FetchType.LAZY时,不会获取多端的数据。         * 此时,什么时候获取多端的数据?当调用多端的方法时,才会select         */        System.out.println(g.getUser().size());//这句话在fetch=FetchType.LAZY状态时,不能写在session外,因为没有session不能select到        session.getTransaction().commit();    }

三、Update
update:一定是先get到对象,然后对该对象进行操作。该对象会放入缓存中,当对其set时,会检测set的是否和之前信息相同,若相同,则不更新。若不同,则更新。比如在这个例子中user参考group,那么当user类中有group类对象,对其设置新属性也会触发update。无论是否有级联操作。

    @org.junit.Test//user表和group表均会做更新,    public void UserUpdate() {        UserSave();        Session session=sf.getCurrentSession();        session.beginTransaction();        User u=(User) session.get(User.class, 1);        u.setName("oo");        u.getGroup().setName("ll");        session.getTransaction().commit();    }

四、Delete(特别注意)
若要删除的类对象中类没有级联操作,则不会影响其他的表。若有级联操作会影响其他的表。解决方法,①将其对应的级联关系字段设为空,如UserDelete1()。
②用HQL无论有无级联,都不会影响其他的表。(这也是在级联中比较好的解决方式)

@org.junit.Test    /*     * 对于双向关联中删除,需要注意     * 在本例中,要删除id=1的用户,因为user(cascade={CascadeType.ALL}),所以它会把group对应的id删掉。     * 若要删除group表中对应的id对应记录,group表cascade={CascadeType.ALL},会先把user表的外键是它的记录删掉,     * 在本例中,相当于删除了group和user中的所有记录。     * 这是在编程过程中不允许的。【原意是只删除一条记录】     */    public void UserDelete() {        UserSave();        Session session=sf.getCurrentSession();        session.beginTransaction();        User u=(User) session.get(User.class, 1);        session.delete(u);        session.getTransaction().commit();    }    @org.junit.Test    /*     * 解决上述问题的方法一:打破这种外键的关系。删除多端。     *      */    public void UserDelete1() {        UserSave();        Session session=sf.getCurrentSession();        session.beginTransaction();        User u=(User) session.get(User.class, 1);        u.setGroup(null);//这样,使得这条user记录与group没有关系        session.delete(u);        session.getTransaction().commit();    }    @org.junit.Test    /*     * 解决上述问题的方法二:使用hql。删除多端。     *      */    public void UserDelete2() {        UserSave();        Session session=sf.getCurrentSession();        session.beginTransaction();        session.createQuery("delete from User u where u.id=1").executeUpdate();        session.getTransaction().commit();    }    //删除1端,也会级联操作。多数情况这也是需要级联操作的,所以不必做更多的操作。
原创粉丝点击