hibernate 关联关系CRUD

网上一篇CRUD写的挺好的,借鉴一下其中的内容。
在我自己写的时候junit报异常信息,org.hibernate.exception.SQLGrammarException: could not insert: [错误] 仔细检查了一下发现MySql关键字冲突。表名和列名不能是MySql关键字,把group类指定一个表名即可,就像下文原作者这样指定@Table(name=”t_Group”)//指定一个表名
一:Group和Users两个类
1、Users和Group的关联关系:User对Group是@Many-To-One,Group对Users是@One-To-Many
2.CRUD时候,希望是能从具体用户Users查到其对应的Group,反过来也能通过Group查到具体Users,所以是双向关联(这里还是要记得用mappedBy去除冗余)

@Entity
@Table(name="t_Group")//指定一个表名
public class Group 
{
    private int id;
    private String name;
    private Set<Users> users = new HashSet<Users>();

    @Id
    @GeneratedValue//主键用自增序列
    public int getId() {
        return id;
    }
    @OneToMany(mappedBy="group",cascade=(CascadeType.ALL))//以“多”一方为主导管理,级联用ALL
    public Set<Users> getUsers() {
        return users;
    }


@Entity
@Table(name="t_Users")
public class Users 
{
    private int id;
    private String name;
    private Group group;

    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }
    @ManyToOne(fetch=FetchType.LAZY,cascade=(CascadeType.ALL))//解决1+N,级联用ALL
    @JoinColumn(name="groupId")//指定外键名称,不指定的默认值是group_Id
    public Group getGroup() {
        return group;
    }

二:C增

cascade:级联,只影响cud,不影响r

(all全都级联,persist存储时级联,remove删除时级联)

如果没有设置cascade,默认需要save(Group)和save(users),两个都要存,设置级联之后,只存一个就行了

级联依赖于这句:@ManyToOne(cascade=(CascadeType.ALL))//需要依赖于其他的东西时候
设置好正反向之后,多个有级联关系的对象就一起被保存了

@Test
    public void testC() {   
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();

        Users u1 = new Users();
        Users u2 = new Users();
        u1.setName("u1");
        u2.setName("u2");

        Group g = new Group();
        g.setName("g1");

        g.getUsers().add(u1);//正向
        g.getUsers().add(u2);

        u1.setGroup(g);//反向
        u2.setGroup(g);//不然u1和u2中的group信息为空
        //因为设置级联,所以存储g时候也把u1和u2存上了。下面删除的时候
        不能直接删除Users也是级联的原因。
        session.save(g);
        /*不设置级联的话,还要存储u1和u2
        session.save(u1);
        session.save(u2);
        */

        session.getTransaction().commit();
        HibernateUtil.getSessionFactory().close();         
    }

三:R查

默认会这样处理(平时常用的思路也是这样):

1.取“多”的时候,把“一”取出来
2.取“一”时,不取“多”的,用到时候再去取(看user信息时候一般看组名,看group时候user信息太多不必看)

fetch管读取,cascade管增删改
@OneToMany(mappedBy=”group”,cascade=(CascadeType.ALL),fetch=FetchType.EAGER)
@OneToMany默认的是LAZY,@ManyToOne默认是EAGER

User u = (User)s.get(User.class,1);
//取user时候,把group也取出来,

    Users u = (Users)session.get(Users.class,11);//取id为11号的u
    //hibernate产生的语句里也把group拿出来了:group1_.id as id0_0_,和group1_.name as name0_0_ 

Hibernate:
select
users0_.id as id1_1_,
users0_.groupId as groupId1_1_,
users0_.name as name1_1_,
group1_.id as id0_0_,
group1_.name as name0_0_
from
t_Users users0_
left outer join
t_Group group1_
on users0_.groupId=group1_.id
where
users0_.id=?

只取出Group的话,不会去查询里边的user

    //只取出Group的话,不会去查询里边的user
    Group group = (Group)session.get(Group.class,1);

Hibernate:
select
group0_.id as id0_0_,
group0_.name as name0_0_
from
t_Group group0_
where
group0_.id=?

*如果闲的蛋疼想查user里面的数据:在Group 中把Fetchtype类型设为EAGER.

    @OneToMany(mappedBy="group",
     cascade={CascadeType.ALL},
     fetch=FetchType.EAGER
    )
    public Set<Users> getUsers() {
        return users;
    }

Hibernate:
select
group0_.id as id0_1_,
group0_.name as name0_1_,
users1_.group_id as group3_3_,
users1_.id as id3_,
users1_.id as id1_0_,
users1_.group_id as group3_1_0_,
users1_.name as name1_0_
from
t_Group group0_
left outer join
Users users1_
on group0_.id=users1_.group_id
where
group0_.id=?

四:U更新
注意:fetch影响两者读取顺序(两边都设成EAGER要多取出一次).

@OneToMany,@ManyToOne都写cascade=(CascadeType.ALL)
update时候自动关联更新

   //因为cascade=(CascadeType.ALL),所以自动关联更新  
   Users u = (Users)session.load(Users.class,1);//取id为1.  
   u.setName("aaa");  
   u.getGroup().setName("group1");  

不能直接s.delete(u),因为u和group有级联,group和所有users都有级联,
原因就是设置了 cascade={CascadeType.ALL}

    @Test
    public void saveLoaddelete(){   
  Configuration con= new AnnotationConfiguration();
    SessionFactory sf=con.configure().buildSessionFactory();
    Session session=sf.getCurrentSession();
    session.beginTransaction();
     //第一种删除方法。
       String sql="delete from Users u where u.id=2";
       Query query=session.createQuery(sql);

    query.executeUpdate();

    session.getTransaction().commit(); 
    sf.close();

    }

第二种删除方法:

Users u=(Users)session.load(Users.class, 1);
u.setName(“uuuuuu”);
u.setGroup(null);//俩表脱离关联,删除的时候就不会都删掉了。
session.delete(u);

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值