hibernate学习笔记(三)

来源:互联网 发布:中国出口数据统计 编辑:程序博客网 时间:2024/06/05 20:47
1.hibernate中一级缓存指session级别的缓存,一个session做了一个查询操作,它会把这个操作的结果放到一级缓存中,如果这个session(一定要同一个session)又做了当从数据库查询数据时会先从一级缓存中去找,找不到再从数据库查。一级缓存会在session关闭时清除。

二级缓存为Sessionfactory级别的缓存,如果同一个sessionFactory创建的某个session执行了相同的操作,hibernate就会从二级缓存中查结果,而不会连接数据库,需要配置。

2.缓存中存放的是键值对,而通过list查询的结果会放入二级缓存,但list本身查询时不会使用二级缓存,因为list里边没有id

缓存会将对象以key-value存储起来,key为完整类名 + # + id,如

com.bjsxt.po.User#3
3.在一对多中,经常出现1+N问题,这表示一个sql语句查询引起N个sql语句执行。解决方案为懒加载或使用二级缓存。懒加载可为

@OneToMany(mappedBy="grade",fetch=FetchType.LAZY)
4.List和iterator区别
①list仅仅会填充二级缓存,却不能利用二级缓存
②iterator可以读二级缓存,对于一条查询语句,它会先从数据库中查找出符合所有条件的记录的id,然后根据id去缓存中找,若缓存中没有,再去数据库找。

5.hibernate对象生命周期经历三种状态,以程序来说明
①transient(游离态),它在内存中是自由存在的,与数据库没有任何关系

//创建一个Transient对象User user = new User();user.setName("username");user.setPwd("password");//此时user为游离态,没有与任何数据库的记录相关联,也与session没有任何关系
②persistent(持久态),与session和数据库都有关系

//创建一个Transient对象User user = new User();user.setName("username");user.setPwd("password");//此时user为游离态,没有与任何数据库的记录相关联,也与session没有任何关系Session session = sessionFactory.openSession();Transaction tx1 = session.beginTransaction();//此时的user仍为一个transient(游离态)对象session.save(user);//此时的user为persistent(持久态)对象tx1.commit();//提交后向数据库加入一条记录Transaction tx2 = session.beginTransaction();uesr.setPwd("abc");tx2.commit();//虽然在这个事务中没有调用Session的save方法来保存save对象,但由于user//对象处于persistent状态,所以对user所做的任何修改都将被持久化到数据库//所以这时数据库的密码已经修改为abc
③detached(游离态),有影响。游离态实体对象在数据库中有相应的记录(从持久态遗留下来的),如果没有被其它事务删除。但对对象所做的任何操作不再会对数据库
//创建一个Transient对象User user = new User();user.setName("username");user.setPwd("password");//此时user为游离态,没有与任何数据库的记录相关联,也与session没有任何关系Session session = sessionFactory.openSession();Transaction tx = session.beginTransaction();//此时的user仍为一个transient(游离态)对象session.save(user);//此时的user为persistent(持久态)对象tx.commit();//提交后向数据库加入一条记录session.close();//此时的user为detached(游离态),此时对user所进行的任何操作,都不会对数据库有任何影响
6.在配置hibernate的映射文件时,有generator class="native",表示设置主键自增

<id name="gid"><generator class="native"></generator><!-- 表示设置主键自增 --></id>
在类似于<one-to-many>等中,当前表对象对应前者,class数据对应后者。如在Department-Employee的一对多关系中,在Employee.hbm.xml是这么写

<many-to-one column="did" class="Department"><!--class对应的即为one的一方--><property name="ename" column="name"></property><property name="eid"></property><!-- column="name"对应数据库中的字段名,要是不写,那么默认对应的即为属性名。如此时数据库中字段为name,eid -->
7.下面说说映射文件如何配置
①在多对一中one-to-many
如User与Grade,User为多的一方,则在User.hbm.xml可如下

<hibernate-mapping package="com.bjsxt.po"><class name="User" table="t_user"><id name="id"><generator class="native"></generator></id><property name="name" ></property><property name="tel" ></property><!--关键还是看下边这配置--><many-to-one name="grade" class="Grade"><!-- class处该为com.bjsxt.po.Grade,但前边已加了包名,所以可以省略 --><column name="grade_id"></column><!--grade_id是自己写的,Grade里没有该属性--><!--grade_id与Grade.hbm.xml中的key column值相同,否则会出现多个外键  --></many-to-one></class></hibernate-mapping>

Grade.hbm.xml如下

<hibernate-mapping package="com.bjsxt.po"><class name="Grade" table="t_grade"><id name="gid"><generator class="native"></generator><!-- 设置主键自增 --></id><property name="gname" ></property><set name="setUser"><key column="grade_id"></key><!--此时grade_id也是自己所设,Grade没有该属性--><!--key column是指在多的一方,即User添加一个名为 grade_id的字段,配置的值为当前配置文件中主键的值,即gid。这实现了主外键关联 --><one-to-many class="User" /></set></class></hibernate-mapping>

②在多对多many-to-many中,需要产生一个中间表,方便查找。
如选课时,User与Course为多对多,那么User.hbm.xml可如下

<hibernate-mapping package="com.bjsxt.po"><class  name="User"  table="t_user" ><id  name="uid"  ><generator class="native"></generator></id><property name="name" ></property><set name="courses"  table="user_course" ><!--user_course即为中间表--><key><column name="user_id"></column><!--设置user_id为中间表主键,中间表可有多个主键--></key><many-to-many  class="Course"  column="course_id" ></many-to-many></set></class></hibernate-mapping>
这个<set>集合可以这么理解,在User.hbm.xml中,set集合中存的是课程,所以在<key>中的column name="user_id"表示一门课程由哪些学生(根据id查找)来选,底下的column="course_id",表示一个学生选了哪些课(根据course_id来找)。下边的都类似



而Course.hbm.xml如下

<hibernate-mapping package="com.bjsxt.po"><class  name="Course"  table="t_course" ><id  name="cid"  ><generator class="native"></generator></id><property name="cname"    ></property><set name="users"  table="user_course" ><!--中间表--><key><column name="course_id"></column><!--中间表的另一个主键--></key><many-to-many  class="User"  column="user_id"></many-to-many></set></class></hibernate-mapping>


产生的中间表如下:

可以看到,在映射表<set>中设置了中间表的主键,主键可以有多个。

下边给出一张总结性的图:

8.若在一个jsp下拉框想获取数据库的值,在页面载入时就展示出这些值,可以用s标签的action,比用继承监听器要简单。

<s:action name="departmentAction!findAll" namespace="/"  var="dep"  ></s:action><SELECT  name="employee.department.id"  ><s:iterator  value="#dep.list"  var="obj"  ><option value="${obj.id }" >${obj.dname }</option></s:iterator></SELECT>


原创粉丝点击