one-to-many 一对多
package lt.demo6; import java.util.HashMap; import java.util.HashSet; import java.util.Set; public class Department { private Integer id; private String name; private Set<Employee> employees=new HashSet<Employee>(); @Override public String toString() { return "Department [id=" + id + ", name=" + name + ", employees=" + employees + "]"; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Set<Employee> getEmployees() { return employees; } public void setEmployees(Set<Employee> employees) { this.employees = employees; } }
package lt.demo6; public class Employee { private Integer id; private String name; private Department department; @Override public String toString() { return "Employee [id=" + id + ", name=" + name + "]"; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Department getDepartment() { return department; } public void setDepartment(Department department) { this.department = department; } }
javabean toString方法最好只包含基本类型,不包含引用数据类型
department 父表 映射 set集合映射
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="lt.demo6"> <class name="Department" table="t_department"> <id name="id"> <generator class="native" /> </id> <property name="name" type="string" column="name" length="50" /> <!-- column不写默认为name属性 --> <!-- key 对方表(子表)的外键列 --> <!-- class 关联的实体类型 --> <!-- inverse属性(相对于父表) --> <!-- 默认false 表示维护关联关系 --> <set name="employees" inverse="true"> <key column="departmentId"></key> <one-to-many class="Employee"/> <!-- class(实体类型)=====type(值类型) --> </set> </class> </hibernate-mapping>
employee子表映射 包含外键 name 外键类型 class 外键列
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="lt.demo6"> <class name="Employee" table="t_employee"> <id name="id"> <generator class="native" /> </id> <property name="name" type="string" column="name" length="50" /> <many-to-one name="department" class="Department" column="departmentId"></many-to-one> </class> </hibernate-mapping>
测试类
private static SessionFactory sessionFactory=new Configuration()// .configure()// .addClass(Employee.class)// .addClass(Department.class)// .buildSessionFactory();
public void testSave() { Session session=sessionFactory.openSession(); Transaction tx=session.beginTransaction(); //保存员工数据 Employee employee1=new Employee(); employee1.setName("张三"); Employee employee2=new Employee(); employee2.setName("lisi"); //保存部门信息 Department department=new Department(); department.setName("科研部门"); //设置联系 以至于两表之间可以互相获取对方 employee1.setDepartment(department); employee2.setDepartment(department); // 由于父表默认维护外键关系 所以设置关联只用设置子表的关联 // System.out.println(employee1.getDepartment()+"------"); // department.getEmployees().add(employee1); // department.getEmployees().add(employee2); //由上面生成 设置 子表关联后就不用设置父表关联了 两边都维护 面向对象愿意 数据库不愿意 //两全齐美解决办法 让没有外键那一方(主表) inverse=true //子表中有外键 可以自动维护父表 // Hibernate: update t_employee set departmentId=? where id=? // Hibernate: update t_employee set departmentId=? where id=? // System.out.println(department.getEmployees().size()+"------size()"); //保存两表信息 session.save(department); //放在上面 两个update 知道了departmentId // Hibernate: insert into t_department (name) values (?) // Hibernate: insert into t_employee (name, departmentId) values (?, ?) // Hibernate: insert into t_employee (name, departmentId) values (?, ?) // Hibernate: update t_employee set departmentId=? where id=? // Hibernate: update t_employee set departmentId=? where id=? // 如果父表设置了维护 session.save(employee1); session.save(employee2); // session.save(department); 放在下面四个update 不知道departmentId 效果一样 // Hibernate: insert into t_employee (name, departmentId) values (?, ?) // Hibernate: insert into t_employee (name, departmentId) values (?, ?) // Hibernate: insert into t_department (name) values (?) // Hibernate: update t_employee set name=?, departmentId=? where id=? // Hibernate: update t_employee set name=?, departmentId=? where id=? // Hibernate: update t_employee set departmentId=? where id=? // Hibernate: update t_employee set departmentId=? where id=? tx.commit(); session.close(); //注意one-to-many 维护的是外键表 //many-to-many 维护的是中间表 // many-to-many 设置一方inverse=true 就行 // }
public void testDelete() { // 父表 inverse=true 不维护由于外键约束是删不了的 //父表inverse=false 维护关联 会将子表的外键设为null 在删掉外键 //目前知道的唯一作用 //删父表 Session session=sessionFactory.openSession(); Transaction tx=session.beginTransaction(); Department department=(Department) session.get(Department.class, 2); session.delete(department); tx.commit(); session.close(); }
many-to-many
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="lt.demo7"> <class name="Student" table="student"> <id name="id"> <generator class="native" /> </id> <property name="name" type="string" column="name" length="50" /> <set name="teachers" table="teacher_student" > <key column="studentId"></key> <many-to-many class="Teacher" column="teacherId"></many-to-many> <!-- 外键 --> </set> </class> </hibernate-mapping> <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="lt.demo7"> <class name="Teacher" table="teacher"> <id name="id"> <generator class="native" /> </id> <property name="name" type="string" column="name" length="50" /> <set name="students" table="teacher_student" > <key column="teacherId"></key> <many-to-many class="Student" column="studentId"></many-to-many> <!-- 外键 --> </set> </class> </hibernate-mapping>
Long->Integer long.intValue()
Integer->Long x.Longvalue();
Long x=5L;
一对多 从父表设置关联(自动维护)
@Test public void testSave() { Session session=se
@Test public void testSave() { Session session=sessionFactory.openSession(); Transaction tx=session.beginTransaction(); //保存员工数据 Employee employee1=new Employee(); employee1.setName("张三"); Employee employee2=new Employee(); employee2.setName("lisi"); //保存部门信息 Department department=new Department(); department.setName("科研部门"); //设置联系 以至于两表之间可以互相获取对方 employee1.setDepartment(department); employee2.setDepartment(department); // System.out.println(employee1.getDepartment()+"------"); // department.getEmployees().add(employee1); // department.getEmployees().add(employee2); // //由上面生成 设置 子表关联后就不用设置父表关联了 两边都维护 面向对象愿意 数据库不愿意 //两全齐美解决办法 让没有外键那一方(主表) inverse=true //子表中有外键 可以走哦那个维护父表 // System.out.println(department.getEmployees().size()+"------size()"); //保存两表信息 session.save(department); //放在上面 两个update 知道了departmentId session.save(employee1); session.save(employee2); tx.commit(); session.close(); //注意one-to-many 维护的是外键表 //many-to-many 维护的 // many-to-many 设置一方inverse=true 就行 // }
Hibernate: insert into t_department (name) values (?) Hibernate: insert into t_employee (name, departmentId) values (?, ?) Hibernate: insert into t_employee (name, departmentId) values (?, ?) Hibernate: update t_employee set departmentId=? where id=? Hibernate: update t_employee set departmentId=? where id=?
为什么还多了两条update语句了?
因为从父表设置与子表(有外键方)的联系时,只有先插入所有数据后,父表才能去设置联系,导致多了两条update语句(没有实体不能设置关联)
从子表设置关联(推荐(规范))
@Test public void testSave() { Session session=sessionFactory.openSession(); Transaction tx=session.beginTransaction(); //保存员工数据 Employee employee1=new Employee(); employee1.setName("张三"); Employee employee2=new Employee(); employee2.setName("lisi"); //保存部门信息 Department department=new Department(); department.setName("科研部门"); //设置联系 以至于两表之间可以互相获取对方 employee1.setDepartment(department); employee2.setDepartment(department); //保存两表信息 session.save(department); //放在上面 两个update 知道了departmentId session.save(employee1); session.save(employee2); session.close(); //注意one-to-many 维护的是外键表 //many-to-many 维护的 // many-to-many 设置一方inverse=true 就行 // }
因为提前保存父表 ,从而子表知道了外键id,就不用更新,效率很高(1对1也是这样设置)
Hibernate: insert into t_department (name) values (?) Hibernate: insert into t_employee (name, departmentId) values (?, ?) Hibernate: insert into t_employee (name, departmentId) values (?, ?)
session.save(employee1);
session.save(employee2);
session.save(department);
Hibernate: insert into t_employee (name, departmentId) values (?, ?)
Hibernate: insert into t_employee (name, departmentId) values (?, ?)
Hibernate: insert into t_department (name) values (?)
Hibernate: update t_employee set name=?, departmentId=? where id=?
Hibernate: update t_employee set name=?, departmentId=? where id=?