对象关系 - 多对一

对象关系 - 多对一

一对一就好比一个班级对应一个班主任,而一个班主任也只管理一个班级

多对一就好比班级和学生的关系,一个班级有很多学生,很多的学生组成一个班级

由于一对一比较简单,再此就不过多解释了,接下来先用一个项目来讲解多对一

来做一个hibernate多对一的增删改查

JavaBean代码多端:学生

//一个班级有好多学生
public class Student {// manytoOne
	private int sid;
	private String sname;
	private int age;
	private double score;
	// 关联属性
	private Clazz clazz;
	public Student() {

	}
	public int getSid() {
		return sid;
	}

	public void setSid(int sid) {
		this.sid = sid;
	}
	public String getSname() {
		return sname;
	}
	public void setSname(String sname) {
		this.sname = sname;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public double getScore() {
		return score;
	}
	public void setScore(double score) {
		this.score = score;
	}
	public Clazz getClazz() {
		return clazz;
	}
	public void setClazz(Clazz clazz) {
		this.clazz = clazz;
	}
	@Override
	public String toString() {
		return "Student [sid=" + sid + ", sname=" + sname + ", age=" + age + ", score=" + score + ", clazz=]"  
				;
	}
}

JavaBean代码一端: Clazz班级,由于是单向的,故此看不见多端的详情

public class Clazz {//onetomany
	private int cid;
	private String cname;	
	public Clazz() {
	}
	public int getCid() {
		return cid;
	}
	public void setCid(int cid) {
		this.cid = cid;
	}
	public String getCname() {
		return cname;
	}
	public void setCname(String cname) {
		this.cname = cname;
	}
	@Override
	public String toString() {
		return "Clazz [cid=" + cid + ", cname=" + cname + "]";
	}
}

核心配置文件hiernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
		"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
		"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
    	<!-- DB四要素 -->
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="hibernate.connection.password">1234</property>
		<property name="hibernate.connection.url">jdbc:mysql:///bwie</property>
		<property name="hibernate.connection.username">root</property>
		<!--方言  -->
		<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
		<!-- 配置数据源 -->
		<property name="hibernate.connection.provider_class">
			org.hibernate.connection.C3P0ConnectionProvider
		</property>
		<!--生成sql-->
		<property name="hibernate.hbm2ddl.auto">update</property>
		<!--展示sql -->
		<property name="hibernate.show_sql">true</property>
		<!--格式化sql -->
		<property name="hibernate.format_sql">true</property>
		<!-- sesssion上下文 -->
		<property name="hibernate.current_session_context_class">thread</property>
		<!--关联 映射文件 -->
        <!-- !!!重点注意哦!!! -->
		<mapping resource="com/baidu/bean/Student.hbm.xml"/>
		<mapping resource="com/baidu/bean/Clazz.hbm.xml"/>
	</session-factory>
</hibernate-configuration>

关联配置文件:clazz端

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2018-11-14 16:26:37 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
	<class name="com.baidu.bean.Clazz" table="t_clazz">
		<id name="cid" type="int">
			<column name="cid" />
			<generator class="native" />
		</id>
		<property name="cname" type="java.lang.String">
			<column name="CNAME" />
		</property>
	</class>
</hibernate-mapping>

关联配置文件学生端Student.hbm.xml

<?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="com.baidu.bean">
    <class name="Student" table="t_student">
        <id name="sid" type="int">
            <column name="sid" />
            <generator class="native" />
        </id>
        <property name="sname" type="java.lang.String">
            <column name="SNAME" />
        </property>
        <property name="age" type="int">
            <column name="AGE" />
        </property>
        <property name="score" type="double">
            <column name="SCORE" />
        </property>
        <many-to-one name="clazz" class="Clazz" fetch="join" cascade="save-update" lazy="false">
        	<!-- 外键字段名称 -->
            <!-- !!!重点注意部分!!! -->
            <column name="cid" />
        </many-to-one>
    </class>
</hibernate-mapping>

Dao层代码如下:

public interface StudentDao {
	// 添加学生
	public int insertStudent(Student stu);
	// 删除学生
	public int deleteStudentById(int id);
	// 修改学生
	public int updateStudent(Student stu);
	// 查询学生
	public Student selectStudentById(int sid);
	// 查询所有信息
	public List<Student> selectAll();
}

Dao实现类代码:

public class StudentDaoImpl implements StudentDao {
	@Override
	public int insertStudent(Student stu) {
		// 获取session
		Session session = HbnUtil.getSession();
		// 开启事务
		session.getTransaction().begin();
		// 添加对象
		session.save(stu);
		// 提交事务
		session.getTransaction().commit();
		return 1;
	}
    @Override
	public int deleteStudentById(int id) {
		// 获取session
		Session session = HbnUtil.getSession();
		// 开启事务
		session.getTransaction().begin();
		// 获取对象
		Student stu = session.get(Student.class, id);
		// 删除对象
		session.delete(stu);
		// 提交事务
		session.getTransaction().commit();
		return 1;
	}
	@Override
	public int updateStudent(Student stu) {
		// 获取session
		Session session = HbnUtil.getSession();
		// 开启事务
		session.getTransaction().begin();
		// 删除对象
		session.update(stu);
		// 提交事务
		session.getTransaction().commit();
		return 1;
	}
	@Override
	public Student selectStudentById(int sid) {
		// 获取session
		Session session = HbnUtil.getSession();
		// 开启事务
		session.getTransaction().begin();
		// 删除对象
		Student stu = session.get(Student.class, sid);
		// 提交事务
		session.getTransaction().commit();
		// 返回目标对象
		return stu;
	}
	@Override
	public List<Student> selectAll() {
		// 获取session
		Session session = HbnUtil.getSession();
		// 开启事务
		session.beginTransaction();
		//准备sql
		String hql="from Student";
		List<Student> list = session.createQuery(hql).list();
		// 提交事务
		session.getTransaction().commit();
		// 返回目标对象
		return list;
	}
}

Service层代码的如下:

public interface StudentService {
	// 添加学生
	public int addStudent(Student stu);
	// 删除学生
	public int removeStudentById(int id);
	// 修改学生
	public int changeStudent(Student stu);
	// 查询学生
	public Student queryStudentById(int sid);
	// 查询所有信息
	public List<Student> queryAll();
}

Service层的实现代码如下:

public class StudentServiceImpl implements StudentService {
	// 引入dao
	private StudentDao studentDao;
	// 构造器注入
	public StudentServiceImpl(StudentDao studentDao) {
		this.studentDao = studentDao;
	}
	@Override
	public int addStudent(Student stu) {
		return studentDao.insertStudent(stu);
	}
	@Override
	public int removeStudentById(int id) {
		return studentDao.deleteStudentById(id);
	}
	@Override
	public int changeStudent(Student stu) {
		return studentDao.updateStudent(stu);
	}
	@Override
	public Student queryStudentById(int sid) {
		return studentDao.selectStudentById(sid);
	}
	@Override
	public List<Student> queryAll() {
		return studentDao.selectAll();
	}
}

工具类代码如下:HbnUtil.java

public class HbnUtil {
	// 线程安全,可以当做成员对象共享给各个成员;
	public static SessionFactory sessionFactory;
	/**
	 * 获取sessionFactory对象
	 * @return
	 */
	public static SessionFactory getSessionFactory() {
		if (sessionFactory == null || sessionFactory.isClosed()) {
			return new Configuration().configure().buildSessionFactory();
		} else {
			return sessionFactory;
		}
	}
	/**
	 * 获取session
	 * 
	 * @return
	 */
	public static Session getSession() {
		// 调用方法
		return getSessionFactory().getCurrentSession();
	}
}

测试代码如下:增删改查的测试都是OK

public class MyTest {
	public StudentDao sDao = new StudentDaoImpl();
	public StudentService uService = new StudentServiceImpl(sDao);
	@Test
	public void testAdd() {
		// 添加操作
		Student stu = new Student();
		stu.setSname("王五");
		stu.setScore(90);
		stu.setAge(20);
		// 实例化班级表
		Clazz clz = new Clazz();
		clz.setCname("中级班");
		// 多端维护外键
		stu.setClazz(clz);
		// 添加对象
		uService.addStudent(stu);
	}
	@Test
	public void testDel() {
		// 删除操作
		int x = uService.removeStudentById(1);
		// 判断
		if (x > 0) {
			System.out.println("删除成功了");
		}
	}
	@Test
	public void testUpdate() {
		Clazz clz = new Clazz();
		clz.setCid(1);
		clz.setCname("加强班");

		Student stu = new Student();
		stu.setSname("张万年");
		stu.setScore(87);
		stu.setAge(10);
		stu.setSid(4);
		// 多端维护外键
		stu.setClazz(clz);
		// 删除操作
		int x = uService.changeStudent(stu);
		// 判断
		if (x > 0) {
			System.out.println("修改成功了");
		}
	}
	@Test
	public void testFindOne() {
		// 查询操作
		Student stu = uService.queryStudentById(3);
		// 展示对象信息
		System.out.println(stu);
	}
	@Test
	public void testFindAll() {
		// 查询操作
		List<Student> list = uService.queryAll();
		// 遍历容器
		for (Student stu : list) {
			// 展示对象信息
			System.out.println(stu);
		}
	}
}

注意事项:

主键的生成策略,常见的要知道其特点

Native,默认是自己维护;手动插入

Cascade:no,all,save-update,persister,外键的维护,一般推荐多端来维护;

在many-to-one中lazy的值的含义;

​ Proxy:

​ No-proxy:

​ False:立即加载

在ono-to-many中lazy中的值含义:

​ True:延迟加载

​ False:立即加载

​ Extra:增强加载

Cascade:级联:

​ No:不做级联操作

​ All:所有都做级联操作

​ Save-update,添加,修改时候做级联

​ Delete:级联删除

sessionFactory.openSession();

sessionFactory.getcrurentSession()区别;

双向的关联关系;

一端可以看见多端对象

public class Clazz {// onetomany
	private int cid;
	private String cname;
	// 关联属性集合
	private Set<Student> stus;
	public Clazz() {
		// 初始化属性
		stus = new HashSet<Student>();
	}
	//省略set,get方法
	@Override
	public String toString() {
		return "Clazz [cid=" + cid + ", cname=" + cname + ", stus=]";
	}
}

多端也可以一端的对象;

//一个班级有好多学生
public class Student {// manytoOne
	private int sid;
	private String sname;
	private int age;
	private double score;
	// 关联属性
	private Clazz clazz;	
	public Student() {
	}	
	public Student(String sname, int age, double score) {
		this.sname = sname;
		this.age = age;
		this.score = score;
	}	
//省略set,get方法
	@Override
	public String toString() {
		return "Student [sid=" + sid + ", sname=" + sname + ", age=" + age + ", score=" + score + ", clazz=" + clazz
				+ "]";
	}
}

配置文件:

<?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="com.baidu.bean">
    <class name="Clazz" table="t_clazz">
        <id name="cid" type="int">
            <column name="cid" />
            <generator class="native" />
        </id>
        <property name="cname" type="java.lang.String">
            <column name="CNAME" />
        </property>
        <!--关联属性  -->
        <set name="stus" table="t_student" inverse="false" cascade="save-update" lazy="false">
            <key>
                <column name="cid" />
            </key>
            <one-to-many class="Student"  />
        </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="com.baidu.bean">
    <class name="Student" table="t_student">
        <id name="sid" type="int">
            <column name="SID" />
            <generator class="native" />
        </id>
        <property name="sname" type="java.lang.String">
            <column name="SNAME" />
        </property>
        <property name="age" type="int">
            <column name="AGE" />
        </property>
        <property name="score" type="double">
            <column name="SCORE" />
        </property>
        <!-- 关联属性 -->
        <many-to-one name="clazz" class="Clazz" fetch="join" lazy="false" cascade="save-update">
            <column name="cid" />
        </many-to-one>
    </class>
</hibernate-mapping>

测试添加一个班级,班级里三个学生对象:

	@Test
	public void test00() {
		//添加一个班级,里面有三个学生
		Clazz clz=new Clazz();
		clz.setCname("加强班");
		
		Student s1=new Student("令狐冲",20,92);
		Student s2=new Student("张无忌",21,82);
		Student s3=new Student("刘德华",22,95);
		
		clz.getStus().add(s1);
		clz.getStus().add(s2);
		clz.getStus().add(s3);
		//添加一个班级,级联添加三个对象,班级来管理外键
		//获取session
		Session session = HbnUtil.getSession();
		//开启事务
		session.beginTransaction();
		//执行添加操作
		session.save(clz);
		//提交事务
		session.getTransaction().commit();
	}

I.类级别:

​ <class>元素中lazy属性的可选值为true(延迟加载)和false(立即加载);

​ <class>元素中的lazy属性的默认值为true

II.一对多关联级别:

​ <set>元素中的lazy属性的可选值为:true(延迟加载),extra(增强延迟加载)和false(立即加载);

​ <set>元素中的lazy属性的默认值为true

III.多对一关联级别:

​ <many-to-one>元素中lazy属性的可选值为:proxy(延迟加载),no-proxy(无代理延迟加载)和false(立即加载)

​ <many-to-one>元素中的lazy属性的默认值为proxy

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值