Hibernate learning detailed (2: HQL practical technology

Hibernate learning detailed (2: HQL practical technology

HQL statement

Hibernate supports three query methods : HQL query Criteria query Native SQL query
HQL query

Hibernate Query Language (Hibernate Query Language) is an object-oriented query language. Unlike SQL (structured query language)
, there is no concept of tables and fields, only the concept of objects and attributes; (this learning direction)
HQL statement form The above is similar to the SQL statement, but there are differences...HQL is object-oriented and can be understood as polymorphism, inheritance and association...

Criteria query Constructs the query in an object-oriented way;
native SQL query directly executes the query of the SQL statement, you can perform special corresponding queries in the SQL statement according to different databases (function sequence, etc...)

Commonly used HQL

注意:
	HQL语句对: Java类和属性区分大小写..!!  对其它大小写不影响;
	
因为:Hibernate中, 对每一个Java实体类已经在数据库中对应了数据库的一个表...
使用HQL查询时, 只需要使用对应的Java类,就相当于是对表的操作.... 

类名相当于表名 类中属性对应表中的列
From
from query all: equivalent to query, all data of the table corresponding to this Java class! ! as or space for alias;
from Java class name
from Java class name as alias
from Java class name alias


Select
select is used to select the column corresponding to the query : select is more special and will be explained later ~
select attribute from class name;
select alias. Attribute 1, alias, attribute 2 from class name alias;


where
clause is used to restrict conditions of expression query : query based on conditions, or non-empty conditions;
from class name where attribute = "";
from class name where attribute is not null;


Expression
expressions are generally used in the where clause...
from class name where lower (character type attribute) = "sadasd"; lower() means that the matching column attribute is not case sensitive...
form class name where year (time type attribute) = "1999"; year() takes out the year of the time type for comparison; there is still a lot to be good at learning...


The order by clause
order by is used to sort by specified attribute (column)
from class name order by attribute desc|asc

Point to HQL

Steps to execute HQL statement

Obtain the Session object and
write the HQL statement
Create the Query object to
execute the query and get the query result: The two methods provided in Hibernate are the list() and iterate() of the Query object;

Key code : Example Demo> hibernate realizes adding, deleting, modifying, checking and writing
DeptDao.java

//list方法
	public void queryList(){
    
    
		//获取Session对象
		Session session = hibernateUtil.openSession();
		//编写 HQL语句
		String hql = "from Dept";
		//创建Query对象
		Query query = session.createQuery(hql);
		//执行查询,得到查询结果: Hibernate中提供两种方式都是Query对象的 list() 和 iterate();
		List<Dept> list = query.list();
		//关闭资源
		hibernateUtil.closeSessionn(session);
		//遍历结果
		for (Dept dept : list) {
    
    
			System.out.println(dept);
		}
	}

//iterate方法
	public void queryiterate(){
    
    
		//获取Session对象
		Session session = hibernateUtil.openSession();
		//编写 HQL语句
		String hql = "from Dept";
		//创建Query对象
		Query query = session.createQuery(hql);
		//执行查询,得到查询结果: Hibernate中提供两种方式都是Query对象的 list() 和 iterate();
		Iterator<Dept> Iterator = query.iterate(); 
		//遍历iterate 迭代器;
		while(Iterator.hasNext()){
    
    			
			Dept dept = Iterator.next();
			System.out.println(dept);
		}
		//关闭资源: iterate()属于懒加载最后关闭!! 
		hibernateUtil.closeSessionn(session);
	}
//自主在Test.java类中测试

The difference between list() and iterate():

They are all implemented query methods of hibernate, according to the From class name; return the corresponding generic type;
list() return list<> collection;
iterate() return Iterator<> iterator; (requires some understanding of iterators~)
iterate () belongs to 懒加载, and the query method of iterate() is different from list().
list() executes Hql at a time and the result set is stored in list(); query once;
iterate() will first obtain the corresponding primary key value from the database , Query the corresponding data one by one according to the primary key! ! Iterate() has the advantage of querying multiple times
, it will cache data, so it is not recommended to use it once. For frequently queried data, consider iterate()...

Bind parameters in HQL statements

Haha, how do you like the parameters?
Do you stitch parameters in HQL?

	public void CS(String name){
    
    
		//省略...
		String hql = "from Dept where dname='"+name+"'";
		//省略...
	}

It is indeed feasible, but not good, low performance, and unsafe, consider SQL injection... Solution↓↓↓↓

Hibernate provides two ways of parameter binding, using placeholders,
binding
by parameter position, binding by parameter name
DeptDao.java

//根据dname 查询();
	public void query(String dname) {
    
    
		Session session = hibernateUtil.openSession();
		//定义hql
		//String hql = "from Dept where dname like ?";		//	?占位符
		String hql = "from Dept where dname like :dname";	//	起别名形式
		
		Query query = session.createQuery(hql);
		
		//query.setString(0,dname);						 //	?占位符: 	setxxx(int,xxx类型);		int对于占位符的下标 0开始,Obejct对应的值;
		query.setString("dname", "%"+dname+"%");		//	起别名形式:  setxxx(String,xxx类型);	String对应的别名,Objetc对应的值;
		
		List<Dept> list = query.list();
		hibernateUtil.closeSessionn(session);
		for (Dept dept : list) {
    
    
			System.out.println(dept);
		}
	}

//对于多个参数还可以使用Object[] 来进行处理...
	public void queryall(Object[] ob) {
    
    
		Session session = hibernateUtil.openSession();
		//定义hql
		String hql = "from Dept where dname like ? and loc like ?";		//	?占位符
		Query query = session.createQuery(hql);
		//通过遍历Object[] 集合数组形式来完成占位符的赋值...
		if(ob!=null && ob.length>0){
    
    
			for (int i = 0; i < ob.length; i++) {
    
    
				query.setParameter(i,ob[i]);		//根据数组下标,0开始,且Object可以是所有类型; 
			}
			//setParameter(int,Object);	 根据占位符下标.完成占位符赋值..
		}
		List<Dept> list = query.list();
		hibernateUtil.closeSessionn(session);
		//遍历结果...
		for (Dept dept : list) {
    
    
			System.out.println(dept);
		}
	}
//setParameter(int,Object); 	可以通过下标来给占位符赋值;
//setParameter(String,Object);	其实也有根据别名来完成赋值的方法,但是并不是很方便遍历(别名和值两个数组进行遍历..)...而Hibernate有更好的方法: setProperties(Object);
	public void queryPoroerties(Dept dept){
    
    
		Session session = hibernateUtil.openSession();
		//定义hql
		String hql = "from Dept where dname like :dname";	//使用别名进行赋值,这里使用对象所以 别名必须要和类的属性名对应!!
		Query query = session.createQuery(hql);
		//setProperties(类对象类型); 
		query.setProperties(dept);							//使用对象直接进行赋值...注意hql别名要和属性名对应!
		
		List<Dept> list = query.list();
		hibernateUtil.closeSessionn(session);
		for (Dept d : list) {
    
    
			System.out.println(d);
		}
	}

Test.java

		DeptDao ddDao = new DeptDao();
//		ddDao.query("");

//		Object[] ob = new Object[2];
//		ob[0]="%%";			//因为数值太少就啥也不填了,模糊查询直接写%号
//		ob[1]="%%";		
//		ddDao.queryall(ob);
		
		Dept dept = new Dept();
		dept.setDname("%%");
		ddDao.queryPoroerties(dept);

Hibernate provides two ways of parameter binding : Binding by parameter position and binding by parameter name
setXXX(): for specific data types
setXXX(int position, XXX type value); for? Placeholder subscript assignment...
setXXX( int position, XXX type value); Assign a value for the designated alias...
setParameter(): any type parameter
setParameter( int position, Object value); for? Placeholder subscripts for assignment... You can set the value as an Object[] for traversal...
setParameter( String name, Object value); For assigning aliases, for assignment... It is not very convenient to traverse Hibernate to provide methods: setProperties(Object);
setProperties ():
setProperties(Obeject) is customized for named parameters ; the parameter is an object type, when using the object property name as an alias for assignment operation...
setProperties(Map); Map is in the form of a key-value pair, and the key is used as an alias parameter Execute with Hql
... There are many others good at discovering

Realize dynamic query

Dynamic SQL has
been learned when learning Mybatis before, and different SQL statements are executed according to the provided conditional judgments, and different results are generated;
the program has a certain optimization ~ high versatility...
Dynamic SQL can be implemented in Hibernate

DeptDao.java

//动态sql
//根据输入的dname模糊查询如果没输入就查全部	
	public void queryD(Dept dept){
    
    
		Session session = hibernateUtil.openSession();
		String hql = "from Dept where 1=1";		// where 1=1方便后面拼接条件的 and/or;
		//动态条件判断
		if(dept.getDname()!=null && dept.getDname().length()>0){
    
    
			hql+=" and dname like :dname";	//空一格 拼接小细节~ dname注意对象中要存在对应属性名哦~
		}
		//将拼接好的 HQL进行执行;
		Query query = session.createQuery(hql);
		query.setProperties(dept);	//直接进行赋值...
		
		List<Dept> list = query.list();
		hibernateUtil.closeSessionn(session);
		for (Dept d : list) {
    
    
			System.out.println(d);
		}
	}	

Test.java

		Dept dept = new Dept();
		dept.setDname("%人%");
		ddDao.queryD(dept);

Although the above example is very tasteless! But it's probably so...

Query接口方法uniqueResult() unique result and pagination;

Use uniqueResult(); to obtain a unique result:

Compared with list iterate, it is the returned collection type; and it is not suitable for returning a collection of data that only returns one item;
* uniqueResult(); the return value is Object type;
for only one record that is returned, you can use... The mandatory type in progress Conversion. This method is more suitable than returning a collection!

DeptDao.java

	public void queryUnique(){
    
    
		Session session = hibernateUtil.openSession();
		String hql = "select count(*) from Dept";
		Query query = session.createQuery(hql);
		Long count = (Long)query.uniqueResult();
		hibernateUtil.closeSessionn(session);
		System.out.println("总共"+count+"条数据");
	}

Pagination

In the previous learning process:
paging needs to use complex SQL statements to achieve, the most important thing is that the paging methods for different databases are different;
Mysql's limit SqlServer's top Oracle's rownum
Hibernate provides:
setFirstResult(): Set the number from Start
setMaxResults(): Set the maximum number of records to read. It's
a bit similar to mysql's limit...

DeptDao.java

//模拟分页
	public  void queryPage(Integer dye,Integer hang){
    
    	//dye当前页   hang每页行数;
		Session session = hibernateUtil.openSession();
		String hql = "from Dept";
		Query query = session.createQuery(hql);
		//对于分页,以下代码应该都了解不详细介绍了...
		//设置结果集中的起始位置
		query.setFirstResult((dye-1)*hang);
		//设置所需的数据数;
		query.setMaxResults(hang);			//如果不指定所需行数则是后面所有数据....
	
		List<Dept> depts = query.list();
		hibernateUtil.closeSessionn(session);
		//遍历集合..
		for (Dept dept : depts) {
    
    
			System.out.println(dept);
		}
	} 
	

Test.java

ddDao.queryPage(1,2);		//单纯调用方法();

Use projection

Sometimes data display does not need all the attributes of the object, but only one or a few attributes in the object;
or some results must be obtained through expressions and aggregate functions... You can use projection
投影使用的是HQL的Select语句而不是 from for projection, the query result will be There will be three situations;

DeptDao.java

/*投影
 * 	当查询结果仅包含一个结果列,每个结果将作为一个Object的对象返回;
 * 	当查询结果不止一个结果列	,每个结果将作为一个Object[]的数组返回;
 * 	还可以使用 类的构造函数	,类确定每次返回的对象类型;
 * */
	public void query1() {
    
    
		Session session = hibernateUtil.openSession();
		String hql = "select dname from Dept";				//查询Dept2表的所有dname名;
		Query query = session.createQuery(hql);
		//因为返回只有一个列Object类型,定义为 String字符类型可以代表很多...
		List<String> list = query.list();	
		hibernateUtil.closeSessionn(session);
		//遍历
		for (String string : list) {
    
    
			System.out.println(string);
		}
	}

	public void query2() {
    
    
		Session session = hibernateUtil.openSession();
		String hql = "select dname,loc from Dept";				//查询Dept2表的所有dname名 和 loc ;
		Query query = session.createQuery(hql);
		//因为返回有多个列Object[]类型;
		List<Object[]> list = query.list();	
		hibernateUtil.closeSessionn(session);
		//遍历
		for (Object[] objects : list) {
    
    
			System.out.println(objects[0]+""+objects[1]);
		}
	}

	public void query3() {
    
    
		Session session = hibernateUtil.openSession();
		String hql = "select new Dept(dname,loc) from Dept";	//根据类的构造函数进行返回对应类型对象;	
		Query query = session.createQuery(hql);
		//使用类的构造进行查询,将返会的是 对应类型的集合...
		List<Dept> list = query.list();	
		hibernateUtil.closeSessionn(session);
		//遍历
		for (Dept dept : list) {
    
    
			System.err.println(dept);
		}
	}

Test.java

//调用各个查询语句;
		ddDao.query1();
		ddDao.query2();
		ddDao.query3();

注意别忘了实体类还需要的有参构造 **Dept.java**

	//为投影查询,返回对象类型提供的有参构造
	public Dept(String dname, String loc) {
    
    
		super();
		this.dname = dname;
		this.loc = loc;
	}

Guess you like

Origin blog.csdn.net/qq_45542380/article/details/109352461