这个是自己总结的hibernate东西,这只是笔记而已,后期要把真实的代码贴出来以及整合。

———————————-一对多单向关联关系:unidirectional association————————————————————————–

 

下面的代码都省略了开启事务,提交事务,关闭session的动作;

 

@Test

public void savePerson_cascadeAccount() {

Person person = new Person();

person.setName("小明");

Account account = new Account();

account.setAccountNum("xyz1101");

account.setMoney(100);

// 构造集合将personaccount建立类之间的关联;

Set accounts = new HashSet();

accounts.add(account);

person.setAccounts(accounts);

// 保存person;

session.save(person);

}

sql语句: 这里有五条sql语句;

1 选出person  id的最大值

2 选出account id的最大值;

3 插入person

4 插入account;

5 更新account的外键;

 

@Test

public void savePerson_cascadeUpdateAccount(){

Person person=new Person();

person.setName("小华");

//先查出账号来,在设置到person中去

Account account = (Account) session.get(Account.class, 1L);

Set accounts = new HashSet();

accounts.add(account);

//建立person和账号之间的关系;

person.setAccounts(accounts);

//保存person;

session.save(person);

}

这里有四条sql语句;

分别是:

1:select * from account where aid=1;

2:查出person 最大id

3 插入person

4 更新account的外键;

如果上面增加一行更新account的代码比如account.setMoney(100);

那么还将多一条语句;

    update

Account 

    set

accountNum=?,

money=? 

    where

aid=?

这是因为session对于每个持久化对象都有一个副本(拷贝),如果副本和当前持久化对象一致,

当事务提交的时候将不会发出update语句;

这样做的好处在于减少和数据库的交互,提高了效率;

 

@Test

public void updatePerson_cascadeSaveAccount(){

Person person=(Person) session.get(Person.class, 1L);—查出id1person;

//person.setName("");

Account account=new Account();

account.setAccountNum("wolegequ");

account.setMoney(100000);

person.getAccounts().add(account);//先查出当前person对应的所有account

//然后查出当前account表中id的最大值,

加一后插入到account表中

最后更新account表的外键,pid;

}

上面的语句中如果把person.setName("xiaohua");的注释去掉;

那么还会有更新person的语句,但是第二次什么都不动,再执行一次该操作;

将不在更新name;这是因为副本中的name值和你设的是一样的,他还是认为你是相同的没有变过;

 

@Test

public void updatePerson_cascadeUpdateAccount(){

Person person=(Person) session.get(Person.class, 1L);

person.setName("wanggang");

Account account = (Account) session.get(Account.class, 1L);

account.setAccountNum("wohahahahah");

person.getAccounts().add(account);

}

sql语句:

查询id1 person;

查询id1account;

根据personid查询所有pid为其idaccount;

更新personname属性

更新accountNum;

由于这里不涉及到关系的解除只是自己更新自己的

 

 

@Test//cascade属性为delete或者save-update均可,sql语句相同;

public void deletePerson_cascadeDeleteAccount(){

//要删除先得找到两个东东;

Person person=(Person) session.get(Person.class, 1L);

Account account = (Account) session.get(Account.class, 1L);

//通过person删除account;

person.getAccounts().remove(account);

session.delete(person);

}

sql语句

先查找到id1person

再查找到id1account

在根据personpid查找account表中外键等于personpidaccount;

解除personaccount的关系,updateaccountid=null;

删除person;

———————————-一对多双向关联关系:Bidirectional association—————————————————————–

       

@Test

public void savePerson_cascadeSaveAccountByMany(){

//创建person 创建account;通过account维护两者之间 的关系;

Person person=new Person();

person.setName("wujie");

Account account=new Account();

account.setAccountNum("xxxooo");

account.setPerson(person);

session.save(account);

}

1 首先查account的最大id

2 其次查person的最大id

3 然后插入person

4 最后插入account;

由于外键处于account表中因此无需单独更新外键的值,在根系account的表的时候,

一起跟着更新了,这就是为什么多的一方负责关系的维护效率更高;

前提:多的一方中cascade="save-update";这里就是account.hbm.xml映射文件中要有这么个东东

inverse是放在set标签中的;

—–如果一的一方进行操作,会多更新外键这一sql语句,因此效率没有多的一方维护那么高;

 

@Test

public void savePerson_cascadeUpdateAccountByMany(){

//创建person 查找account;通过account维护两者之间 的关系;

Person person=new Person();

person.setName("wxx");

Account account=(Account) session.get(Account.class, 1L);

account.setAccountNum("xxxppp");//这里要有一条语句;

account.setPerson(person);

}

sql语句:

1 查询account表中的id1的记录;

2 查询person表中的id最大值

3 id最大值自增一后insert person

4 更新account,包括普通字段,和外键;

四条语句,效率高;

 

@Test

public void savePerson_cascadeUpdateAccountByOne(){

Person person=new Person();

person.setName("zxx");

Account account=(Account) session.get(Account.class, 1L);

account.setAccountNum("xxxppplll");//这里要有一条语句;

Set accounts=new HashSet();

accounts.add(account);

person.setAccounts(accounts);

session.save(person);

}

比上面多了一条语句;

将更新accountNum和外键分成了两个语句执行;因此;效率低;

    delete:save-update的区别:

    delete只要设置了级联操作的属性集cascade=delete(关系维护端的映射文件);

    然后session.delete(关系维护端);

    即可;

    如果是save-update要达到级联删除的效果,

    先解除两者之间关系,然后在分别删除即可;差点给弄进去了;

   

@Test

public void deletePerson_cascadeByDeleteAccountByMany2(){

Session session = HibernateUtils.getSession();

Transaction transaction = session.beginTransaction();

//先查出来在说;

Account account=(Account) session.get(Account.class, 1L);

Person person=(Person) session.get(Person.class, 1L);

session.delete(person);

//account.setPerson(null);—-这里注释了,得到了下面的sql语句

transaction.commit();

session.close();

}

    Hibernate: 

    select

        account0_.aid as aid3_0_,

        account0_.accountNum as accountNum3_0_,

        account0_.money as money3_0_,

        account0_.pid as pid3_0_ 

    from

        Account account0_ 

    where

        account0_.aid=?

Hibernate: 

    select

        person0_.pid as pid4_0_,

        person0_.name as name4_0_ 

    from

        Person person0_ 

    where

        person0_.pid=?

Hibernate: 

    update

        Account 

    set

        pid=null 

    where

        pid=?

        ——————–这个sql语句表明,在删除的时候会自动解除两者之间的关系;

Hibernate: 

    delete 

    from

        Person 

    where

        pid=?

———————-多对多双向关联关系——————————————————————-

 

@Test

public void saveStudent_cascadeSaveTeacher() {

Session session = HibernateUtils.getSession();

Transaction transaction = session.beginTransaction();

Student student=new Student();

Teacher teacher=new Teacher();

teacher.setName("栋哥");

Set teachers=new HashSet();

teachers.add(teacher);

student.setTeachers(teachers);

//保存学生,级联保存学生

session.save(student);

transaction.commit();

session.close();

}

五条sql语句:

1 查询student表的id最大值

2 查询teacher表的id最大值

3 插入记录到学生表;

4 插入记录到教师表;

5 插入sid,tid到中间表;

两种方式都可以级联更新;