hibernate学习笔记3

13   hibernate核心java

表和表的关系:mysql

常见有7中关系:sql

单项关系一下四种       数据库

1-1  外键1-1,主键1-1的关系缓存

1-n服务器

n-1session

n-noracle

多项关系:互相使用;框架

1-1eclipse

1-nn-1

n-n

   如下有两个表,user_info、和login连个表。表和字段以下;

User_info

Uid  truename  phone   sex

 

Longin

Lid   longinname  password  uid

这里创建了user类和longin类,同事newuser

User表中不含login字段,可是longin表中有user_info字段,可是在login的类中加入了user应用;

注:a单项外键1-1中第一个表的主键是另一个表的外键,因此在另一个表里,这个外键不受约束能够随便写。为了达到主外键一一对应就用到unique写法以下

<many-to-one name="user" column="uid" not-null="true" class="User" unique="true" cascade="all">

</many-to-one>当把配置文件和类写好就能够自动生成数据库链接表了;

保存的时候:这里先将user先存入进去,由于只有主键先得到持久化才能跟其余表有关系;注意外键配置时候必须不能为空;也就是说user_info是父表,另外的表longin为子表,但查询的时候必须先查询子表,也就是login表,由于user_info表中没有login表中的属性,但login表中有user_info的应用:

//这里只保存了一个关联表被关联的不保存通常会报错,可是有这样的配置就会保存一个表:级联(如:两表经过 id字段创建一对一关系,同时选项上了实施参照完整性”“级联更新相关字段”“级联删除相关记录,目的是实现,当在employee创建新用户时,同时自动在user_right表中给其创建相应的权力记录,但我发现如在employee中新增一个用户时,user_right并无同步增长一条记录,可是在employee中删除一个用户时,user_right中却会同步更新!):cascade(级联)="all"它将配置的关联和被关联的对象共存亡;

多项外键1-1:其它不变就是对象的模型变了,在user表中加入(表名)longin对象字段,也就是双向包含,因此在user配置中加入了<one-to-one name="login"class="Login"property-ref(表示关联对方的属性)="user"></one-to-one>这样保存数据顺序和上一致,可是查询能够是反向和正向,有利于查询

b共享主键关联:能够是主键名不同,但主键值必须同样,也就是关系模型有变化,对象模型则不会变化;

1-1的单项共享主键关联:主键在longin中,因此先建立longin在建立user

           1-1的双项共享主键关联:保存的时候以login的主键为主,因此先保存login:查询则无所谓;

     单项n-1:先保存有主键的对象在保存无主见的对象;<many - to-one></many-to-one>,连个表字段:

                                   T_room                        user

                                   Id  idname            1    ----   n    id  username   rooomid

       双项n-1:数据库不变,只是变对象用到private Set<User> users;,一个循环语句for(User user:users)

     单项1-n:主控权放在1的上面,而n-1主控权在n的一方,因此在1的一方加上引用

                              room  1-------- n    user

        双项1-n:就是在在n的一方加上引用,在user方加上<many -to-one>

                                   注:在1掌控的时候,会发送多余的sql语句(update),因此效率就降低了,因此能够在配置文件中加入inverse=true反转(就是将主控权交给多的一方,false的话就是本身掌控),这时候注意的是操做数据只能从n的一方去操做;而有n掌控时候就不会发多余的;

   n-n的关系:实现的时候须要一个中间表,中间表中有连个字段,它们就是联合主键(联合主键就是这个表里字段值不能同样的,两个字段加起来作一个主键),保存的时候先保存无set的那个对象;映射是<many -to- many>.

                      在双项多对多中要从两个对象中分别查询的话配置xml文件是同样的;(也就是<set>配置)

集合映射:中的例子映射,通常用set设置的值不会有顺序的。而用list设置的值就会有顺序的(这里的list是个接口,不能是arrylist,可是new的时候就得是arrylist),一样的也要修改配置文件

                     

继承映射:将对象的映射关系在表里面体现出来     

1)每一个类分层结构一张表:一个父类无论他有多少子类都将他们与父类数据放入一张表中;

       也就是整个树一张表,subclass表明子类它的名字与类名绑定的,discriminator是个鉴别器这里的type就是鉴别器,是用来识别数据类型的一个字段,

  例子以下:父类是persion,两个子类是studentwork

                Id   name   age     school          factory            type

           1        aaa             55              qinghua                           s

        2   bbb      22                     shuoshuodian        w

   有这张表体能够看出只有学校和工厂才能分清楚他们是什么人,在配置文件中不能加不能为空的判断,这样也有问题,应为的字段能够空,就没有意义

2)每一个子类一张表,对象模型不变,也就是类代码不变,只需修改配置文件(数据模型)

       和以上的类同样因此就作三张表,

T_person

Id     name        age      sex

T_student

Id      school      pid        

T_work

Id       factory     pid

 

 

说明:这里的pid是外键就是personid字段不一样但值相同(也能够去掉pid用共享主键来达到要求)这里所用就是共享主键,从建表看,生成了第三个表达到结果:能够加不能为空的配置

3)每一个具体的类一张表;对象模型仍是不变,变的仍是数据库

例子以下:创建三张表

           T_pserson

 

                          T_studnet

                          Id     name       age     school

                         

                          T_factory

                          Id      name      age     factory  

         说明:这俩个子表的id不能相同 ,用到联合子类,这里产生了person表,可是是空的为了    不让这个表产生能够用abstract =true;这里假如加了不能为空的话,就不能手动的向表中插入数据了; 

-----------------------------------------------------------------------------------------------------------------

HQL讲解

语法:1.实体查询

String hql = " from TUser";

执行这条语句会返回TUser以及TUser子类的纪录。

注: 若是 TUser 类具备外键, 查询会报错!

解决方法: select 别名。属性 from  as 别名。 没有别名。属性仍然报错!

hql = "from java.lang.Object"

会返回数据库中全部库表的纪录。

where 语句

hql = "from TUser as user where user.name='yyy'"

其中,as能够省略也同样

hql = "from TUser user where user.name='yyy'"

where子句中,咱们能够经过比较运算符设定条件,如:= <> > < >= <= between not between in not in islike等。

2.属性查询

List list = session.createQuery("select user.name, user.age from TUser as user").list();

还能够在HQL中动态构造对象实例的方法,将数据封装。

List list = session.createQuery("select new TUser(user.name, user.age) from TUser as user").list();
Iterator it = list.iterator();
while(it.hasNext() ) {
TUser user = (TUser)it.next();
System.out.println(user.getName());
}

可是要注意这里的TUser对象只是对nameage属性的封装,其余状态均未赋值,因此不能用它来进行更新操做。

也能够在HQLSelect子句中使用统计函数

"select count(*) ,min(user.age) from TUser as user"

也可使用distinct关键字来删除重复纪录。

select distinct user.name from TUser as user

3.实体的更新与删除

hibernate 2中须要先查询出实体,设置属性后再保存。

hibernate 3中,提供了更灵活的方式(bulk delete/update

更新:

Query query = session.createQuery("update TUser set age=18 where id=1");
query.executeUpdate();

删除:

session.createQuery("delete TUser where age>=18");
query.executeUpdate();

4.分组与排序

Order by子句:

from TUser user order by user.name, user.age desc

Group by子句和Having子句

"select count(user), user.age from TUser user group by user.age having count(user)>10"

5.参数绑定

经过顺序占位符?来填充参数:

1hibernate 2 中经过session.find方法来填充

session.find("from TUser user where user.name=?", "Erica", Hibernate.STRING);

多个参数的状况:

Object[] args = new Object[] {"Erica", new Integer(20)};
Type[] types = new Type{Hibernate.STRING, Hibernate.INTEGER};
session.find("from TUser user where user.name=? and user.age=?", args, types);

2)经过Query接口进行参数填充:

Query query = session.createQuery("from TUser user where user.name=? and user.age>?");
query.setString(0,"Erica");
query.setInteger(1, 20);

经过引用占位符来填充参数:

String hql = "from TUser where name=:name";
Query query = session.createQuery(hql);
query.setParameter("name","Erica");

甚至能够将查询条件封装为一个

class UserQuery {
private String name;
private Integer age;
//getter and setter
}
String hql = "from TUser where name=:name and age=:age";
Query query = session.createQuery(hql);
UserQuery uq = new UserQuery();
uq.setName("Erica");
uq.setAge(new Integer(20));
query.setProperties(uq); //
会调用里面的getter?
query.iterate();

6.联合查询

也可使用 inner joinleft outer join right out join full join

排列组合:form TUser TAddress

事实上sqlhql除了语法上类似外,差异很大,彻底不是一个概念.这里所操做的都是对象的属性sql是关系数据库查询语言,面对的数据库;hqlHibernate这样的数据库持久化框架提供的内置查询语言,虽然他们的目的都是为了从数据库查询须要的数据,sql操做的是数据库表和字段,而做为面向对象的hql操做的则是持久化类及其属性。hql语句执行后的结果都是对象;

oracle的案例数据库来说解;分别有三个脚本语句文件,将三个脚本文件打开粘贴到oracle中,在dos下按命令User\sqlplus scott to tiger 接着把sql脚本拷贝运行,也就是案 例数据库,分别是建立数据、添加数据、删除冗余数据。

 1 Hibernian中的column属性:们声明从JavaBeanid属性到表的id列的映射. propertyHibernate column属性都有相同的值,咱们原本能够忽略Hibernate column属性,可是为了清晰起见,咱们仍是把column列出来是个特殊的标 .它被用来声明表的主键

2myclipse中能够自动的生成Hibernian配置文件可是手动导包的时候他不会把log4j property文件导入,须要咱们本身去导入,还要在myeclipse中手动导入junit组件

3这种写法:也能够是一种循环for(Object obj:list): 这是一种新的循环遍历集合的方式,冒号前边定义变量,表明集合中当前操做的元素,它的类型是集合中元素的类型,在循环体中直接用。
冒号后边就是一个集合。这种写法比较简单,易于理解。
4当现有表后又文件的时候hql读取表的时候出现的CGLIB错误说明数据表中的字段为空了,必须赋值

5Hql语句的时候可使用myclipse中的HQL编辑器他能够将hql语句自动翻译为sql语句,可是有时候这个编辑器会报错打不开,就要看看工做路径下…data文件的配置,看的是configfile的配置路径和是否可以找到session工厂,还有就是映射文件不能错;

6 hql支持查询对象的别名打点,就能够实现多表查询,还支持左右连接和内联。

7数据表达连接方式:左外连接,右外链接,内链接,全链接

  左外连接:把左边的那个表中不符合条件的字段查出来,右外链接同样

  内链接:发送等值连接条件

  全链接:左右都不符合条件的值都显示出来

   这里的简写id就是对象中的持久化标识,就是配置文件中<id>标签中name的值

With能够在join后面设置条件,createQuery发出的是hql语句,

  支持:子查询+汇集函数,分组查询(分组查询用having加条件:)

8 ROWNUM sql中的函数:限制返回数据的条数(相似游标工做)系统任务这样的函数起始值是1

 因此rownum>某个数字或rownum = 非数字都是 不合法的:可是 能够用rownum<=某个数字

HQL中有这个函数可是没有此功能。用这个也就是查询最大的几个数据,因此也叫TOP n 方法

 

Hibernate中的缓存 一级缓存:session(进程)级别(listireator查询缓存都在)不关闭session的话一直都存在

二级缓存:sessionfactory应用中,是服务器级别的 ,只要网站不关闭就一直存在,通常会在里面放一些不重要的东西

cout*)的时候在hibernate中返回的必定是integerlong版本不一样也会不一样的

原生SQLnetive SQL):

         就是像mysql oracle等本身的一些特性就称做原生sql

 

 

二级缓存只须要查一次数据库,在次操做数据不用去查询了,它会首先找缓存,看看有没有,若是有就直接用,没有的时候在去查!

hibernate中用的都是EHCache,不支持集群,Hibernate的二级缓存是应用服务器级别的,他的最大的好处就是跨session的,把一些不时经常使用不到的数据放到session

                还有一些如SwarmCacheJBoss TreeCache都是企业级的分布式的

配置二级缓存:1首先在hibernate.cfg.xml中的配置

                <property name="cache.use_second_level_cache">true</property>   //开启缓存

                   <propertyname="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>//缓存提供商

              2上述就配置提供了缓存,还要在相应的表中配置缓存

                            <cache usage="read-only"/>

                   3.当这里启用了EHcache的时候就要导入ehcache.xml文件(在hibernate-3.2\etc的包中)这样就不会报错,里面有相应的配置

                4 解释:当查询的时候先从一级缓存中查,而后从二级缓存中查询,若是都查不到的话就会发sql继续查询

相关文章
相关标签/搜索