本文主要介绍:

1 Criteria 接口

2 用 myeclipse 反向生成

3 hibernate  主键生成策略

4 多对一

5 一对多

6 使用List 集合的一对多

7 多对多

一、Criteria 接口

//例一
public static AdminInfo getLoginAdminCriteria(String adminName,String password){
try{
Session s=HibUtil.getSession();
Criteria c=s.createCriteria(AdminInfo.class);
c.add(Restrictions.eq("adminName", adminName));
c.add(Restrictions.eq("password", password)); return (AdminInfo) c.uniqueResult(); }finally{
HibUtil.closeSession();
}
}

QBC常用限定方法

Restrictions.eq --> equal,等于.

Restrictions.allEq --> 参数为Map对象,使用key/value进行多个等于的比对,相当于多个Restrictions.eq的效果

Restrictions.gt --> great-than > 大于

Restrictions.ge --> great-equal >= 大于等于

Restrictions.lt --> less-than, < 小于

Restrictions.le --> less-equal <= 小于等于

Restrictions.between --> 对应SQL的between子句

Restrictions.like --> 对应SQL的LIKE子句

Restrictions.in --> 对应SQL的in子句

Restrictions.and --> and 关系

Restrictions.or --> or 关系

Restrictions.isNull --> 判断属性是否为空,为空则返回true

Restrictions.isNotNull --> 与isNull相反

Restrictions.sqlRestriction --> SQL限定的查询

Order.asc --> 根据传入的字段进行升序排序

Order.desc --> 根据传入的字段进行降序排序

MatchMode.EXACT --> 字符串精确匹配.相当于"like 'value'"

MatchMode.ANYWHERE --> 字符串在中间匹配.相当于"like '%value%'"

MatchMode.START --> 字符串在最前面的位置.相当于"like 'value%'"

MatchMode.END --> 字符串在最后面的位置.相当于"like '%value'"

//例子
Criteria c=s.createCriteria(AdminInfo.class); // 查询 id在 10 到 30 之间的用户
c.add(Restrictions.between("id",10,30)).list(); //查询 adminName 在 张三,李四,王五之间的
String [] names={"张三","李四","王五"}; //这里也可以用集合 只要是从Collection派生的都可以
c.add(Restrictions.in("userName",names)).list(); //查询 note为空的用户
c.add(Restrictions.isNull("note")).list(); //查询年龄为空,或名字为admin的
c.add(Restrictions.or(Restrictions.eq("adminName", "admin"),Restrictions.isNull("age")));
 //使用 QBC实现动态查询(以前的例子)
public List<AdminInfo> getAdminList(String adminName,String password,String note) {
String sql="select * from adminInfo where 1=1 ";
if(adminName!=null){
sql+=" and adminName='"+addminName+"'";
}
if(password!=null){
sql+=" and adminName='"+password+"'";
}
if(note!=null){
sql+=" and adminName='"+note+"'";
}
}
 //上例使用 QBC
public static List<AdminInfo> getLoginAdminList(String adminName,String password,String note){
try {
Session s=HibUtil.getSession();
Criteria c=s.createCriteria(AdminInfo.class); if(adminName!=null){
c.add(Restrictions.eq("adminName", adminName));
} if(password!=null){
c.add(Restrictions.eq("password", password));
} if(note!=null){
c.add(Restrictions.eq("note", note));
} return c.list(); }finally{
HibUtil.closeSession();
}
} //官方推荐使用HQL

二、用 myeclipse 反向生成

Hibernate 的开发流程

1) 由domain对象开始   bean  -> 生成xml -> 生成数据库表

2) 由数据库表开始, 由表生成 bean 和 配置文件

3) 由配置文件开始

关于 <property name="hbm2ddl.auto">update</property> 这个配置

#Hibernate.hbm2ddl.auto create-drop   //创建,用完之后再删除

#Hibernate.hbm2ddl.auto create  //这个操作会重新创建表

#Hibernate.hbm2ddl.auto update  //会把对象模型的变化,表现在关系模型上

#Hibernate.hbm2ddl.auto validate  //当对象模型和关系模不一样的时候,会发生错误(通常生产环境下用)

、Hibernate  主键生成策略

所有的主键生成器都实现了  org.Hibernate.id.IdentifierGenerator  接口

常用的主键生成器

1) increament: 适合所有的数据库, 由hiberante来维护主键的生成(先查询最大的,再加1), 有线程安全问题,不适合多个进程的情况。用于 long ,short ,int ,生成的是数字型的自增的唯一标识,在集群的情况下不要用实测,在mysql下,无论原来是否设置了自增主键,用它都可以

2) identity:  适合于mysql , mssqlserver 等支持自增主键的数据库,主键不由 Hibernate 来维护,类型是 int, short,long。oracle中不能用 (无法将 NULL 插入 ("SA"."USERINFO"."ID") 这样的异常)

3) sequence: (顺列) 适合于oracle等支持序列的数据库, 主键值不由Hibernate维护。mysql不支持(出现 Dialect does not support sequences 这样的异常), 在 oracle中直接这样写:  <generator class="sequence" /> 它会对所有的表使用同一个序列。

4) native:  和底层数据库的具体特性有关, 如果是mysql或 mssqlserver ,它就会选择 identity, 如果是oracle 它会选  sequence

5) hilo: 高低位 根据 hilo算法 生成主键,支持所有的数据库, 需要一张额外的表生成的表名 默认是 Hibernate_unique_key 里面就一列 next_hi

<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="hilo" >
<param name="table">t_key</param>
<param name="column">f_nextval</param>
<param name="max_lo">100</param>
</generator>
</id>

6) uuid :  Hibernate 来维护的主键 ,支持所有数据库

 <id name="id" >
<column name="id" />
<generator class="uuid" />
</id> //附 用java程序生成uuid => UUID.randomUUID().toString() c6204dc1-b9b6-40a9-a03a-a35ab6e6adc

7) assigned : 主键由用户来维护, 如果选择了这种生成方式,则Hibernate不再帮我们生成主键,主键要由用户。在程序中指定,不指定将出错  ids for this class must be manually assigned before calling save():

四、多对一

//对象模型
//尼姑
public class NiGu {
private int id;
private String fahao; private NiGuAn niguan; // 用的是NiGuAn 对象 这样就建立起了一对多的关联
} //尼姑庵
public class NiGuAn {
private int id;
private String name;
}
//映射文件 (NiGuAn.hbm.xml)
<Hibernate-mapping>
<class name="cat.beans.NiGuAn" >
<id name="id">
<column name="id" />
<generator class="native" />
</id>
<property name="name" />
</class>
</Hibernate-mapping> NiGu.hbm.xml
<Hibernate-mapping>
<class name="cat.beans.NiGu" >
<id name="id">
<column name="id" />
<generator class="native" />
</id>
<property name="fahao" />
<many-to-one name="niguan" column="niguan_id" /> //让它生成的外键这列的名字叫 niguan_id
</class>
</Hibernate-mapping>
//添加的方法
public static void add(){
try{
NiGuAn niguan= new NiGuAn();
niguan.setName("普渡寺"); NiGu nigu=new NiGu();
nigu.setFahao("灭绝师太"); //建立起两对象模型的关联
nigu.setNiguan(niguan); Session s=HibUtil.getSession();
Transaction tx=s.beginTransaction(); s.save(niguan); //先存的是尼姑庵
s.save(nigu); tx.commit(); }
finally{
HibUtil.closeSession();
}
}

总结::

1) 只要对象模型建好了,生成关系模型(数据库表)的时候,也能正确的生成

2) 如果把上面的

s.save(niguan); 反过来写,会多生成一条sql语句,用来维护关联关系

s.save(nigu);

3) 如果不     s.save(niguan); 将出现下面的异常信息

object references an unsaved transient instance - save the transient instance before flushing: cat.beans.NiGuAn

对象引用了一个没有保存的瞬时对象

//查询 

          public static void main(String[] args) {
NiGu nigu=searchNiGu();
System.out.println(nigu.getFahao()); //可以输出结果 /* 被关联的对象,查询的时候默认是使用懒加载的 如果下面的代码中没有
Hibernate.initialize(nigu.getNiguan()); 这句,将引发
could not initialize proxy - no Session */
System.out.println(nigu.getNiguan().getName());
} //关于查询的例二
public static NiGu searchNiGu(){
try{
Session s=HibUtil.getSession();
NiGu nigu= (NiGu) s.get(NiGu.class,1 );
Hibernate.initialize(nigu.getNiguan()); //通知Hibernate 直接把关联的数据查询出来
return nigu;
}finally{
HibUtil.closeSession();
}
} //关于查询的例一
public static void search(){
try{
Session s=HibUtil.getSession();
NiGu nigu= (NiGu) s.get(NiGu.class,1 ); System.out.println(nigu.getFahao());
System.out.println(nigu.getNiguan().getName()); //能否把关联的数据查出来 ? }finally{
HibUtil.closeSession();
}
}

五、一对多

//对象模型
//尼姑庵
public class NiGuAn {
private int id;
private String name; private Set<NiGu>niguList; //一对多关联
}
//映射文件(NiGuAn.hbm.xml)
<Hibernate-mapping>
<class name="cat.beans.NiGuAn" >
<id name="id">
<column name="id" />
<generator class="native" />
</id>
<property name="name" /> <set name="niguList">
<key column="niguan_id" />
<one-to-many class="NiGu" />
</set>
</class>
</Hibernate-mapping>
//映射文件 (NiGuAn.hbm.xml)
<Hibernate-mapping>
<class name="cat.beans.NiGuAn" >
<id name="id">
<column name="id" />
<generator class="native" />
</id>
<property name="name" />
</class>
</Hibernate-mapping> NiGu.hbm.xml
<Hibernate-mapping>
<class name="cat.beans.NiGu" >
<id name="id">
<column name="id" />
<generator class="native" />
</id>
<property name="fahao" />
<many-to-one name="niguan" column="niguan_id" /> //让它生成的外键这列的名字叫 niguan_id
</class>
</Hibernate-mapping>
//添加的方法
public static void add(){
NiGuAn niguan=new NiGuAn();
niguan.setName("少林寺"); NiGu nigu1=new NiGu();
nigu1.setNiguan(niguan);
nigu1.setFahao("空闻"); NiGu nigu2=new NiGu();
nigu2.setNiguan(niguan);
nigu2.setFahao("玄苦"); try{
Session s=HibUtil.getSession();
Transaction tx=s.beginTransaction(); /*
Set<NiGu> niguList=new HashSet<NiGu>();
niguList.add(nigu1);
niguList.add(nigu2); niguan.setNiguList(niguList); */ s.save(niguan);
s.save(nigu1);
s.save(nigu2); tx.commit(); }finally{
HibUtil.closeSession();
} public static void main(String[] args) {
// add();
NiGuAn niguan= search2();
System.out.println(niguan.getName());
for(NiGu n:niguan.getNiguList()){
System.out.println(n.getFahao());
}
} public static NiGuAn search2(){
try{
Session s=HibUtil.getSession();
NiGuAn niguan= (NiGuAn) s.get(NiGuAn.class, 4);
Hibernate.initialize(niguan.getNiguList());
return niguan; }finally{
HibUtil.closeSession();
}
} public static void search(){
try{
Session s=HibUtil.getSession();
NiGuAn niguan =(NiGuAn) s.get(NiGuAn.class, 4); System.out.println(niguan.getName());
Set<NiGu> niguList= niguan.getNiguList();
for (NiGu n:niguList) {
System.out.println(n.getFahao());
} }finally{
HibUtil.closeSession();
}
}

六、使用List 集合的一对多

对象模型中的set 要换成list

 <!-- 把它换成下面的配置即可
<set name="niguList">
<key column="niguan_id" />
<one-to-many class="NiGu" />
</set>
--> <list name="niguList">
<key column="niguan_id" />
<index column="indexNo" />
<one-to-many class="NiGu" />
</list>
//如果对象模型还是使用list,但关系模型中不要排序列,可以用bag 来配置
<bag name="niguList">
<key column="niguan_id" />
<one-to-many class="NiGu" />
</bag>
 //添加方法
public static void add(){
NiGuAn niguan=new NiGuAn();
niguan.setName("九峰寺"); NiGu nigu1=new NiGu();
nigu1.setNiguan(niguan);
nigu1.setFahao("空空大师"); NiGu nigu2=new NiGu();
nigu2.setNiguan(niguan);
nigu2.setFahao("玄玄"); NiGu nigu3=new NiGu();
nigu3.setNiguan(niguan);
nigu3.setFahao("灭绝"); try{
Session s=HibUtil.getSession();
Transaction tx=s.beginTransaction(); List<NiGu> niguList=new ArrayList<NiGu>();
niguList.add(nigu1);
niguList.add(nigu2);
niguList.add(nigu3); niguan.setNiguList(niguList); s.save(niguan);
s.save(nigu1);
s.save(nigu2);
s.save(nigu3); tx.commit(); //说明
/*
List<NiGu> nlist=niguan.getNiguList(); 没有问题
ArrayList<NiGu> nlist=(ArrayList<NiGu> )niguan.getNiguList();
将出现异常 ClassCastException: org.Hibernate.collection.PersistentBag cannot be cast to java.util.ArrayList */ }finally{
HibUtil.closeSession()

七、多对多

//对象模型
public class Student {
private int id;
private String stuName;
private Set<Teacher> teacherList; } public class Teacher {
private int id;
private String teacherName;
private Set<Student> stuList; //建立关联
}
//Teacher.hbm.xml
<Hibernate-mapping package="cat.beans">
<class name="Teacher" >
<id name="id">
<column name="id" />
<generator class="native" />
</id>
<property name="teacherName" />
<set name="stuList" table= "teacher_student" lazy="false"> //指明不要懒加载
<key column="teacher_id" /> <!-- 将来根据 teacher_id列表中间表找学生 -->
<many-to-many class="Student" column="stucent_id" />
</set>
</class>
</Hibernate-mapping>
//Student.hbm.xml
<Hibernate-mapping package="cat.beans">
<class name="Student" >
<id name="id">
<column name="id" />
<generator class="native" />
</id>
<property name="stuName" />
<set name="teacherList" table= "teacher_student">
<key column="student_id" />
<many-to-many class="Teacher" column="teacher_id" />
</set>
</class>
</Hibernate-mapping>
//测试
public static void main(String[] args) {
Teacher t=search(); System.out.println(t.getTeacherName()); for(Student stu:t.getStuList()){
System.out.println(stu.getStuName());
}
} public static Teacher search(){
return (Teacher) HibUtil.get(Teacher.class, 1);
} public static void add(){
//老师的数据
Teacher t1=new Teacher();
t1.setTeacherName("成秀秀"); Teacher t2=new Teacher();
t2.setTeacherName("史老师"); Set<Teacher> teacherList=new HashSet<Teacher>();
teacherList.add(t1);
teacherList.add(t2); //学生的数据
Student stu1=new Student();
stu1.setStuName("刘冰"); Student stu2=new Student();
stu2.setStuName("侯晨阳"); Set<Student> studentList=new HashSet<Student>(); studentList.add(stu1);
studentList.add(stu2); t1.setStuList(studentList); //建立起老师和学生的关联
t2.setStuList(studentList); ///////有没有必要//////
//stu1.setTeacherList(teacherList);
//stu2.setTeacherList(teacherList);
////////////////////// Session s=HibUtil.getSession();
Transaction tx=s.beginTransaction(); s.save(t1);
s.save(t2);
s.save(stu1);
s.save(stu2); tx.commit(); s.close(); }

高低位: 附:它的算法

next_hi * (max_lo + 1) + lo

1. 读取并记录数据库的Hibernate_unique_key表中next_hi字段的值,数据库中此字段值加1 并保存

2. nHibernate取得lo值(从0循环到(max_lo-1),到max_lo的时候,再执行步骤1,然后 lo继续从 0循环到(max_lo-1))

3. 最后根据公式计算主键值。

注意:

所谓的hilo性能比identity好的前提是在同一Session里批量添加记录的时候(id不用每添加一条记录都从数据库里返回);

如果两条记录在不同的Session添加,那么每条记录的id值会相隔32767的差值(max_lo默认值是 32767时)。

由于我们多数都是一条一条记录的添加的,这样如果按 max_lo的默认值32767来生成主键的话,其值很快就会暴增,甚至会出现溢出的可能。

Java框架之Hibernate(二)的更多相关文章

  1. java框架篇---hibernate入门

    Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库. Hibernate可以应用在任何使用JDB ...

  2. JAVA框架:hibernate(二)

    一.事务操作. 代码: @Test public void tr_Up(){ Session session=hibernateUtils.getSession(); Transaction tran ...

  3. Java框架之Hibernate(三)

    本文主要讲解: 1 级联 cascade 关键字 2 级联删除 3 inverse 关键字 4 懒加载 5 缓存的模拟 6 Hibernate 的一级缓存 7 Hibernate 的二级缓存 一.级联 ...

  4. Java框架之Hibernate(一)

    一.Hibernate - 核心接口 它是  JBoss Community team (社区团队) 开发的.Hibernate 是一个开源的,对象关系模型框架 (ORM),它对JDBC进行了轻量的封 ...

  5. java框架篇---hibernate之缓存机制

    一.why(为什么要用Hibernate缓存?) Hibernate是一个持久层框架,经常访问物理数据库. 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能. 缓存内的数据是对物理数 ...

  6. Java框架之Hibernate(四)

    本文主要介绍: 1 悲观锁和乐观锁 2 使用版本号控制并发访问 3 flush方法和批量更新的问题 4 DetachedCriteria 5 N + 1 次查询 6 使用sql进行查询 7 注解方式 ...

  7. JAVA框架之Hibernate框架的学习步骤

    首先介绍一下Java三大框架的关系 以CRM项目即客户关系管理项目示例 hibernate框架的学习路线: 1.学习框架入门,自己搭建框架,完成增删改查的操作 2.学习一级缓存,事物管理和基本查询 3 ...

  8. java框架之Hibernate(1)-简介及初使用

    简介 hibernate 是一个开源 ORM ( Object / Relationship Mipping ) 框架,它是对象关联关系映射的持久层框架,它对 JDBC 做了轻量级的封装,而我们 ja ...

  9. java框架之Hibernate(2)-持久化类&主键生成策略&缓存&事务&查询

    持久化类 概述 持久化:将内存中的对象持久化到数据库中的过程就是持久化.Hibernate 就是用来进行持久化的框架. 持久化类:一个 Java 对象与数据库的表建立了映射关系,那么这个类在 Hibe ...

随机推荐

  1. springMVC学习总结(二)路径映射和请求方法限定

    springMVC学习总结(二)路径映射和请求方法限定 一.路径映射 无参数的访问路径 对springmvc项目的访问路径,是由根路径和子路径组成:在注解式开发中,根路径标注在类名之上,子路径标注在方 ...

  2. HDU 1671 Phone List (Trie)

    pid=1671">Phone List Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

  3. 经典面试题目——250M内存处理10G大小的log文件

    前言 周末逛知乎的时候,看到的一个经典面试题目:http://www.zhihu.com/question/26435483.非常经典的一道分而治之的题目. 题目描写叙述例如以下: 有次面试遇到一个问 ...

  4. 【SqlServer系列】AS的用法

    1   概述 本篇文章简要分析,在SQL SERVER中,AS的基本用法. 2   具体分析 2.1  定义变量类型 )='Alan_beijing' 2.2 取别名 2.2.1 为结果集列取别名 c ...

  5. jersey实现文件下载

    好久没有更新博客了,今天来再次总结一下,之前有整理过关于jersey实现文件上传功能的相关知识,但是前一阵子在实习过程中写接口又要实现文件下载的功能,由于这些东西基本都是使用jersey提供的注解和接 ...

  6. 四.RabbitMQ之发布/订阅(Publish/Subscribe)

    一.基础知识点 在上述章节中,我们理解的RabbitMQ是基于如下这种模式运作的. 而事实上,这只是我们简单化了的模型的结果,真正的模型应该是这样的. P:Producer 生产者,生产消息,把它放进 ...

  7. spring cloud sidecar

    用spring cloud sidecar的整合异构语言,以前做过没有做笔记,现在再做由于各种坑又浪费了一天,这里记一下 首先是官网:http://cloud.spring.io/spring-clo ...

  8. android JSON解析 fastjson和gson的使用

    User user = new User(); user.setPhone("11111111"); user.setNmae("张三"); user.setP ...

  9. 1-MySQL数据库(android连接MySQL数据库)

    很好的链接 http://www.cnblogs.com/best/p/6517755.html  一个小时学会MySQL数据库 http://www.cnblogs.com/klguang/p/47 ...

  10. C#又能出来装个B了。一步一步微信跳一跳自动外挂

    PS:语言只是载体.思维逻辑才是王道 前天看见了个python的脚本.于是装python.配置环境变量.装pip.折腾了一上午,最终装逼失败. 于是进入博客园,顶部有篇文章吸引了我 .NET开发一个微 ...