Hibernate--HQL、QBC以及本地SQl查询

Hibernate中提供了HQL、QBC以及SQL的三种形式查询,HQL查询是一种根据映射文件的便捷查询,只要写部分SQL语句即可。QBC查询则是借助Criteria 进行快捷的查询。SQL查询是基于SQL语句的查询

以下案例用于查询的两个表结构

CREATE TABLE `department` (
  `id` int(2) NOT NULL AUTO_INCREMENT,
  `NAME` varchar(30) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

CREATE TABLE `employee` (
  `Id` int(2) NOT NULL AUTO_INCREMENT,
  `NAME` varchar(30) DEFAULT NULL,
  `SALARY` float(10,2) DEFAULT NULL,
  `EMAIL` varchar(30) DEFAULT NULL,
  `DEPT_Id` int(2) DEFAULT NULL,
  PRIMARY KEY (`Id`),
  KEY `dept_id_fk` (`DEPT_Id`),
  CONSTRAINT `dept_id_fk` FOREIGN KEY (`DEPT_Id`) REFERENCES `department` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;

department实体以及映射文件

public class Department implements java.io.Serializable {

	private static final long serialVersionUID = 1L;
	private Integer id;
	private String name;
	private Set<Employee> employees = new HashSet<>();
}
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- 
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
    <class name="com.zhuojing.hibernate.hql.holleworld.Department" table="department" catalog="hibernate2">
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="identity" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" length="30" />
        </property>
        <set name="employees" inverse="true">
            <key>
                <column name="DEPT_Id" />
            </key>
            <one-to-many class="com.zhuojing.hibernate.hql.holleworld.Employee" />
        </set>
    </class>
</hibernate-mapping>

employee实体以及映射文件

public class Employee implements java.io.Serializable {

	private static final long serialVersionUID = 1L;
	private Integer id;
	private Department department;
	private String name;
	private Float salary;
	private String email;
}
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- 
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
    <class name="com.zhuojing.hibernate.hql.holleworld.Employee" table="employee" catalog="hibernate2">
        <id name="id" type="java.lang.Integer">
            <column name="Id" />
            <generator class="identity" />
        </id>
        <many-to-one name="department" class="com.zhuojing.hibernate.hql.holleworld.Department" fetch="select">
            <column name="DEPT_Id" />
        </many-to-one>
        
        <property name="name" type="java.lang.String">
            <column name="NAME" length="30" />
        </property>
        <property name="salary" type="java.lang.Float">
            <column name="SALARY" precision="5" scale="0" />
        </property>
        <property name="email" type="java.lang.String">
            <column name="EMAIL" length="30" />
        </property>
    </class>
    
    <!-- 配置命名方式检查的 SQL 语句 -->
    <query name="salaryEmp"><![CDATA[FROM Employee e WHERE e.salary > :minSay AND e.salary < :maxSay]]></query>
</hibernate-mapping>

一、HQL

    1.命名参数:

@Test
public void testHQLParameter(){
		
		//1. 创建 Query 对象
		//基于命名参数
		String hql = "FROM Employee e WHERE e.salary > :sal AND e.email LIKE :email";
		Query query = session.createQuery(hql);
		
		//2. 绑定参数
		query.setFloat("sal", 7000)
		     .setString("email", "%com");
		//3. 执行查询
		List<Employee> employees = query.list();
		
		System.out.println(employees.size());
		
	}

2.分页查询

@Test
public void testPageQuery(){
		String hql = "FROM Employee";
		Query query = session.createQuery(hql);
		
		int pageNo = 3;
		int pageSize = 2;
		List<Employee> employees = query.setFirstResult((pageNo -1 )*pageSize)
				                        .setMaxResults(pageSize)
				                        .list();
		System.out.println(employees.toString());
}

3.命名方式:在映射文件中写SQL

//*映射文件
<!-- 配置命名方式检查的 SQL 语句 -->
    <query name="salaryEmp"><![CDATA[FROM Employee e WHERE e.salary > :minSay AND e.salary < :maxSay]]></query>
*/
@Test
	public void testNamedQuery(){
		Query query = session.getNamedQuery("salaryEmp");
		List<Employee> employees = query.setFloat("minSay", 6000)
				                        .setFloat("maxSay", 10000)
				                        .list();
		System.out.println(employees.size());
	}

4.查找部分属性

@Test
public void testFieldQuery(){
		String hql = "SELECT e.name, e.email, e.department FROM Employee e WHERE e.department = :dept";
		
		Query query = session.createQuery(hql);
		Department department = new Department();
		department.setId(3);
		List<Object[]> objects = query.setEntity("dept", department).list();
		for(Object[] obj : objects){
			System.out.println(Arrays.asList(obj));
		}
}

5.查找部分属性,返回结果为一个实体类:实体类需要提供对应的构造方法

@Test
public void testFieldQuery2(){
		String hql = "SELECT new Employee(e.name, e.email, e.department) FROM Employee e WHERE e.department = :dept";
	
		Query query = session.createQuery(hql);
		Department department = new Department();
		department.setId(3);
		
		List<Employee> employees = query.setEntity("dept", department).list();
		
		for(Employee employee : employees){
			System.out.println(employee);
		}
	}

6.迫切左外连接:使用LEFT JOIN FETCH 进行迫切左外连接

用于:查询一个实体的一个实体类的成员变量时,不会在使用 SQL 语句去查询,在第一次就将结果初始化好

@Test
public void testLeftJoinFetch(){
		String hql = "FROM Department d LEFT JOIN FETCH d.employees";
		Query query = session.createQuery(hql);
		
		List<Department> departments = query.list();
		departments = new ArrayList<>(new LinkedHashSet<>(departments));
		for(Department department : departments){
			System.out.println(department.getName() +"--"+department.getEmployees().size());
		}
	}

7.左外连接

@Test
public void testLefJoin(){
		String hql = "SELECT DISTINCT d FROM Department d LEFT JOIN d.employees";
		Query query = session.createQuery(hql);
		
		List<Department> departments = query.list();
		
		for(Department department : departments){
			System.out.println(department.getName() +"--"+department.getEmployees().size());
		}
		
	}

二、QBC查询主要使用Criteria进行查询

  1.QBC的HelloWorld

@Test
	public void testQBC(){
		//创建一个 Criteria 对象
		Criteria criteria = session.createCriteria(Employee.class);
		
		//2.添加查询条件:在QBC 中查询条件使用 Criterion 表示
		// Criterion 可以通过Restrictions 的静态方法得到
		criteria.add(Restrictions.eq("email", "bb@zhuoojing.com"));
		criteria.add(Restrictions.ge("salary", 6000F));
		
		//3.执行查询
		Employee employee = (Employee)criteria.uniqueResult();
		System.out.println(employee);
	}

2.QBC 统计查询:


	@Test
	public void testQBC3(){
		Criteria criteria= session.createCriteria(Employee.class);
		//统计查询:使用 Projection 来表示:可以由 Projections 的静态方法得到
		criteria.setProjection(Projections.max("salary"));
		
		//Employee employee = (Employee)criteria.uniqueResult();
		System.out.println(criteria.uniqueResult());
	}

3.排序和分页

@Test
public void testQBC4(){
		Criteria criteria = session.createCriteria(Employee.class);
		
		//添加排序
		criteria.addOrder(Order.asc("salary"));
		criteria.addOrder(Order.desc("email"));
		List<Employee> employees = criteria.list();
		System.out.println(employees);
		
		//2.添加分页方法
		int pageSize = 2;
		int pageNo = 3;
		Criteria criteria3 = session.createCriteria(Employee.class);
		criteria3.setFirstResult((pageNo - 1) *pageSize)
		         .setMaxResults(pageSize);
		List<Employee> employees2 = criteria3.list();
		System.out.println(employees2);
		         
}
	

三、SQL查询(使用sql语句)

@Test
	public void testNativeSQL(){
		//String sql = "INSERT INTO employee(NAME,SALARY,EMAIL,DEPT_Id) VALUES('ZZ',7000,'zz@zhuojing.com',5)";
		String sql = "INSERT INTO department(NAME) VALUES('ZHUOJING')";
		Query query = session.createSQLQuery(sql);
		
		/*query.setString(0, "ZZ")
		     .setFloat(1, 7000F)
		     .setString(2, "zz@zhuojing.com")
		     .setInteger(3, 4)
		     .executeUpdate();*/
		query.executeUpdate();
	}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值