1、1. Configuration2. SessionFactory3. Transaction4. 保存学 生记 录的例子 保存、更新一定要显式调用事务5. manyto one 的级连更新 例子6. hibernate 查询复杂 的查询需求 Restrictions,Projections 的用法结果集排序 投 影 Projections,提供聚合函数的类对多个字段进行 投影7. 分页查询8. 根据模版例 子查询9. 离线查询10. HQL 聚 合函数11. HQL 例子12. 清除 Session 内部缓存的两个方法,Session.evict(Object o) ,Session.cle
2、ar() 清空内部缓存13. inverse14.15. Hibernate 设置 二级缓存16. 使用经验Configuration使用Hibernate 必须首先提供这些基础信息以完成初始化工作,为后继操作做好准备。这些属性在hibernate配置文件(hibernate.cfg.xml或hibernate.properties)中加以设定。Hibernate会自动在当前的 CLASSPATH 中搜寻hibernate.cfg.xml文件并将其读取到内存中作为后继操作的基础配置。Configuration config= new Configuration().configure();Se
3、ssionFactory会话工厂缓存了生成的SQL语句和Hibernate 在运行时使用的映射元数据。它在多个应用线程间进行共享。通常情况下,整个应用只有唯一的一个会话工厂。如果你使用Hibernate访问多个数据库,你需要对每一个数据库使用一个会话工厂。SessionFactory负责创建Session 实例。我们可以通过 Configuation实例构建SessionFactory:Configuration config = new Configuration().configure();SessionFactory sessionFactory= config.buildSession
4、Factory();Transaction使用Hibernate进行操作时(增、删、改)必须显示的调用Transaction(默认:autoCommit=false)。Configuration config= new Configuration().configure();SessionFactory sessionFactory= config.buildSessionFactory();Session session= sessionFactory.openSession();Transaction tx= session.beginTransaction();Student stu=n
5、ew Student();.session.save(stu);mit();保存学生记录的例子一定要显式调用事务,Transaction tx= session.beginTransaction();public static void saveStudent() /(1)创建Hibernate 的Configuration 对象Configuration config= new Configuration().configure();/* (2)从config 中获取SessionFactory对象(可以多线程共享)* 在整个应用程序中,SessionFactory 只需要一个实例,所以一在
6、系统启动时创建*/SessionFactory sessionFactory = config.buildSessionFactory();/(3)创建Session对象(单线程独占),通过session完成curd操作Session session= sessionFactory.openSession();/(4)可以创建一个Transaction对象Transaction tx= session.beginTransaction();Student stu=new Student();stu.setName(“小明明“);stu.setAge(96);stu.setDesc(“他是一个坏
7、学生“);stu.setSex(“f“);try/保存学生对象到数据库session.save(stu);/提交事务mit();System.out.println(“保存成功!“ );catch(Exception e)/如果失败,回退tx.rollback();System.out.println(“保存失败!“ );finally/ 最后关闭sessionsession.close();manyto one 的级联更新例子要在标签增加 cascade=“save-update“ ,Hibernate才会级连更新*最好在外键约束上加上 not-null=”true”,表示外键不能为空,这是
8、一个好的编程习惯在一对一的关联和多对一几乎是一样的,唯一不同的就是单向一对一关联中的外键键字段具有唯一约束. Unique=”true”Session session=HibernateSessionFactory.getSession();Address address=new Address(“gzXXX“,new Integer(4567851);Person person=new Person();person.setProsonName(“FGHJ“);person.setAddress(address);Transaction tx= session.beginTransactio
9、n();session.save(person);mit();hibernate 查询获取一个对象(即如何对应数据库的记录 )?最简单的请况是知道了对象的 ID(对象主键),使用 load()方法或 get()方法例如我们要查询一个用户信息,事先知道了它的用户 IDsession.load(Student.class, new Integer(1);或者session.get(User.class, “1“);查询多个对象 -条件查询对象,由 session 创建。 -查询条件对象,由 Restrictions 创建,Criterion 接口实例还可以通过 org.hibernate.crit
10、erion.Property 来取得/1).创建Criteria 实例,使用org.hibernate.Criteria接口Criteria stuCriteria = session.createCriteria(Student.class);/创建查询条件,这里是性别为 f的所有学生Criterion criterion=Restrictions.eq(“stuSex“,“f“);stuCriteria.add(criterion);List stuList=stuCriteria.list();如果有更复杂的查询需求,hibernate 照样能满足:1.查询条件按逻辑分组,例如我们查询名
11、字为“narci“或“frank“ 的男性用户,可以这样写:userCriteria.add(Restrictions.or( Restrictions.eq(“name“, “narci“), Restrictions.eq(“name“, “frank“).add(Restrictions.eq(“sex“, “M“);结果集排序可以使用 org.hibernate.criterion.Order 来为查询结果排序,例如将上面的结果按用户年龄升序排序。userCriteria.add(Restrictions.ge(“age“, new Integer(“18“).add(Restrict
12、ions.eq(“sex“, “F“).addOrder(Order.asc(“age“);投影投影其实就是选择结果集中的某些列, *如果这些列的值是相等的,hibernate 会过滤.Projection 可以实现投影,org.hibernate.criterion.Projections 是 Projection 的实例工厂:/对 name 进行投影,这种方式只能对一个字段进行投影userCriteria.setProjection( Projections.groupProperty(“name“);/对多个字段进行投影/创建投影字段列表ProjectionList pl=Project
13、ions.projectionList();/向投影列表上添加具体的投影字段pl.add(Projections.groupProperty(“stuName“);pl.add(Projections.groupProperty(“stuSex“);criteria.setProjection(pl); List stuList=criteria.list();分页查询Criteria stuCriteria=session.createCriteria(Student.class);/设置起始行stuCriteria.setFirstResult(startRowNo);/设置每页要显示的记
14、录数stuCriteria.setMaxResults(size);List list=stuCriteria.list();session.close();根据模版例子查询*注意,如果有原始类型,如 int,会有默认的初值。Criteria stuCriteria = session.createCriteria(Student.class);/ 根据模版例子查询,查询性别为女性的学生,空的属性不会作为查询条件Student stu = new Student();stu.setStuSex(“m“);stu.setStuAge(26);stuCriteria.add(Example.cre
15、ate(stu);List list = stuCriteria.list();session.close();离线查询/ 创建一个条件查询对象Criteria criteria = session.createCriteria(Student.class);/ 添加查询条件Criterion /添加离线查询条件的代码DetachedCriteria avgAge = DetachedCriteria.forClass(Student.class).setProjection(Projections.avg(“stuAge“);/ 查询年龄大于平均年龄的所有学生Criterion criter
16、ion = Property.forName(“stuAge“).gt(avgAge);/ 添加查询条件对象到条件查询对象criteria.add(criterion);List stuList = criteria.list();session.close();return stuList;HQL1。大小些敏感,针对的是 pojo 类 2。from 语句Session session = HibernateSessionFactory.getSession();String hql=“from Student“; /查询所有学生的hqlQuery query=session.createQu
17、ery(hql); /创建 Query 对象List stuList=query.list();只显示两个字段的例子:Session session = HibernateSessionFactory.getSession();String hql2=“select stu.stuName,stu.stuSex from Student stu“;Query query=session.createQuery(hql2);List stuList=query.list(); /返回的是一个对象数组for(Object o:stuList)System.out.println(“*n“);Sys
18、tem.out.println(“学生姓名: “ + o0);System.out.println(“学生性别: “ + o1);这是可以返回类型安全对象的 hql 语句,但要求 pojo 的构造方法有这样的构造方法Session session = HibernateSessionFactory.getSession();String hql3=“select new Student(stu.stuName,stu.stuSex) from Student stu“;Query query=session.createQuery(hql3);List stuList=query.list()
19、;for(Student stu:stuList)System.out.println(“学生姓名: “ + stu.getStuName();System.out.println(“学生性别: “ + stu.getStuSex();/聚合函数String hql4=“select avg(stu.stuAge) from Student stu“;String hql5=“select count(*) from Student stu“;Query query=session.createQuery(hql4);List list=query.list();for(Object o:li
20、st)System.out.println(“平均年龄为: “+o);HQL 例子String hql=“from Student“; /查询所有学生的hql/查询sex为f的学生String hql6=“FROM Student stu WHERE stu.stuSex=f“;/in语句String hql7=“FROM Student stu WHERE stu.stuName in(aaa,tom,小冰冰)“;/order语句String hql8=“FROM Student stu order by stu.stuAge desc,stu.stuName asc“;/分组语句,统计学生
21、的年龄以及相同学生的人数String hql9=“select stu.stuAge,count(stu.stuAge) from Student stu “ +“group by stu.stuAge“;/只查询学生的两个属性,返回 Object String hql2=“select stu.stuName,stu.stuSex FROM Student stu“;/只查询学生的两个属性,返回学生类型的对象String hql3=“select new Student(stu.stuName,stu.stuSex) from Student stu“;/聚合函数String hql4=“s
22、elect avg(stu.stuAge) from Student stu“;String hql5=“select count(*) from Student stu“;3。join 相关(inner) joinleft (outer) joinright (outer) joinfull joinHQL 同样对 SQL 中的这些特性支持下面插播一个小话题,关于上边的那些特性,我一直都没怎么用,今天既然说到这里,就想把上边的几个特性的用法说一下,也算对自己的一个补充:假设有两个表:部门、员工,下面列举一些数据:员工(Employee):ID Name DepNo001 Jplateau 0
23、1002 Jony 01003 Camel 02部门(Department):ID Name01 研发部02 营销部在 Hibernate 中我们操纵的都是对象,所以我们操纵的是部门类和员工类1).(inner) joinselect employee.ID as id1,employee.Name as name1,department.ID as id2,department.Nameas name2 from Employee as employee join Department as department on employee.DepNo=department.ID (注意到条件语
24、句我用 on 没有用 where)那么执行结果是什么呢?id1 name1 id2 name2+001 Jplateau 01 研发部002 Jony 01 研发部2).left (outer) joinselect employee.ID as id1,employee.Name as name1,department.ID as id2,department.Nameas name2 from Employee as employee left join Department as department on employee.DepNo=department.ID 那么执行结果又该是什么
25、呢?id1 name1 id2 name2+001 Jplateau 01 研发部002 Jony 01 研发部 003 Camel null null 就是说此时我要已第一个表的记录多少为准,第二个表中没有相应纪录的时候填充 null 3). right (outer) joinselect employee.ID as id1,employee.Name as name1,department.ID as id2,department.Nameas name2 from Employee as employee right join Department as department on
26、employee.DepNo=department.ID 那么执行结果又该是什么呢?id1 name1 id2 name2+001 Jplateau 01 研发部002 Jony 01 研发部 null null 02 营销部 就是说此时我要已第二个表的记录多少为准,第一个表中没有相应纪录的时候填充 null 4。select 语句就是要确定你要从查询中返回哪些对象或者哪些对象的属性。写几个例子吧:select employee form Employee as employee select employee form Employee as employee where employee.
27、Name like J%select employee.Name form Employee as employee where employee.Name like J%select employee.ID as id1,employee.Name as name1,department.ID as id2,department.Nameas name2 from Employee as employee right join Department as department on employee.DepNo=department.ID select elements(employee.Name) from Employee as employee (不明白 elements 到底是做什么用的?望给于说明) 等等5。数学函数JDO 目前好像还不支持此类特性。avg(.), sum(.), min(.), max(.) count(*)