HQL的使用及封装的操作数据的工具类

package com.hsp.util;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

//在使用hibernate开发项目,请一定保证只有一个SessionFactory
//一个数据库对应一个SessionFactory 对象.
final public class MySessionFactory {

	private static SessionFactory sessionFactory=null;
	
	private MySessionFactory(){
		
	}
	
	static{
		
		sessionFactory =new Configuration().configure("com/hsp/config/hsp.cfg.xml").buildSessionFactory(); 
		System.out.println("sessionFactory 类型"+sessionFactory);
	}
	
	public static SessionFactory getSessionFactory(){
		return sessionFactory;
	}
	
}
package com.hsp.view;
//这是未使用工具类的操作数据库


import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.hsp.util.HibernateUtil;
import com.sina.domain.Studcourse;
import com.sina.domain.Student;

public class TestMain {

	public static void main(String[] args) {
		
		//这我们举例说明hql使用
		Session session=null;
		Transaction tx=null;
		try {
			session=HibernateUtil.getCurrentSession();
			tx=session.beginTransaction();
			//比如,显示所有学生的性别和年龄.
			Query query=session.createQuery("from Student where sdept=? and sage>?");
			
			query.setString(0, "计算机系");
			query.setString(1, "2");
			List  list=query.list();
			for(int i=0;i list=session.createQuery("from Student where sdept not in ('计算机系','外语系')").list();
			//取出1. for 增强
			for(Student s:list){
				System.out.println(s.getSname()+" "+s.getSaddress()+" "+s.getSdept());
			}
			*/
			//显示各个系的学生的平均年龄
		/*	List list=session.createQuery("select avg(sage),sdept from  Student group by sdept").list();
			//取出1. for 增强
			for(Object[] obj:list){
				System.out.println(obj[0].toString()+" "+obj[1].toString());
			}*/
			
			//having的使用
			//1.对分组查询后的结果,进行筛选:比如请显示人数大于3的系名称
			//a. 查询各个系分别有多少学生.
			
	/*		List list=session.createQuery("select count(*) as c1,sdept from  Student group by sdept having count(*)>3").list();
			//取出1. for 增强
			for(Object[] obj:list){
				System.out.println(obj[0].toString()+" "+obj[1].toString());
			}*/
			
			//2查询女生少于200人的系
			//a.查询各个系的女生有多个个
		/*	List list=session.
			createQuery("select count(*) as c1,sdept from  Student where ssex='F' group by sdept").list();
			//取出1. for 增强
			for(Object[] obj:list){
				System.out.println(obj[0].toString()+" "+obj[1].toString());
			}*/
			
			//		1.查询计算机系共多少人?->如果我们返回的是一列数据
			//这时我们的取法是直接取出list->object 而不是 list->Object[]
	/*		List list=session.
			createQuery("select sage from  Student where sdept='计算机系'").list();
			//取出1. for 增强
			for(Object obj:list){
				System.out.println(obj.toString());
			}*/
//					2.查询总学分是多少?
/*			List list=session.
			createQuery("select sum(grade) from Studcourse").list();
			//取出1. for 增强
			for(Object obj:list){
				System.out.println(obj.toString());
			}*/
//					3.查询选修11号课程的最高分和最低分.
/*			List list=session.
			createQuery("select 11,max(grade),min(grade) from Studcourse where course.cid=11").list();
			//取出1. for 增强
			for(Object[] obj:list){
				System.out.println(obj[0].toString()+" max="+obj[1].toString()+" min="+obj[2].toString());
			}*/
			//4.显示各科考试不及格学生的名字(Student-student),科目(Course-course)和分数(Studcourse-studcourse)
			
		/*	List list=session.
			createQuery("select student.sname,course.cname,grade from Studcourse where grade>=60").list();
			//取出1. for 增强
			for(Object[] obj:list){
				System.out.println(obj[0].toString()+" "+obj[1].toString()+" "+obj[2].toString());
			}*/
			
			//计算各个科目不及格的学生数量.(学生练习!)
			
			/*List list=session.
			createQuery("select count(*),student.sdept from Studcourse where grade<60 group by student.sdept").list();
			//取出1. for 增强
			for(Object[] obj:list){
				System.out.println(obj[0].toString()+" "+obj[1].toString());
			}*/
			
			//请按照学生的年龄从小->大,取出第3到第5个学生
		/*	List list=session.createQuery
			("from Student  order by sage").setFirstResult(2)
			.setMaxResults(3).list();
			for(Student s: list){
				System.out.println(s.getSname()+" "+s.getSage());
			}*/
			
			
			
			tx.commit();
			
			
		} catch (Exception e) {
			e.printStackTrace();
			if(tx!=null){
				tx.rollback();
			}
			throw new RuntimeException(e.getMessage());
			// TODO: handle exception
		}finally{
			if(session!=null&&session.isOpen()){
				session.close();
			}
			
		}
		
	}
	
	//分页函数
	private static void showResultByPage(int pageSize){
		//设置分页的变量
		int pageNow=1;
		int pageCount=1;//计算
		int rowCount=1;//这个需要查询
		
		Session session=null;
		Transaction tx=null;
		try {
			session=HibernateUtil.getCurrentSession();
			tx=session.beginTransaction();
			
			//查询出rowcount
			rowCount=Integer.parseInt(session.createQuery("select count(*) from Student").uniqueResult().toString());
			pageCount=(rowCount-1)/pageSize+1;
			
			//现在我们可以循环的显示每页的信息
			for(int i=1;i<=pageCount;i++){
				System.out.println("************第"+i+"页************");
				List list=session.createQuery("from Student").setFirstResult((i-1)*pageSize)
				.setMaxResults(pageSize).list();
				for(Student s: list){
					System.out.println(s.getSname()+" "+s.getSdept());
				}
				
			}
			
			tx.commit();
			
		}catch(Exception e){
			e.printStackTrace();
			if(tx!=null){
				tx.rollback();
			}
			throw new RuntimeException(e.getMessage());
		}finally{
			if(session!=null&&session.isOpen()){
				session.close();
			}
		}
		
	}
	

	private static void query2() {
		//这我们举例说明hql使用
		Session session=null;
		Transaction tx=null;
		try {
			session=HibernateUtil.getCurrentSession();
			tx=session.beginTransaction();
			//hql
			//1.检索的学生名字和所在系
			//原则: 在讲解jdbc我们曾说过, 要查询什么字段就查询什么字段,不要select * from 表
			//但是在hibernate ,我们其实可以不遵循这个规则,建议我们把整个对象的属性都查询
			//这里我们还是要讲解如何取出部分属性
			
			
			List list=session.createQuery("select sname,sdept from Student").list();
			
			for(int i=0;i list=session.createQuery("from Student").list();
			//取出1. for 增强
			for(Student s:list){
				System.out.println(s.getSname()+" "+s.getSaddress());
			}
			System.out.println("*****************");
			//2. 使用iterator
			Iterator iterator=list.iterator();
			while(iterator.hasNext()){
				Student s=iterator.next();
				System.out.println(s.getSname()+" "+s.getSage());
			}
			
			tx.commit();
			
		} catch (Exception e) {
			e.printStackTrace();
			if(tx!=null){
				tx.rollback();
			}
			throw new RuntimeException(e.getMessage());
			// TODO: handle exception
		}finally{
			if(session!=null&&session.isOpen()){
				session.close();
			}
			
		}
	}
}

package com.hsp.util;
import java.util.List;

//这是工具类

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
final public class HibernateUtil {
	private static SessionFactory sessionFactory=null;
	//使用线程局部模式
	private static ThreadLocal threadLocal=new ThreadLocal();
	private HibernateUtil(){};
	static {
		sessionFactory=new Configuration().configure().buildSessionFactory();
	}
	
	//获取全新的全新的sesession
	public static Session openSession(){
		return sessionFactory.openSession();
	}
	//获取和线程关联的session
	public static Session getCurrentSession(){
		
		Session session=threadLocal.get();
		//判断是否得到
		if(session==null){
			session=sessionFactory.openSession();
			//把session对象设置到 threadLocal,相当于该session已经和线程绑定
			threadLocal.set(session);
		}
		return session;
		
		
	}
	
	//统一的一个修改和删除(批量 hql) hql"delete upate ...??"
	public static void executeUpdate(String hql,String [] parameters){
		
		Session s=null;
		Transaction tx=null;
		
		try {
			s=openSession();
			tx=s.beginTransaction();
			Query query=s.createQuery(hql);
			//先判断是否有参数要绑定
			if(parameters!=null&& parameters.length>0){
				for(int i=0;i0){
				for(int i=0;i0){
				for(int i=0;i


 
  


package com.hsp.view;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;

import com.hsp.util.*;
import com.sina.domain.Course;
import com.sina.domain.Studcourse;
import com.sina.domain.Student;
public class TestMain2 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//这里我们使用增强的HibernateUtil来完成curd.
	/*	String hql="select sname,saddress from Student where sdept=? and sage>?";
		String parameters[]={"计算机系","3"};
		List list= HibernateUtil.executeQuery(hql,parameters);
		for(Object[] s: list){
			System.out.println(s[0].toString()+" "+s[1].toString());
		}*/
		
		//使用工具分页
	/*	String hql="select sname,saddress from Student order by sage";
		String parameters[]=null;
		List list= HibernateUtil.
		executeQueryByPage(hql, parameters, 2, 3) ;
		for(Object[] s: list){
			System.out.println(s[0].toString()+" "+s[1].toString());
		}*/
		
		/*添加*/
	/*	Course c=new Course();
		c.setCname("servlet");
		c.setCid(4L);
		HibernateUtil.save(c);*/
		
		//调用修改/删除
	/*	String hql="update Student set sage=sage+1 where sdept=?";
		String parameters[]={"计算机系"};
		try {
			HibernateUtil.executeUpdate(hql, parameters);
		} catch (Exception e) {
			System.out.println(e.getMessage());
			// TODO: handle exception
		}*/
		//请显示所有选择了21号课程的学生信息
	/*	String hql="select student.sname,student.sdept from Studcourse where course.cid=?";
		String parameters[]={"21"};
		List list=HibernateUtil.executeQuery(hql, parameters);
		for(Object[] s:list){
			System.out.println(s[0].toString()+" "+s[1].toString());
		}*/
		
	/*	String hql="from Studcourse where course.cid=21";
		List list=HibernateUtil.executeQuery(hql, null);
		//懒加载我们有一个章节详解.
		for(Studcourse sc:list){
			System.out.println(sc.getGrade()+sc.getStudent().getSname());
		}*/

		//查询年龄大于10岁的学生 criteria
		
		Session s=HibernateUtil.getCurrentSession();
		Transaction tx=s.beginTransaction();
		Criteria cri=s.createCriteria(Student.class);
		//添加检索条件
		cri.add(Restrictions.gt("sage", new Long(10)));
		List list=cri.list();
		for(Student s1: list){
			System.out.println(s1.getSname());
		}
		
		tx.commit();
	}

}

数据库语句,是采用oracle 
--建立学生表
create table student
(sid number primary key , --这是学生的学号
sname varchar2(45) not null, --学生姓名
ssex  char(2) not null,--性别
sdept varchar2(10) not null, --所在系
sage  number(3) ,--年龄
saddress varchar2(45) --住址
)

--学生表中的数据
insert into student values(20040001,'林青霞','F','计算机系',22,'上海');
insert into student values(20040002,'刘德华','M','外语系',23,'南京');
insert into student values(20050003,'成龙','M','化学系',21,'山东');
insert into student values(20050004,'林可欣','F','计算机系',22,'北京');
insert into student values(20050005,'周华健','M','生物系',24,'山东');
insert into student values(20050006,'周润发','M','数学系',20,'湖北');

--建立课程表
create table course
(
cid number primary key ,--这是课程号
cname varchar2(50) not null,--课程名
ccredit number(3) --课程学分
)

insert into course values(11,'java编程',6);
insert into course values(21,'c++课程',4);
insert into course values(31,'oracle',3);
insert into course values(41,'javaEE',100);
insert into course values(51,'linux',1);


--建立选课表
create table studCourse
(
stuCourseId number primary key ,--这是一个自增的,表示一次选课
sid number  references student(sid),--学生号
cid number references course(cid),--课程号
grade number not null--成绩
)


--初始化数据
insert into studCourse values(stucourse_seq.nextval,20040001,11,90);
insert into studCourse values(stucourse_seq.nextval,20040001,21,19);
insert into studCourse values(stucourse_seq.nextval,20050003,21,45);
insert into studCourse values(stucourse_seq.nextval,20050004,41,99);
insert into studCourse values(stucourse_seq.nextval,20050006,11,39);


 
  



我们现在使用hibernate工具,自动生成 domain 对象 和映射文件,如果我们的表有主外键的关系,则应当先映射主表,再映射从表

 

* uniqueResult方法

如果我们检索一个对象,明确知道最多只有一个对象,则建议使用该方法:

具体用法如下:

Student s=(Student)session.createQuery("from Student wheresid='20050003'").uniqueResult();

                     System.out.println(s.getSname());

*distinct的用法

过滤重复的记录

//比如,显示所有学生的性别和年龄.

                     Listlist=session.createQuery("select distinct sage,ssex fromStudent").list();

                     for(inti=0;i

                            Object[]  objs=(Object[]) list.get(i);

                            System.out.println(objs[0].toString()+""+objs[1].toString());

                     }

*between and..

List list=session.createQuery("selectdistinct sage,ssex,sname from Student where sage between 20 and22").list();

                     for(inti=0;i

                            Object[]  objs=(Object[]) list.get(i);

                            System.out.println(objs[0].toString()+""+objs[1].toString()+objs[2].toString());

                     }

*in /not in

//查询计算机系和外语系的学生信息

                    

                     Listlist=session.createQuery("from Student where sdept in ('计算机系','外语系')").list();

                     //取出1. for 增强

                     for(Students:list){

                            System.out.println(s.getSname()+""+s.getSaddress()+" "+s.getSdept());

                     }

*group by使用

//显示各个系的学生的平均年龄

Listlist=session.createQuery("select avg(sage),sdept from  Student group by sdept").list();

                     //取出1. for 增强

                     for(Object[]obj:list){

                            System.out.println(obj[0].toString()+""+obj[1].toString());

                     }

 

 

//having的使用

                     //1.对分组查询后的结果,进行筛选:比如请显示人数大于3的系名称

                     //a.查询各个系分别有多少学生.

                    

                     Listlist=session.createQuery("select count(*) as c1,sdept from  Student group by sdept havingcount(*)>3").list();

                     //取出1. for 增强

                     for(Object[]obj:list){

                            System.out.println(obj[0].toString()+""+obj[1].toString());

                     }

//2查询女生少于200人的系

                     //a.查询各个系的女生有多个个

                     Listlist=session.

                     createQuery("selectcount(*) as c1,sdept from  Student wheressex='F' group by sdept").list();

                     //取出1. for 增强

                     for(Object[]obj:list){

                            System.out.println(obj[0].toString()+""+obj[1].toString());

                     }

//1.查询计算机系共多少人?->如果我们返回的是一列数据

                     //这时我们的取法是直接取出list->object 而不是 list->Object[]

                     Listlist=session.

                     createQuery("selectsage from  Student where sdept='计算机系'").list();

                     //取出1. for 增强

                     for(Objectobj:list){

                            System.out.println(obj.toString());

                     }

3.查询选修11号课程的最高分和最低分.

                     Listlist=session.

                     createQuery("select11,max(grade),min(grade) from Studcourse where course.cid=11").list();

                     //取出1. for 增强

                     for(Object[] obj:list){

                            System.out.println(obj[0].toString()+"max="+obj[1].toString()+" min="+obj[2].toString());

                     }

//计算各个科目不及格的学生数量.(学生练习!)

                    

                     Listlist=session.

                     createQuery("selectcount(*),student.sdept from Studcourse where grade<60 group by student.sdept").list();

                     //取出1. for 增强

                     for(Object[]obj:list){

                            System.out.println(obj[0].toString()+""+obj[1].toString());

                     }

参数绑定案例 (jdbc->PreparedStatement setXXX)

使用参数绑定的好处有3:

1.      可读性提高, 2 效果高 3,防止 sql注入漏洞

? 面试题: 如果不使用参数绑定,怎样防止登录时, sql注入?

name password  

思路: 1. 通过用户名,查询出该用户名在数据库中对应的密码,然后再与用户输入的秘密比较,如果相等,则用户和法,否则,非法.

 

参数绑定有两种形式

Query q=session.createQuery(from Studentwhere sdept=:dept and sage>:age)

 

如果我们的参数是 :冒号形式给出的,则我们的参数绑定应当这样:

Listlist=session.createQuery("from Student where sdept=:a1 andsage>:sage")

                     .setString("a1","计算机系").setString("sage","2").list();

还有一种形式:

Query q=session.createQuery(from Studentwhere sdept=? and sage>?)

如果我们的参数是以 ? 形式给出的则,参数绑定应当:

Listlist=session.createQuery("from Student where sdept=? and sage>?")

                     .setString(0,"计算机系").setString(1,"2").list();

 

参数的绑定,可以分开写:形式如下:

Query query=session.createQuery("fromStudent where sdept=? and sage>?");

                    

                     query.setString(0,"计算机系");

                     query.setString(1,"2");

                     List list=query.list();

                     for(inti=0;i

                            Students= list.get(i);

                            System.out.println(s.getSname()+""+s.getSage());

                     }

把HibernateUtil升级了

u  在映射文件中得到hql语句

hibernate提供了一种更加灵活的查询方法:

把hql语句配置到 对象关系映射文件,

       22]]>

      

在程序中,我们这样获取并执行:

Listlist=session.getNamedQuery("myquerytest").list();

              System.out.println(list.size());

              Iteratorit=list.iterator();

              while(it.hasNext()){

                     Objectobj[]=(Object[])it.next();

                     System.out.println("n="+obj[0]);

       }

 

hibernate 对象的三种关系:

 

1.      one – to – one : 身份证<--->人

2.      one – to – many  部门 <---> 员工

3.      many-to-one   员工<--->部门

4.      many-to-many  学生<--->老师

 


hibernate开发的三种方式中的:

编写domainobject + 映射文件------> 创建出对应的数据库,

这里我们说明如果要自动的创建出对应的数据库,需要做配置(hibernate.cfg.xml).

create

这里有四个配置值:create , update , create-drop, validate

create : 当我们的应用程序加载hibernate.cfg.xml [ new Configuration().config(); ]就会根据映射文件,创建出数据库, 每次都会重新创建, 原来表中的数据就没有!!!

update: 如果数据库中没有该表,则创建,如果有表,则看有没有变化,如果有变化,则更新.

create-drop: 在显示关闭 sessionFactory时,将drop掉数据库的schema

validate: 相当于每次插入数据之前都会验证数据库中的表结构和hbm文件的结构是否一致

 

l  在开发测试中,我们配置哪个都可以测试,但是如果项目发布后,最好自己配置一次,让对应的数据库生成,完后取消配置,

 

 

u  domain对象的细节:

1.      需要一个无参的构造函数(用于hibernate反射该对象)

2.      应当有一个无业务逻辑的主键属性.

3.      给每个属性提供 get set方法.

4.      在domian对象中的属性,只有配置到了对象映射文件后,才会被hiberante管理.

5.      属性一般是private范围

 

u  对对象关系映射文件的说明

对象关系文件中,有些属性是可以不配,hibernate会采用默认机制,比如

table 值不配,则以类的小写做表名

type不配置,则hibernate会根据类的属性类型,选择一个适当的类型

 

hibernate对象的三种状态,转换图:

HQL的使用及封装的操作数据的工具类_第1张图片

面试图:如果判断一个对象处于怎样的状态?

主要的依据是: 1. 看该对象是否处于session, 2, 看在数据库中有没有对应的记录

瞬时态: 没有session管理,同时数据库没有对应记录

持久态: 有session管理,同时在数据库中有记录

脱管态/游离态: 没有session管理,但是在数据库中有记录.

 

u  懒加载:

简述: 当我们查询一个对象的时候,在默认情况下,返回的只是该对象的普通属性,当用户去使用对象属性时,才会向数据库发出再一次的查询.这种现象我们称为 lazy现象.

解决方法可以这样:

1.      显示初始化 Hibernate.initized(代理对象)

2.      修改对象关系文件 lazy  改写 lazy=false

3.      通过过滤器(web项目)openSessionInView



你可能感兴趣的:(servlet)