hibernate基础学习:关联关系
1. 单实体
2. 多实体关联
a. 关联
b. 聚合
c. 组合
1) 一对多关系是主流
确认主控方,主控方一般是一方。关系是由多方来维持的。
市民和公交卡
市民是强势方, 不需要去维护关系,因为关系不存在,它还可以安然存在。
公交卡是弱势方,如果不知道自己属于哪个市民,其将不复存在,所以公交卡需要去维护关系,需要去记住其所属的市民。在关系型数据中,关系就是外键。
明星和粉丝
一对多关系是这个世界的原生态的主流关系。
2) 一对一关系是被限制的一对多
a. 外键唯一约束
table citizen
cid cname
001 mary
002 david
table idcard
cardno carowner issue_date
c01 001 2016-1-1
c02 002 2016-1-2
b. 主外键重合,通过主键来间接实现外键唯一约束
> table citizen
cid cname
001 mary
002 david
> table idcard
cardno issue_date
001 2016-1-1
002 2016-1-2
3) 多对多是双向一对多。
4) 多对一是反向一对多。
下面是基本的代码:一对一关系:驾驶员-驾车关系
Car.java
/** * 工 程 名:HibernateOneToOneDemoPrj-20180526 <br> * 文 件 名:Car.java <br> * 工具包名:edu.fjnu.domain <br> * 功能描述:TODO <br> * 创建时间:2018年5月26日 下午9:35:32 <br> * 版本信息:V1.0 * @创建人:Zhou Kailun */ package edu.fjnu.domain; /** * 类名:Car <br> * 功能描述: <br> * 创建日期:2018年5月26日 下午9:35:32 <br> * 修改备注: * @作者信息:Zhou kailun <br> */ public class Car { /**汽车编号*/ private Integer carNo; /**汽车品牌*/ private String carBrand; /**汽车所属驾驶员*/ private Person carOwner; /**<p>构造函数:</p><br><br> * <p>描述:</p><br> */ public Car() { // TODO Auto-generated constructor stub } public Integer getCarNo() { return carNo; } public void setCarNo(Integer carNo) { this.carNo = carNo; } public String getCarBrand() { return carBrand; } public void setCarBrand(String carBrand) { this.carBrand = carBrand; } public Person getCarOwner() { return carOwner; } public void setCarOwner(Person carOwner) { this.carOwner = carOwner; } public String toString() { return "Car [carNo=" + carNo + ", carBrand=" + carBrand + ", carOwner=" +"owner" + "]"; } }
Person.java
/** * 工 程 名:HibernateOneToOneDemoPrj-20180526 <br> * 文 件 名:Person.java <br> * 工具包名:edu.fjnu.domain <br> * 功能描述:TODO <br> * 创建时间:2018年5月26日 下午9:36:14 <br> * 版本信息:V1.0 * @创建人:Zhou Kailun */ package edu.fjnu.domain; /** * 类名:Person <br> * 功能描述: <br> * 创建日期:2018年5月26日 下午9:36:14 <br> * 修改备注: * @作者信息:Zhou kailun <br> */ public class Person { /**人物编号*/ private Integer personNo; /**人名*/ private String personName; /**车辆信息*/ private Car car; /**<p>构造函数:</p><br><br> * <p>描述:</p><br> */ public Person() { // TODO Auto-generated constructor stub } public Integer getPersonNo() { return personNo; } public void setPersonNo(Integer personNo) { this.personNo = personNo; } public String getPersonName() { return personName; } public void setPersonName(String personName) { this.personName = personName; } public Car getCar() { return car; } public void setCar(Car car) { this.car = car; } public String toString() { return "Person [personNo=" + personNo + ", personName=" + personName + ", car=" + car + "]"; } }
Person.hbm.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 package="edu.fjnu.domain"> <!-- 人物信息与数据库匹配 --> <class name="Person" table="tbl_person"> <id name="personNo" column="person_no" type="java.lang.Integer" > <generator class="increment"/> </id> <property name="personName" column="person_name" type="java.lang.String" length="30" not-null="true"></property> <!-- 1.class="Car" 说明这个属性是Car对象 2:property-ref="carOwner" 你去查找所有Car的carOwner对象与我这个 --> <one-to-one name="car" class="Car" property-ref="carOwner" cascade="all"></one-to-one> </class> </hibernate-mapping>
Car.hbm.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 package="edu.fjnu.domain"> <!-- 车辆信息与数据库匹配 --> <class name="Car" table="tbl_car"> <id name="carNo" column="car_no" type="java.lang.Integer" length="4"> <generator class="assigned"></generator> </id> <property name="carBrand" column="car_brand" type="java.lang.String" length="30" not-null="true"></property> <!-- 1.class="Person" select * from tbl_person 2.column="car_owner" select * from tbl_person where person_no =? --> <many-to-one name="carOwner" class="Person" column="car_owner" unique="true"></many-to-one> </class> </hibernate-mapping>
Tester.java 测试文件Junit4测试
package edu.fjnu.test; import static org.junit.Assert.*; import java.util.List; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.junit.After; import org.junit.Before; import org.junit.Test; import edu.fjnu.domain.Car; import edu.fjnu.domain.Person; public class Tester { private SessionFactory factory; private Session session; @Before public void setUp() throws Exception { System.out.println("test prepared....."); Configuration config=new Configuration();//构建一个配置器 config.configure("/edu/fjnu/config/hibernate.cfg.xml"); factory =config.buildSessionFactory(); session=factory.openSession(); } @After public void tearDown() throws Exception { System.out.println("test clear...."); if(session.isOpen()) session.close(); if(!factory.isClosed()) factory.close(); } @Test public void testAdd(){ Car car=new Car(); car.setCarNo(003); car.setCarBrand("toney"); Person person=new Person(); person.setPersonName("jenny"); car.setCarOwner(person); person.setCar(car); Transaction trans=null; try{ trans=session.beginTransaction(); session.save(person); trans.commit(); }catch(HibernateException e){ e.printStackTrace(); trans.rollback(); } } @Test public void testSearch()throws Exception{ Transaction trans=null; String hql="from Person p where p.personName like 'm%' and p.car.carBrand like '%one%' order by p.personNo desc"; try{ trans=session.beginTransaction(); List data=session.createQuery(hql).list(); for(Object obj:data){ Person p=(Person)obj; System.out.println(p); } trans.commit(); }catch(HibernateException e){ e.printStackTrace(); trans.rollback(); } } @Test public void testChangeCar()throws Exception{ Transaction trans=null; Car car=new Car(); car.setCarNo(003); car.setCarBrand("superGone"); try{ trans=session.beginTransaction(); Person person=(Person)session.load(Person.class,new Integer(3)); person.getCar().setCarOwner(null); person.setCar(null); session.saveOrUpdate(person); session.flush(); person.setCar(car); car.setCarOwner(person); session.saveOrUpdate(person); trans.commit(); }catch(HibernateException e){ e.printStackTrace(); trans.rollback(); } } @Test public void testRemove()throws Exception { Transaction trans=null; try{ trans=session.beginTransaction(); Person person=(Person)session.load(Person.class, new Integer(1)); person.getCar().setCarOwner(null); person.setCar(null); session.delete(person); trans.commit(); }catch(HibernateException e){ e.printStackTrace(); trans.rollback(); } } @Test public void testUpdate()throws Exception { Transaction trans=null; try{ trans=session.beginTransaction(); Person person=(Person)session.load(Person.class, new Integer(2)); Car car=person.getCar(); car.setCarBrand("ford"); session.saveOrUpdate(person); trans.commit(); }catch(HibernateException e){ e.printStackTrace(); trans.rollback(); } } }
然后是原来的SMS-SSH 的整合 学生管理系统
User.hbm.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 package="edu.fjnu.training.domain"> <!-- 用户信息与数据库匹配 --> <class name="User" table="tbl_user"> <id name="userNo" column="user_no" type="java.lang.String" length="6"></id> <property name="userName" column="user_name" type="java.lang.String" length="30" not-null="true"></property> <property name="userPwd" column="user_pwd" type="java.lang.String" length="6" not-null="true"></property> </class> </hibernate-mapping>
Student.hbml.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 package="edu.fjnu.training.domain"> <!-- 学生信息与数据库匹配 --> <class name="Student" table="tbl_student"> <id name="stuNo" column="stu_no" type="java.lang.String" length="4"></id> <property name="stuName" column="stu_name" type="java.lang.String" length="30" not-null="true"></property> <property name="stuMark" column="stu_mark" type="java.lang.Integer" length="11"></property> <property name="stuSex" column="stu_sex" type="java.lang.String" length="2"></property> <property name="stuHobbyStr" column="stu_hobbies" type="java.lang.String" length="30"></property> <property name="stuOrigin" column="stu_origin" type="java.lang.String" length="2"></property> <property name="stuMemo" column="stu_memo" type="java.lang.String" length="30"></property> <property name="stuPic" column="stu_pic" type="binary"></property> </class> </hibernate-mapping>
UserDaoHibernateImpl.java
/** * 工 程 名:SMS-SSH-20180524 <br> * 文 件 名:UserDaoHibernateImpl.java <br> * 工具包名:edu.fjnu.training.dao <br> * 功能描述:TODO <br> * 创建时间:2018年5月26日 下午7:25:47 <br> * 版本信息:V1.0 * @创建人:Zhou Kailun */ package edu.fjnu.training.dao; import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.TransactionException; import edu.fjnu.training.domain.User; import edu.fjnu.training.exception.DataAccessException; import edu.fjnu.training.utils.HibernateUtils; /** * 类名:UserDaoHibernateImpl <br> * 功能描述: <br> * 创建日期:2018年5月26日 下午7:25:47 <br> * 修改备注: * @作者信息:Zhou kailun <br> */ public class UserDaoHibernateImpl implements UserDao { /**<p>构造函数:</p><br><br> * <p>描述:</p><br> */ public UserDaoHibernateImpl() { // TODO Auto-generated constructor stub } /* (非 Javadoc) * <p>Title:getUserByNo</p> * <p>描 述:</p> * @param userNo * @return * @see edu.fjnu.training.dao.UserDao#getUserByNo(java.lang.String) */ @Override public User getUserByNo(String userNo) { Session session=HibernateUtils.createSession(); Transaction trans=null; trans=session.beginTransaction(); User user=null; try{ user=session.get(User.class, userNo); trans.commit(); }catch(TransactionException e){ e.printStackTrace(); trans.rollback(); }finally{ if(session.isOpen()){ session.close(); } } if(user==null) throw new DataAccessException("账号不存在"); return user; } @Override public void delUser(String userNo) { // Session session=HibernateUtils.createSession(); // Transaction trans=null; // trans=session.beginTransaction(); // // try{ // session.delete(userNo); // trans.commit(); // }catch(TransactionException e){ // e.printStackTrace(); // trans.rollback(); // } } }
StudentDaoHibernateImpl.java
/** * 工 程 名:SMS-SSH-20180524 <br> * 文 件 名:StudentDaoHibernateImpl.java <br> * 工具包名:edu.fjnu.training.dao <br> * 功能描述:TODO <br> * 创建时间:2018年5月26日 下午8:28:07 <br> * 版本信息:V1.0 * @创建人:Zhou Kailun */ package edu.fjnu.training.dao; import java.util.List; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.Transaction; import edu.fjnu.training.domain.Student; import edu.fjnu.training.utils.HibernateUtils; /** * 类名:StudentDaoHibernateImpl <br> * 功能描述: <br> * 创建日期:2018年5月26日 下午8:28:07 <br> * 修改备注: * @作者信息:Zhou kailun <br> */ public class StudentDaoHibernateImpl implements StudentDao { /**<p>构造函数:</p><br><br> * <p>描述:</p><br> */ public StudentDaoHibernateImpl() { // TODO Auto-generated constructor stub } /* (非 Javadoc) * <p>Title:addStudent</p> * <p>描 述:</p> * @param stu * @see edu.fjnu.training.dao.StudentDao#addStudent(edu.fjnu.training.domain.Student) */ @Override public void addStudent(Student stu) { Session session=HibernateUtils.createSession(); Transaction trans=null; trans=session.beginTransaction();; try{ session.saveOrUpdate(stu); trans.commit(); }catch(HibernateException e){ e.printStackTrace(); trans.rollback(); }finally{ if(session.isOpen()){ session.close(); } } } /* (非 Javadoc) * <p>Title:removeStudent</p> * <p>描 述:</p> * @param stuNo * @see edu.fjnu.training.dao.StudentDao#removeStudent(java.lang.String) */ @Override public void removeStudent(String stuNo) { Session session=HibernateUtils.createSession(); Transaction trans=null; trans=session.beginTransaction();; try{ Student stu=session.load(Student.class, stuNo); session.delete(stu); trans.commit(); }catch(HibernateException e){ e.printStackTrace(); trans.rollback(); }finally{ if(session.isOpen()){ session.close(); } } } /* (非 Javadoc) * <p>Title:loadAllStudent</p> * <p>描 述:</p> * @return * @see edu.fjnu.training.dao.StudentDao#loadAllStudent() */ @Override public List<Student> loadAllStudent() { Session session=HibernateUtils.createSession(); Transaction trans=null; List<Student> stuList=null; trans=session.beginTransaction(); try{ String hql="from Student s order by s.stuNo desc";//查询语句 stuList=session.createQuery(hql).list(); trans.commit(); }catch(HibernateException e){ e.printStackTrace(); trans.rollback(); }finally{ if(session.isOpen()){ session.close(); } } return stuList; } /* (非 Javadoc) * <p>Title:getStudentByStuNo</p> * <p>描 述:</p> * @param stuNo * @return * @see edu.fjnu.training.dao.StudentDao#getStudentByStuNo(java.lang.String) */ @Override public Student getStudentByStuNo(String stuNo) { Session session=HibernateUtils.createSession(); Transaction trans=null; Student stu=null; trans=session.beginTransaction(); try{ stu=session.get(Student.class, stuNo); trans.commit(); }catch(HibernateException e){ e.printStackTrace(); trans.rollback(); }finally{ if(session.isOpen()){ session.close(); } } return stu; } /* (非 Javadoc) * <p>Title:updateStudent</p> * <p>描 述:</p> * @param stu * @see edu.fjnu.training.dao.StudentDao#updateStudent(edu.fjnu.training.domain.Student) */ @Override public void updateStudent(Student stu) { Session session=HibernateUtils.createSession(); Transaction trans=null; trans=session.beginTransaction(); try{ if(stu.getStuPic()==null || stu.getStuPic().length==0){ stu.setStuPic(this.loadStuPicByNo(stu.getStuNo())); } session.saveOrUpdate(stu);; trans.commit(); }catch(HibernateException e){ e.printStackTrace(); trans.rollback(); }finally{ if(session.isOpen()){ session.close(); } } } /* (非 Javadoc) * <p>Title:loadStuPicByNo</p> * <p>描 述:</p> * @param stuNo * @return * @see edu.fjnu.training.dao.StudentDao#loadStuPicByNo(java.lang.String) */ @Override public byte[] loadStuPicByNo(String stuNo) { return this.getStudentByStuNo(stuNo).getStuPic(); } }