突然感觉接触到了流币的知识,完全不懂。数据库方面的很多东西以前都没接触过。等今年开课在认真学一遍吧,暂时按照教程把我学到的东西整理下。
第一节 一对多映射列表(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<LinkMan> linkMans = new HashSet<LinkMan>();
...
}
- 创建联系人实体类 LinkMan.java
package cn.lkangle.entity;
public class LinkMan {
private Integer lid;
private String name;
private String tel;
// 用于保存所属客户
private Customer customer;
...
}
- XML映射配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!-- 一对多的客户映射配置 -->
<class name="cn.lkangle.entity.Customer" table="t_customer">
<id name="cid" column="cid">
<generator class="native"></generator>
</id>
<property name="name" column="cname"></property>
<property name="attr" column="cattr"></property>
<set name="linkMans" cascade="save-update,delete">
<key column="clid"></key>
<one-to-many class="cn.lkangle.entity.LinkMan"></one-to-many>
</set>
</class>
<!-- 一对多的联系人映射配置 -->
<class name="cn.lkangle.entity.LinkMan" table="t_linkman">
<id name="lid" column="lid">
<generator class="native"></generator>
</id>
<property name="name" column="lname"></property>
<property name="tel" column="ltel"></property>
<many-to-one name="customer" class="cn.lkangle.entity.Customer" column="clid" cascade="save-update"></many-to-one>
</class>
</hibernate-mapping>
客户的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<LinkMan> 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<Role> 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<Man> mans = new HashSet<>();
...
}
- XML映射配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!-- 多对多用户映射配置 -->
<class name="cn.lkangle.entity.Man" table="t_man">
<id name="man_id" column="man_id">
<generator class="native"></generator>
</id>
<property name="man_name" column="man_name"></property>
<property name="man_attr" column="man_attr"></property>
<set name="roles" table="mans_role" cascade="save-update,delete">
<key column="man_id_3"></key>
<many-to-many class="cn.lkangle.entity.Role" column="role_id_3"></many-to-many>
</set>
</class>
<!-- 多对多角色映射配置 -->
<class name="cn.lkangle.entity.Role" table="t_role">
<id name="role_id" column="role_id">
<generator class="native"></generator>
</id>
<property name="role_name"></property>
<set name="mans" table="mans_role">
<key column="role_id_3"></key>
<many-to-many class="cn.lkangle.entity.Man" column="man_id_3"></many-to-many>
</set>
</class>
</hibernate-mapping>
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<Role> 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();
}
}
}
实话我还没写过用到相关操作的项目、、、数据库也没系统学习过对此感觉很是生疏,看过教程也就会这一些基础的知识,更细节深入的知识还需要以后继续学习~~