在下初次接触hibernate,学习之余,有几点小结,与大家分享一下。当然了,作为一个初学者,小结的不足之处,希望大家指点,呵呵,话不多说,咱先进入正题吧!
Hibernate小结I
一、Lazy的取值,对于load方法的影响
<hibernate-mapping>
<class name="domain.Dept" table="dept" catalog="hibernate" lazy="false">
</class>
</hibernate-mapping>
延迟加载
public void testLoad() {
Configuration conf = new Configuration();
conf.configure();
SessionFactory factory = conf.buildSessionFactory();
Session session = factory.openSession();
// 【注】这里不需要new事务
//只执行load方法时,不会执行HQL语句
Dept dept = (Dept) session.load(Dept.class, 20);
System.out.println("-----------");
System.out.println(dept.getDeptno() + " " + dept.getDname() + " "
+ dept.getLoc());
session.close();
}
1、当lazy="false"时,结果如下:
2、当lazy="true"时,结果如下:
Lazy的取值默认为true
get()、load()方法比较
get()
Dept dept = (Dept) session.get(Dept.class, 20);
System.out.println("-----------");
System.out.println(dept.getDeptno() + " " + dept.getDname() + " "
+ dept.getLoc());
Lazy为true或false时,结果一样:
联系:都可以通过指定的实体类与ID从数据库中读取数据,并返回对应的实例
区别大致如下:
1、Load()方法的取值与lazy的取值有关
Get()方法的执行效果与lazy的取值无关
2、如果未能发现符合条件的记录,
get方法会抛出一个空指针异常:
而load方法会抛出一个ObejctNotFoundException :
3、Load方法可以充分利用内部缓存和二级缓存中现有数据,
而get方法则仅仅在内部缓存中进行数据查找,如没有发现对应数据,将越过二级缓存,直接调用SQL完成数据读取。
二、Lazy的取值,对于查询的影响不是很大
【方法1】
先通过Query对象来得到一个List对象
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Dept");
List queryList = query.list();//相当于执行一次HQL语句,取出所有数据
System.out.println("------------");
Iterator it = queryList.iterator();
while (it.hasNext()) {
Dept dept = (Dept) it.next();
System.out.println(dept.getDeptno() + " " + dept.getDname() + " "+ dept.getLoc());
}
不管lazy的取值为何,本方法照旧将所有的数据都取出来。
【方法2】
直接通过Query对象来迭代
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Dept");
//【注】该方式先取出所有数据的id,在进行迭代时再执行每一个id的HQL语句,一次只取一个
Iterator it = query.iterate();
System.out.println("---------------");
while (it.hasNext()) {
Dept dept = (Dept) it.next();
System.out.println(dept.getDeptno() + " " + dept.getDname() + " "+ dept.getLoc());
}
【方法3】
具体指定查询数据库中的数据
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Dept");
query.setFirstResult(1);
query.setMaxResults(2);
List queryList = query.list();
Iterator it = queryList.iterator();
while (it.hasNext()) {
Dept dept = (Dept) it.next();
System.out.println(dept.getDeptno() + " " + dept.getDname() + " "+ dept.getLoc());
}
【方法4】
在HQL语句中指定一个输入参数
Transaction tx=session.beginTransaction();
Query query=session.createQuery("from Dept as dept where dept.deptno=?");
query.setParameter(0, 20);
Iterator it=query.list().iterator();
while(it.hasNext()){
Dept dept=(Dept)it.next();
System.out.println(dept.getDeptno()+" "+dept.getDname()+" "+dept.getLoc());
}
【方法5】
在HQL语句中指定多个参数
Transaction tx=session.beginTransaction();
Query query=session.createQuery("from Dept as dept where dept.deptno=? and dept.loc=?");
query.setParameter(0, 10);
query.setParameter(1, "NEW YORK");
Iterator it=query.iterate();
while(it.hasNext()){
Dept dept=(Dept)it.next();
System.out.println(dept.getDeptno()+" "+dept.getDname()+" "+dept.getLoc());
}
---------------------------------------------------------------------
测试所用数据库信息
配置文件的几个注意点
<set name="emps" cascade="delete">
<key column="dept_id"/>
<one-to-many class="domain.TEmp"/>
</set>
当cascade为delete:
删除dept中的数据时,会自动地将emp中对应的该deptno的员工也删除
删除emp中的数据时,仅会删除emp表中对应的数据,dept表中的数据不变。
当cascade为delete-orphan:
删除dept中的数据时,emp表中相应的数据亦删除
删除emp中的数据时,仅会删除emp表中对应的数据,dept表中的数据不变。
Dept dept = (Dept) session.load(Dept.class, "20");
System.out.println("---------");
Set set = dept.getEmps();
System.out.println("---------");
Iterator it = set.iterator();
while (it.hasNext()) {
TEmp emp = (TEmp) it.next();
if ("12".equals(emp.getName())) {
it.remove();//
System.out.println("del success........");
}
}
当cascade为delete:
删除dept中的数据时,会自动地将emp中对应的该deptno的员工的deptno置为null
当cascade为delete-orphan:
删除dept中的数据时,
cascade的几种取值方式
delete
delete-orphan
save-update
none
all: 相当于delete 和save-update的组合
all-delete-orphan
/**
* cascade=不写或none或save-update时,删除部门时,会自动将emp中对应该部门的字段置为null
*
* cascade=delete或delete-orphan或all或all-delete-orphan时,删除部门时,与该部门对应的emp中的字段亦被删除
*
*/
public void test3() {
Session session = HibernateSessionFactory.getSession();
Transaction tx = session.beginTransaction();
session.delete(session.load(Dept.class, "21"));
tx.commit();
session.close();
}
主键的生成方式:
<generator class="assigned" />
<!-- identity,sequence,native -->
assigned :由应用逻辑产生,主键的产生无需hibernate干预
identity:表示采用数据库的主键生成机制,
如MySQL 、SQL Server的自动主键生成方式
sequence:由序列方式产生主键的数据库,如Oracle
native:主键的生成机制由hibernate决定,hibernate会根据配置文件中的方言(Dialect)来定义。