突然感觉接触到了流币的知识,完全不懂。数据库方面的很多东西以前都没接触过。等今年开课在认真学一遍吧,暂时按照教程把我学到的东西整理下。
第一节 一对多映射列表(XML)
对于没有系统学习过数据库的我而言一开始并不明白这是什么意思。教程给的例子使用的联系人,感觉还是很好理解的。一个客户可以拥有多个用户,客户就是一联系人就是多,即一对多。
- 创建用户实体类 Customer.java
package cn.lkangle.entity;
import java.util.HashSet;
import java.util.Set;
public class Customer {
private Integer cid;
private String name;
private String attr;
// 将联系人保存于set集合中
private Set linkMans = new HashSet();
...
}
- 创建联系人实体类 LinkMan.java
package cn.lkangle.entity;
public class LinkMan {
private Integer lid;
private String name;
private String tel;
// 用于保存所属客户
private Customer customer;
...
}
- XML映射配置文件
客户的set标签与联系人的many-to-one标签是配置一对多的关键,其中的cascade属性设置级联操作。
级联具有方向性,在客户中添加只有在对客户进行操作时才会产生级联,在联系人中添加只有对联系人进行操作时才产生级联
cascade属性取值:
- update-save 在更新和保存时进行级联
- delete 在删除时进行级联
- all 任何操作都进行级联
- 一对多级联的CRUD操作
package cn.lkangle.threeday;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import cn.lkangle.entity.Customer;
import cn.lkangle.entity.LinkMan;
import cn.lkangle.util.HbmUtil;
public class OnetoManyTest {
/**
* 双重级联效果 配置文件中客户和联系人都要设置级联属性 只是试试
*/
@Test
public void testSave2() {
Session session = null;
Transaction tx = null;
try {
session = HbmUtil.getSession();
System.out.println(session);
tx = session.beginTransaction();
Customer customer = new Customer();
customer.setName("客户一");
customer.setAttr("北京");
LinkMan linkMan = new LinkMan();
linkMan.setName("联系人一");
linkMan.setTel("3333333333");
LinkMan linkMan2= new LinkMan();
linkMan2.setName("联系人二");
linkMan2.setTel("865432222");
customer.getLinkMans().add(linkMan);
customer.getLinkMans().add(linkMan2);
linkMan.setCustomer(customer);
linkMan2.setCustomer(customer);
session.save(linkMan);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
}
}
/**
* 级联查询操作
*/
@Test
public void testSelect() {
Session session = null;
Transaction tx = null;
try {
session = HbmUtil.getSession();
System.out.println(session);
tx = session.beginTransaction();
// Customer customer = session.get(Customer.class, 9);
// System.out.println(customer);
// Set linkMans = customer.getLinkMans();
// for (LinkMan linkMan : linkMans) {
// System.err.println(linkMan);
// }
LinkMan linkMan = session.get(LinkMan.class, 2);
System.out.println(linkMan);
System.out.println(linkMan.getCustomer());
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
}
}
/**
* 级联删除
*/
@Test
public void testDelete() {
Session session = null;
Transaction tx = null;
try {
session = HbmUtil.getSession();
System.out.println(session);
tx = session.beginTransaction();
// LinkMan linkMan = session.get(LinkMan.class, 6);
// session.delete(linkMan);
Customer customer = session.get(Customer.class, 6);
session.delete(customer);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
}
}
/**
* 级联修改 直接操作实体类就可以
*/
@Test
public void testUpdate() {
Session session = null;
Transaction tx = null;
try {
session = HbmUtil.getSession();
System.out.println(session);
tx = session.beginTransaction();
/**
* 在这里如果设置了双向级联修改时会出现对外键进行两次修改,这是双向维护外键导致的,这样的效率就不高
* 推荐在客户中设置inverse="true"让其放弃对外键的维护,解决修改时会修改两次外键
*/
Customer customer = session.get(Customer.class, 9);
LinkMan linkMan = session.get(LinkMan.class, 2);
LinkMan linkMan2 = session.get(LinkMan.class, 7);
// 因为放弃了客户对外键的维护 这里要更新联系人
linkMan.setCustomer(customer);
linkMan2.setCustomer(customer);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
}
}
/**
* 级联保存
*/
@Test
public void testSave() {
Session session = null;
Transaction tx = null;
try {
session = HbmUtil.getSession();
System.out.println(session);
tx = session.beginTransaction();
Customer customer = new Customer();
customer.setName("客户一");
customer.setAttr("地址");
LinkMan linkMan = new LinkMan();
linkMan.setName("联系人一");
linkMan.setTel("55555555");
LinkMan linkMan2= new LinkMan();
linkMan2.setName("联系人二");
linkMan2.setTel("9999999999");
customer.getLinkMans().add(linkMan);
customer.getLinkMans().add(linkMan2);
session.save(customer); // 客户要设置级联属性为save-update才能成功保存
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
}
}
}
XMl配置中set标签的inverse属性值
inverse="false" 默认 不放弃级联
inverse="true" 放弃级联
好处在进行update操作时可以提高效率减少一次数据库操作
第二节 多对多映射列表(XML)
多对多使用的人和角色的关系举例,即一个人可以同时有多个角色,一个角色同时可以是多个人的。
- 创建人实体类 Man.java
package cn.lkangle.entity;
import java.util.HashSet;
import java.util.Set;
public class Man {
private Integer man_id;
private String man_name;
private String man_attr;
private Set roles = new HashSet<>();
...
}
- 创建角色实体类 Role.java
package cn.lkangle.entity;
import java.util.HashSet;
import java.util.Set;
public class Role {
private Integer role_id;
private String role_name;
private Set mans = new HashSet<>();
...
}
- XML映射配置文件
set集合属性
table: 第三个表的表名
key属性
column: 本表外键在第三张表中的字段名
many-to-many属性
class: 另一个实体类的路径
column: 另一个表外键在第三张表中的字段名
两个实体类的配置对应关系如图:
- 多对多的CRUD操作
package cn.lkangle.threeday;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import cn.lkangle.entity.Man;
import cn.lkangle.entity.Role;
import cn.lkangle.util.HbmUtil;
public class ManyToMany {
/**
* 查询
*/
@Test
public void testManySelect() {
Session session = null;
Transaction tx = null;
try {
session = HbmUtil.getSession();
tx = session.beginTransaction();
Man man = session.get(Man.class, 2);
System.out.println(man);
Set roles = man.getRoles();
for (Role role : roles) {
System.out.println(role);
}
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
}
}
/**
* 修改 通过维护第三张表实现
*/
@Test
public void testManyUpdate() {
Session session = null;
Transaction tx = null;
try {
session = HbmUtil.getSession();
tx = session.beginTransaction();
Man man = session.get(Man.class, 2);
Role role = session.get(Role.class, 3);
man.getRoles().add(role);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
}
}
/**
* 直接性级联删除 不推荐
*/
@Test
public void testManyDelete0() {
Session session = null;
Transaction tx = null;
try {
session = HbmUtil.getSession();
tx = session.beginTransaction();
Man man = session.get(Man.class, 1);
session.delete(man);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
}
}
/**
* 删除 通过维护第三张表实现
*/
@Test
public void testManyDelete() {
Session session = null;
Transaction tx = null;
try {
session = HbmUtil.getSession();
tx = session.beginTransaction();
Man man = session.get(Man.class, 1);
Role role = session.get(Role.class, 1);
man.getRoles().remove(role);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
}
}
/**
* 多对多级联保存
*/
@Test
public void testMany() {
Session session = null;
Transaction tx = null;
try {
session = HbmUtil.getSession();
tx = session.beginTransaction();
Man man = new Man();
man.setMan_name("严老");
man.setMan_attr("兔斯基");
Man man2 = new Man();
man2.setMan_name("叶老");
man2.setMan_attr("土耳其");
Role role = new Role();
role.setRole_name("老板");
Role role2 = new Role();
role2.setRole_name("秘书");
Role role3 = new Role();
role3.setRole_name("保安");
man.getRoles().add(role);
man.getRoles().add(role2);
man2.getRoles().add(role);
man2.getRoles().add(role3);
session.save(man);
session.save(man2);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
}
}
}
实话我还没写过用到相关操作的项目、、、数据库也没系统学习过对此感觉很是生疏,看过教程也就会这一些基础的知识,更细节深入的知识还需要以后继续学习~~