组件就是对象,组件是对数据和方法的简单封装。
HIBERNATE STRUTS2 SPRING
XML配置和ANNOTATION配置
1. HIBERNATE 是比较流行的ORM框架,提供了优秀的持久化层解决方案
2. 开发步骤:
创建HIBERNATE配置文件
创建持久化类
创建对象-关系映射文件
通过HIBERNATE API 编写访问数据库的代码
读取配置文件(hibernate.cfg.xml)
Configuration configuration=newConfiguration().configure();
创建SessionFactory对象
SessionFactorysessionFactory=configuration.buildSessionFactory();
获取Session对象(getCurrentSession保证用户在访问过程中总是能拿到唯一的一个属于自己的会话)
Sessionsession=sessionFactory.getCurrentSession();
3.HQL查询(hibernate 查询语言)
执行HQL语句: 获得Session对象
编写HQL语句
创建Query 对象
执行查询,得到查询结果
Queryquery=HibernateSessionFactory.getSession().createQuery(“from” + 类名 + where 条件);
动态参数绑定(按参数位置绑定和按参数名字绑定)
Eg: from User u where u.id=? and u.username=? and u.password=?
Orfrom User u where u.id=:id and u.username=:username and u.password=:password;(usernamepassword 为类的属性)
按参数位置:下标从0开始
Eg:query.setInteger(0,1)query.setString(1,”a”),queryt.setString(2,”123”)
For(int i=0 i<params.length;i++){
Query.setParameter(I,params[i]);
}
按参数名字:
Eg:query.setInteger(“id”,1),query.setString(“username”,”a”);
Or query.setProperties(Object),query.setProperties(Map)(会自己调用)
Iterator 查找的是主键的集合
4.分页查询
query.setFirstResult(“?”)设置从第几条开始
query.setMaxResult(“?”) 设置读取最大记录数
query.uniqueResult() 获得唯一对象 返回的是长整型 Long
5.HQL投影查询
投影查询查询的是一个持久化类的一个或多个属性值(不是持久态)
当查询单个属性时,将查询结果封装成Object对象
当查询多个属性时,将查询结果封装成Object[]对象数组
Hql=”select new User(id,username,password)from User”;
通过构造函数封装成对象
执行hql语句采用两种方式:list() 和 iterator()
Hibernate关联映射
1. 单向一对多
Student and Grade
Grade:Set<Student>students=new HashSet<Student>();
<set name=”students”table=”Student” cascade=”” inverse=”” lazy=””>
<keycolumn=”gradeId”/>
<one-to-many class=”po.Student”></one-to-many>
</set>
可以在1的一端的set节点指定 inverse=true来使1的一端放弃维护关联关系cascade 设置在一的一端意义更大点
返回多的一端的集合是Hibernate内置的集合类型,该类型具有延迟加载和存放代理对象的功能
<set>元素的Inverse属性设置为false,则为主动方,有主动方负责维护关联关系,默认为false 一般在一的一端Inverse设置为true,不负责维护关联关系
<set>元素的Order-by属性 order-by=“ename desc”
延迟加载:类级别和关联级别
load:配置文件设置决定(true and false)
get:在类级别上是立即加载,与配置文件无关
关联级别:get and load方法与上一样,当设置为extra时,即调用集合的size/contains等方法的时候,hibernate
并不会去加载整个集合的数据,而是发出一条聪明的SQL语句,以便获得需要的值,只有在真正需要用到这些集合元素对象数据的时候,才去发出查询语句加载所有对象的数据;
在单端关联懒加载策略:即在<one-to-one>/<many-to-one>标签上可以配置,可以取值为false proxy no-proxy(默认,代理延迟,无代理延迟【CGLIB】)
注意:在class标签上配置的lazy属性不会影响到关联对象!!!
2. 单向多对一
Student and Grade
Student: privateGrade grade; setter and getter
<many-to-one name=”grade” class=”po.Grade”>
<column name=”gradeId”></column>
</many-to-one>
推荐:先插入1的一端,在插入多的一端
3. 双向一对多
HQL的连接查询:左外连接、迫切左外连接、内连接、迫切连接、右外连接
不迫切:以数组封装在集合中List<Object[]>
迫切:只需要取其一,另一个绑定
FromDept d left join d.emps e order by d.deptNo
FromDept d left join fetch d.emps e order by d.deptNo
Selectd from Dept d,Emp e where d=e.dept;
隐式内连接
Fromemp e where e.dept.dname=:dname;
Selecte from emp e where e.dept.dname=:dname;
6.命名查询
在映射文件在先定义查询语句给查询语句命名
在标记CDATA下,所有的标记、实体引用都被忽略,而被XML处理程序一视同仁地当做字符数据看待。
Eg:<queryname="testNamedQuery">
<![CDATA[fromDept d left join fetch d.emps e where d.deptNo= :deptNo order by d.deptNo]]>
</query>
在Dao层使用命名查询时HibernateSessionFactory.getSession()..getNamedQuery(命名查询的name);
7.QBC查询(query by criteria)
Criteriacriteria=HibernateSessionFactory.getSession().createCriteria(User.classs,”user”);
List<User> users=criteria.list();
Criteria支持连接查询,主要是左外连接和内连接
单表添加条件查询
Criterion criterion=Restrictions.eq(“location”,”西一区”);
criteria.add(criterion);
List<User> users=criteria.add(Restrictions.eq/gt/lt/ge/le/ilike/like/between/in/isEmpty/isNull/inNotNull/SizeEq/geProperty(“”,””)/not(Restrictions.isEmpty(“’)))
以上条件为and 以下条件为or
.add(Restrictions.disjunction()
.add(Restrictions.条件) .add(Restrictions.条件))
排序
.addOrder(Order.asc(“”))
.addOrder(Order.desc(“”)).list();
关联多表查询
List<User>users=session.createCriteria(User.class)
.createCriteria(“dept”)
Or
List<User>users=session.createCriteria(User.class,”user”)
.createAlias(“dept”,”d”)
左外连接查询
Criteria criteria=session.createCriteria(Dept.class,"d")
.createCriteria("d.emps","e",CriteriaSpecification.LEFT_JOIN);
8.QBC投影查询
查出表中的一部分字段
Org.hibernate.criterion.Projection 接口 和
Org.hibernate.criterion.Projections 类来支持设置条件
List<String>list=session.createCriteria(Dept.class,”dept”)
.setProjection(Property.forName(“dname”)).list();
不能使用两个或两个以上的setProjection
.setProjection(
Projections.projectionList().add(Property.forName(“”))
.add(Property.forName(“”))
).list();
使用投影来实现分组统计功能
criteria.setProjection(
Projections.projectionList().add(Property.forName(“e.dept.deptNo”).group())-à根据部门编号分组
.add(Property.forName(“salary”).max())
.add(Property.forName(“salary”).min())
.add(Property.forName(“salary”).avg())
.add(Property.forName(“empNo”).count())
).addOrder(Order.desc(“”)).list();
或者
Criteria.setProjection(
Projections.projectionList().add(Projections.groupProperty(“e.dept.deptNo”)
.add(Projections.avg(“salary”))
.add(Projections.min(“salary”))
.add(Projections.max(“salary”))
.add(Projections.rowCount())
).addOrder(Order.desc(“”)).list();
9.离线查询
DetachedCriteria 把条件的拼装和会话分离开
DetacheCriteriadc=DetachedCriteria.forName(Dept.class,“d”);
dc.createAlias("d.emps","e",CriteriaSpecification.LEFT_JOIN)
.setProjection(Projections.projectionList()
.add(Projections.groupProperty("d.deptNo"))
.add(Property.forName("e.salary").avg(),"avgSalary"))
.addOrder(Order.asc("avgSalary"));
List list =dc.getExecutableCriteria(Session).list();
10.缓存
缓存介于应用程序和永久性数据存储源之间
使用缓存,可以降低应用程序直接读写永久性数据存储源的频率,提高运行性能
第一级别的缓存是session缓存,属于事务范围的缓存,由hibernate管理,一般情况下无需进行干预
第二级别是sessionFactory的缓存,属于进程范围的缓存,可以被所有的session 共享,二级缓存是可配置的插件
1. 导入jar包
/Hibernate-1/WebContent/WEB-INF/lib/ehcache-1.2.3.jar
2. 设置二级缓存的属性
<propertyname="hibernate.cache.use_second_level_cache">true</property>
<propertyname="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<propertyname="hibernate.cache.use_query_cache">true</property>
3. 缓存插件的配置文件设置
4. 具体的持久化类配置缓存