java三大框架struts2和hibernate和spring学习笔记.docx
《java三大框架struts2和hibernate和spring学习笔记.docx》由会员分享,可在线阅读,更多相关《java三大框架struts2和hibernate和spring学习笔记.docx(55页珍藏版)》请在冰豆网上搜索。
![java三大框架struts2和hibernate和spring学习笔记.docx](https://file1.bdocx.com/fileroot1/2023-7/6/a142829e-d0c9-4a7f-9e02-1ecb0dc2f4b7/a142829e-d0c9-4a7f-9e02-1ecb0dc2f4b71.gif)
java三大框架struts2和hibernate和spring学习笔记
hibernate学习笔记:
首先了解hibernate的配置文件,hibernate配置文件里面配置了与数据库打交道的一些信息,包括数据源,与一些数据库的相关类的配置,drivermanager等等,还设置了实体类与数据库表的映射,那么,在运行程序的时候,首先就要先加载hibernate的配置文件,整个hibernate的配置文件里面的内容首先包含在hibernate-configuration里面,其次,在hibernateconfiguration里面又包装了一层sessionfactory,那么当获得了hibernate-configuration之后,若要生成相应的实体类的表,就要导出相应的表,配置文件里面也配置了相应的语句,之后,若要对数据库表进行增删改查等操作,在获得了hibernate-configuration之后,就要建立一个相应的sessionfactory,当建立了sessionfactory之后,就要建立与数据库的会话机制,那就是在sessionfactory这个工厂里面打开一个session来保持这个通话。
对数据库进行一些基本的操作。
采用session的load方法加载数据:
采用session的load方式加载数据,参数为相应的实体类,和对应的表中的id主键值,来加载相应的数据。
session的load方法支持一级缓存,也就是session级缓存,当查询上来相应的数据时,如果再接着查询,则首先从session级缓存中查询看有没有相应的数据,如果有,就不去数据库存取,不发相应的sql语句。
第二:
session的load方法支持延迟加载,只有在真正用到数据的时候,load方法才去数据库查询相应的数据只有真正用到数据的时候才发sql语句。
采用session的get方法加载数据
session的get方法首先不支持延迟加载,当执行session的get方法时,不管是否用到数据,get方法都发出sql语句查询相应的数据,加载上来。
同样的session的get方法和load方法一样,都支持一级缓存,都首先去缓存里读数据,如果有的话,直接加载数据,‘如果一级缓存中没有,那么发sql语句,去数据库中查找相应的数据。
在对数据库进行某些变动的处理时,如修改,删除等操作,一定要开启事务,保持数据的一致性
在做删除与修改数据库的时候,一定要开启事务的管理,因为事务保持了数据操作的一致性。
而在查询加载数据的时候,并不需要开启事务,因为加载,查询数据,不对数据进行相应的修改操作无需一致性,而在修改,删除时一定要开启事务,以达到保持数据的一致性。
采用session的createQuery方法加载数据时:
查询单个的属性条件,采用直接根据条件查询,或者采用顺序占位符?
来查询当采取顺序占位符?
时,得调用query的setParameter的方法,其中里面的参数解释为:
第一参数表示的是第一个问号的下标,如果为0,则表示为第一个?
号,第二个参数为?
的实际值,对应的是实体表中的某个字段的值,若第一个?
代表的是id,那么第二个参数则是表中的id字段的某个值这样就能根据具体的值把相应的内容加载上来,这样加载上来的信息为一个list集合。
除了采用顺序占位符才传递参数外,还可以使用引用占位符,引用占位符[:
参数名],也就是给hql语句中的条件中的字段另起个别名而已,之后调用query的setParameter方法,参数表示为:
第一个参数表示hql语句中的条件的别名,第二个参数为别名条件的值。
根据这样就能把相应的数据加载上来。
返回一个list集合
One2one唯一外键关联映射是多对一关联映射的特例可以采用标签,指定多的一端的unique=true,这样就限制了多的一端的多重性为一,通过这种手段映射一对一唯一外键关联
例如一个人对应一个身份证号,在person一端配置
idcard一端无需配置
One2one唯一外键双向关联映射,如上面例子需要在另一端(idcard),添加标签,指示hibernate如何加载
其关联对象,默认根据主键加载person,外键关联映射中,因为两个实体采用的是person的外键维护的关系,
所以不能指定主键加载person,而要根据person的外键加载,所以采用如下映射方式:
person端配置与上面配置一致
one2one单向主键关联映射,只需配置一个文件就可以
以下为例,无论配置user还是idcard,只需按下面的user配置完成即可
one2one双向主键关联映射,配置过程(另外在one2one配置中,不在任何一个表中添加多余的字段)
例如一个user对应一个idcard,那么在user.hbm.xml配置文件中
--另外命名表的名字,不能用Group-->
idcard
因为myeclipse默认了cacsde属性,所以在存储任何一方时,都会自动的把另一方给加载上来
在idcard.hbm.xml配置文件中
--另外命名表的名字,不能用Group-->
many2one单向配置过程与one2many返回来的道理一样
例如user和group,多个用户对应一个组,many2one映射,在user.hbm.xml文件中如下配置:
在group中无需任何配置,其中下面的标签,自动在多的一端添加一个column的值的一个字段
此时也就是在user这个表中添加一个groupid这个字段指向group表的主键
--另外命名表的名字,不能用Group-->
idcard
many2one双向就是反过来的one2many双向,还是以上为例
那么在group中添加一个set集合来容纳user,group.hbm.xml配置文件如下:
--另外命名表的名字,不能用Group-->
many2many,单向映射,配置过程
例如,一个用户user可以拥有多个角色role,那么所以,在user用户一端设置一个set集合用来装载role,又因为是many2many,在前面的one2many中说过,会在many的一端自动添加一个字段来指向one的一端那么对于many2many来说,都是many一端,不存在one的一端,这时就要利用set标签里面的一个table属性来建立一个连接两个many端的中间表,配置如下:
对于单向来说,那么在user一端的配置如下:
--另外命名表的名字,不能用Group-->
idcard
many2many双向映射配置,以上为例,一个user多个role,一个role有多个user,那么在role端也同样存在一个set集合用来装载user,那么role端配置文件的时候,因为role与user要产生一个中间表,所以在set标签里面的table属性值对应一个表里面的字段映射要成为互相映射,也就是,在user一端的set标签里面,key的column为userid,那么在role中的many2many标签中的column为userid成互相对应的状态,反过来一样,所以user配置还跟上面的配置一样,role端的配置如下:
--另外命名表的名字,不能用Group-->
多对多双向关联,由于各自都含有包含对方引用的Set集合,那么在各自的配置文件里面就要配置set这个标签并且set集合里的内容在数据库中生成相应的表,并且在给表命名时,必须双方的名字一样,而且里面的字段也要一样否则的话,关联不上在—————————————————————————————————————————————————————————————————实体查询中的-----统计查询:
hql语句为:
例如查询user里面有多少个元素用户
//Longcount=(Long)session.createQuery("selectcount(*)fromUser").uniqueResult();
Listusers=session.createQuery("selectcount(*)fromUser").list();
Longcount=(Long)users.get(0);
实体查询中的----多个属性查询:
多个属性查询,返回的是个对象数组形式,两个属性组成两个元素的数组
//在获取值的时候,只能是对象数组形式获取,
//也可以在hql语句中直接new一个user对象,把属性id,name传进去
//此时必须在实体类中含有有参数的构造函数,这样,多属性查询返回的就是具体的查得表的对应的实体类对象,
//例如下面的User;
Listusers=session.createQuery("selectid,namefromUser").list();
for(Iteratorite=users.iterator();ite.hasNext();){
Object[]user=(Object[])ite.next();
System.out.println(user[0]+"----"+user[1]);
}
System.out.println("-----------------------------------------------");
Listuserss=session.createQuery("selectnewUser(id,name)fromUser").list();
for(Iteratorite=userss.iterator();ite.hasNext();){
Useruser=(User)ite.next();
System.out.println(user.getId()+"----"+user.getName());
}
实体查询中的--------拼字符串查询:
采用拼字符串形式来查询实体类中的属性值,常用在模糊查询中例如:
查询名字里面带有符号B的所有名字
//采用【%字符%】这种形式来查询表中符合条件的元素,其中在hql语句中采用单引号括起来
Listusers=session.createQuery("selectu.namefromUseruwhereu.namelike'%B%'").list();
for(Iteratorite=users.iterator();ite.hasNext();){
Stringname=(String)ite.next();
System.out.println(name);
}
System.out.println("-----------------------------------------------");
Listuserss=session.createQuery("selectu.id,u.namefromUseruwhereu.namelike'%B%'").list();
for(Iteratorite=userss.iterator();ite.hasNext();){
Object[]user=(Object[])ite.next();
System.out.println(user[0]+"----"+user[1]);
}
System.out.println("-----------------------------------------------");
//采用?
来传递参数,然后调用query的setparameter方法,指定问号的位置是什么值,也可以采用别名来传递参数,如下面例子
Listusersss=session.createQuery("selectu.id,u.namefromUseruwhereu.namelike?
")
.setParameter(0,"%B%")
.list();
for(Iteratorite=usersss.iterator();ite.hasNext();){
Object[]user=(Object[])ite.next();
System.out.println(user[0]+"----"+user[1]);
}
System.out.println("-----------------------------------------------");
//也可以采用别名来传递参数,如下面例子,参数的别名为my,在设置参数时,采用key-value形式来设置相应的参数值
Listuserssss=session.createQuery("selectu.id,u.namefromUseruwhereu.namelike:
my")
.setParameter("my","%B%")
.list();
for(Iteratorite=userssss.iterator();ite.hasNext();){
Object[]user=(Object[])ite.next();
System.out.println(user[0]+"----"+user[1]);
}
System.out.println("-----------------------------------------------");
//也可以采用复合参数别名来传递参数,如下面例子,参数s.name的别名为my,s.id的别名位myid,
//在设置参数时,采用key-value形式来设置相应的参数值
Listusersssss=session.createQuery("selectu.id,u.namefromUseruwhereu.namelike:
myand"+
"u.idlike:
myid")
.setParameter("my","%B%")
.setParameter("myid",1)
.list();
for(Iteratorite=usersssss.iterator();ite.hasNext();){
Object[]user=(Object[])ite.next();
System.out.println(user[0]+"----"+user[1]);
}
实体查询中的--------分页查询:
采用分页查询,把查询的结果进行分页,避免元素多而造成的页面拥挤
//采用分页查询方式,首先调用query的setfirstresult,表明数据从下标为几的元素开始,
//然后调用setmaxresus,表明每页显示多少数据
/*Queryquery=session.createQuery("fromUser");
query.setFirstResult(0);
query.setMaxResults(3);
Listusers=query.list();*/
Listusers=session.createQuery("fromUser").setFirstResult
(1).setMaxResults
(2).list();
System.out.println("-----------------------------------------------");
for(Iteratorite=users.iterator();ite.hasNext();){
Useruser=(User)ite.next(