发表于: 2018-02-03 21:07:30
1 775
今日完成
1.hibernate的一对多与多对一操作。
(1)建立一个简单的模型,一对多与多对一。使用学生与班级模型,一个学生只能有一个班级,一个班级有多个学生。
在实体类中申明双方的包含关系。
对应的配置文件,中也需要申明相应的关系。
<hibernate-mapping>
<class name="lujing.entity.Classes" table="t_classes" schema="task4">
<id name="classId" column="class_id">
<generator class="native"/>
</id>
<property name="className" column="class_name"/>
<property name="classRoom" column="class_room"/>
<property name="classAdviser" column="class_adviser"/>
<set name="studentSet" cascade="save-update,delete" >
<key column="s_class_id"></key>
<!--
一对多,外键连接;hibernate使用双向维护的机制。
column:外键的名字
-->
<one-to-many class="lujing.entity.Students" />
</set>
</class>
</hibernate-mapping>
这里的主键生成策略需要注意一下。
3.主键生成策略
1、assigned
主键由外部程序负责生成,在 save() 之前必须指定一个。Hibernate不负责维护主键生成。与Hibernate和底层数据库都无关,可以跨数据库。在存储对象前,必须要使用主键的setter方法给主键赋值,至于这个值怎么生成,完全由自己决定,这种方法应该尽量避免。
2.
increment
由Hibernate从数据库中取出主键的最大值(每个session只取1次),以该值为基础,每次增量为1,在内存中生成主键,不依赖于底层的数据库,因此可以跨数据库。
sequence
采用数据库提供的sequence机制生成主键,需要数据库支持sequence。如oralce、DB、SAP DB、PostgerSQL、McKoi中的sequence。MySQL这种不支持sequence的数据库则不行(可以使用identity)。Hibernate生成主键时,查找sequence并赋给主键值,主键值由数据库生成,Hibernate不负责维护,使用时必须先创建一个sequence,如果不指定sequence名称,则使用Hibernate默认的sequence,名称为hibernate_sequence,前提要在数据库中创建该sequence。
特点:只能在支持序列的数据库中使用,如Oracle。
identity
identity由底层数据库生成标识符。identity是由数据库自己生成的,但这个主键必须设置为自增长,使用identity的前提条件是底层数据库支持自动增长字段类型,如DB2、SQL Server、MySQL、Sybase和HypersonicSQL等,
native
native由hibernate根据使用的数据库自行判断采用identity、hilo、sequence其中一种作为主键生成方式,灵活性很强。如果能支持identity则使用identity,如果支持sequence则使用sequence。
相应的在学生实体中也要声明对应的一个班级。
配置文件中也要使用
<class name="lujing.entity.Students" table="t_student" schema="task4">
<id name="sId" column="s_id">
<generator class="native" />
</id>
<property name="sName" column="s_name"/>
<property name="sSex" column="s_sex"/>
<property name="sAdress" column="s_adress"/>
<!--
<many-to-one>标签
name :关联对象的属性的名称.
column :表中的外键名称.
class :关联对象类的全路径
-->
<many-to-one name="classes" class="lujing.entity.Classes" column="s_class_id"/>
</class>
(2)级联保存操作。一样的,新建几个学生对象,一个班级对象,将学生添加到班级中,保存学生和班级,但是hibernate提供了更加简介的操作方法,使用以下属性,能够完成关联。
cascade="save-update,delete"
(3)对应的测试类
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Classes classes = new Classes();
// classes.setClassId(61103);
classes.setClassName("PHP12");
classes.setClassRoom("C450");
Classes classes1 = session.get(Classes.class,61101);
Students s1 = new Students();
s1.setsName("jack andor2");
s1.setsAdress("japan");
Students s2 = new Students();
s2.setsName("风清扬2");
s2.setsAdress("north china");
classes1.getStudentSet().add(s1);
classes1.getStudentSet().add(s2);
session.update(classes1);
// session.save(s1);
// session.save(s2);
transaction.commit();
session.close();
(4)对应的查询操作,使用对象导航查询,应为实体类中已经包含了相应的属性字段,查询后可以直接将他们取出来。——查询班级,将班级中所有学生也查询出来了。
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
//对象导航查询
Classes c1 = session.get(Classes.class,61101);
Set<Students> studentsSet = c1.getStudentSet();
for (Students students : studentsSet) {
System.out.println(students);
}
transaction.commit();
session.close();
遇到问题
1.hibernate的事务管理,始终不能正常执行,试了很多方法,都不行。这个填坑的过程真的很无语。
(1)看教程说是可以通过
Session session = sessionFactory.getCurrentSession();
方式拿到的session对应的事务可以使用spring来管理。配置方法
在对应的类上使用标签
报错
(2)然后说要配置session管理的类
然后。。。。
又有人说使用spring管理事务不需要上面那个配置了。
然后。。。。终于成功了,看见了可耐的sql语句了。
等等
数据库怎么没有数据啊。。。。???、
再往下看看信息
已近生成了主键,但是rolling back是什么鬼啊。
没明显是没有提交事务,说明spring 配置的事务管理并没有起到作用。很无奈,试了很多方法,都不管用。看来一下hibernate的集成文档,没懂。
还用乖乖的自己提交事务吧。
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
明日计划
1.看公司的框架和代码。
2.试一下spring的hibernate模版,我还没有放弃。
收获
1.了解了hibernate的一对多与多对一的操作。比mybatis要简单一些。
评论