标签:hibernate
| 凡学之不勤,必其志未笃也。 |
0、准备JavaBean和映射文件
Department.java
package com.rk.hibernate.o_query;
import java.util.Set;
public class Department
{
private int deptId;
private String deptName;
private Set<Employee> emps;
public int getDeptId()
{
return deptId;
}
public void setDeptId(int deptId)
{
this.deptId = deptId;
}
public String getDeptName()
{
return deptName;
}
public void setDeptName(String deptName)
{
this.deptName = deptName;
}
public Set<Employee> getEmps()
{
return emps;
}
public void setEmps(Set<Employee> emps)
{
this.emps = emps;
}
@Override
public String toString()
{
return "Department [deptId=" + deptId + ", deptName=" + deptName + "]";
}
}Department.hbm.xml
<?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"> <hibernate-mapping package="com.rk.hibernate.o_query" auto-import="true"> <class name="Department" table="T_Department"> <id name="deptId" column="id"> <generator class="native"></generator> </id> <property name="deptName" column="name" type="string"></property> <set name="emps" table="T_Employee"> <key column="deptId"></key> <one-to-many class="Employee"/> </set> </class> <!-- 存放sql语句 --> <query name="getAllDept"> <!-- CDATA,全名:character data,是指 不由 XML 解析器进行解析的文本数据 CDATA的形式:<![CDATA[文本内容]]> --> <![CDATA[ from Department where deptId<? ]]> </query> <query name="getAllDept2"> <![CDATA[ from Department where deptId < :myid ]]> </query> </hibernate-mapping>
Employee.java
package com.rk.hibernate.o_query;
public class Employee
{
private int empId;
private String empName;
private int salary;
private Department dept;
public int getEmpId()
{
return empId;
}
public void setEmpId(int empId)
{
this.empId = empId;
}
public String getEmpName()
{
return empName;
}
public void setEmpName(String empName)
{
this.empName = empName;
}
public int getSalary()
{
return salary;
}
public void setSalary(int salary)
{
this.salary = salary;
}
public Department getDept()
{
return dept;
}
public void setDept(Department dept)
{
this.dept = dept;
}
@Override
public String toString()
{
return "Employee [empId=" + empId + ", empName=" + empName + ", salary=" + salary + "]";
}
}Employee.hbm.xml
<?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"> <hibernate-mapping package="com.rk.hibernate.o_query" auto-import="true"> <class name="Employee" table="T_Employee"> <id name="empId" column="id"> <generator class="native"></generator> </id> <property name="empName" column="name" type="string"></property> <property name="salary" column="salary" type="int"></property> <many-to-one name="dept" column="deptId" class="Department"></many-to-one> </class> </hibernate-mapping>
Person.java
package com.rk.hibernate.o_query;
public class Person
{
private int id;
private String name;
public Person(){}
public Person(int id, String name)
{
this.id = id;
this.name = name;
}
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
@Override
public String toString()
{
return "Person [id=" + id + ", name=" + name + "]";
}
}1、HQL查询
package com.rk.hibernate.o_query;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
public class App_01_HQL
{
private static SessionFactory sf;
static
{
sf = new Configuration()
.configure()
.addClass(Department.class)
.addClass(Employee.class)
.buildSessionFactory();
}
/*
* 1) Get/load主键查询
2) 对象导航查询
3) HQL查询, Hibernate Query language hibernate 提供的面向对象的查询语言。
4) Criteria 查询, 完全面向对象的查询(Query By Criteria ,QBC)
5) SQLQuery, 本地SQL查询
*/
@Test
public void testHQL()
{
Session session = sf.openSession();
session.beginTransaction();
//1) Get/load主键查询
//get和load的区别:
// a) get是及时加载,如果找不到相应的记录,则返回null
// b) load是懒加载,如果找不到相应的记录,则抛出异常 org.hibernate.ObjectNotFoundException: No row with the given identifier exists
// Department dept = (Department)session.get(Department.class, 1);
// Department dept = (Department)session.load(Department.class, 2);
//2) 对象导航查询
// Department dept = (Department)session.get(Department.class, 1);
// System.out.println(dept.getDeptName());
// System.out.println(dept.getEmps());
// 3) HQL查询
// 注意: 使用hql查询的时候,映射文件(.hbm.xml)中hibernate-mapping的 auto-import="true" 要设置为true,
// 如果是false,写hql的时候,要指定类的全名,否则报错:org.hibernate.hql.ast.QuerySyntaxException: 类名 is not mapped
// List<Employee> list = session.createQuery("from Employee").list();
// System.out.println(list);
// a. 查询全部列
// Query q = session.createQuery("from Employee");
// Query q = session.createQuery("select * from Employee"); //这样是不对的 Wrong
// Query q = session.createQuery("select e.* from Employee as e");//这样是不对的 Wrong
// Query q = session.createQuery("select e from Employee as e");
// List list = q.list();
// System.out.println(list);
// b. 查询指定的列 【返回对象数据Object[] 】
// Query q = session.createQuery("select e.empId, e.empName from Employee e ");
// List<Object[]> list = q.list();
// for(Object[] objs : list)
// {
// System.out.println(objs[0] + "###" + objs[1]);
// }
// c. 查询指定的列, 自动封装为对象 【必须要提供带参数构造器】
// 在HQL查询中必须要使用Person的全类名
// 否则,会报错 org.hibernate.hql.ast.QuerySyntaxException: Unable to locate class [Person]
// 同时,Person类必须提供带参数的构造方法
// 否则,会报错 org.hibernate.hql.ast.QuerySyntaxException: Unable to locate appropriate constructor on class [com.rk.hibernate.o_query.Person]
// Query q = session.createQuery("select new com.rk.hibernate.o_query.Person(e.empId,e.empName) from Employee e");
// List<Person> list = q.list();
// System.out.println(list);
// d. 条件where查询: 一个条件/多个条件and or/between and/模糊查询
// 条件查询: 占位符 (索引方式)
// Query q = session.createQuery("from Employee where empId=?");
//// q.setInteger(0, 3);
// q.setParameter(0, 3);
// List<Employee> list = q.list();
// System.out.println(list);
// 条件查询: 占位符 (命名参数)
// Query q = session.createQuery("from Employee where empId= :myid or empName= :myname");
// q.setParameter("myid", 1);
// q.setParameter("myname", "tom");
// List<Employee> list = q.list();
// System.out.println(list);
// 范围查询
// Query q = session.createQuery("from Employee where empId between :firstNum and :secondNum");
// q.setParameter("firstNum", 2);
// q.setParameter("secondNum", 3);
// List<Employee> list = q.list();
// System.out.println(list);
// 模糊查询
// Query q = session.createQuery("from Employee where empName like :myName");
// q.setParameter("myName", "%om%");
// List<Employee> list = q.list();
// System.out.println(list);
// e. 聚合函数统计
// Query q = session.createQuery("select count(*) from Employee");
// Long num = (Long) q.uniqueResult();
// System.out.println(num);
// f. 分组查询
//-- 统计t_employee表中,每个部门的人数
// 数据库写法:SELECT deptId, COUNT(*) AS Num FROM t_employee GROUP BY deptId
// HQL写法
Query q = session.createQuery("select e.dept, count(*) from Employee as e group by e.dept");
List<Object[]> list = q.list();
for(Object[] objs : list)
{
System.out.println(objs[0] + "###" + objs[1]);
}
session.getTransaction().commit();
session.close();
}
// g. 连接查询
@Test
public void testJoin()
{
Session session = sf.openSession();
session.beginTransaction();
//1) 内连接 【映射已经配置好了关系,关联的时候,直接写对象的属性即可】
// Query q = session.createQuery("from Department d inner join d.emps");
//2) 左外连接
// Query q = session.createQuery("from Department d left join d.emps");
//3) 右外连接
Query q = session.createQuery("from Department d right join d.emps");
//显示查询结果
List<Object[]> list = q.list();
for(Object[] objs : list)
{
for(int i=0;i<objs.length;i++)
{
System.out.print(objs[i] + " ");
}
System.out.println();
}
session.getTransaction().commit();
session.close();
}
// g. 连接查询 - 迫切连接
@Test
public void testFetch()
{
Session session = sf.openSession();
session.beginTransaction();
//1) 迫切内连接 【使用fetch, 会把右表的数据,填充到左表对象中!】
//注意需要添加distinct,否则取出的数据有重复
// Query q = session.createQuery("select distinct d from Department d inner join fetch d.emps");
//2) 迫切左外连接
Query q = session.createQuery("select distinct d from Department d left join fetch d.emps");
//显示查询结果
List<Department> list = q.list();
for(Department d : list)
{
System.out.println(d);
}
session.getTransaction().commit();
session.close();
}
// HQL查询优化,HQL写在.hbm.xml文件中
@Test
public void testHQL2()
{
Session session = sf.openSession();
session.beginTransaction();
// HQL写死 HardCode
// Query q = session.createQuery("from Department where deptId<?");
// q.setParameter(0, 3);
// Query q = session.getNamedQuery("getAllDept");
// q.setParameter(0, 3);
Query q = session.getNamedQuery("getAllDept2");
q.setParameter("myid", 3);
List<Department> list = q.list();
System.out.println(list);
session.getTransaction().commit();
session.close();
}
}2、Criteria查询和本地SQL查询
package com.rk.hibernate.o_query;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Restrictions;
import org.junit.Test;
public class App_02_Criteria
{
private static SessionFactory sf;
static
{
sf = new Configuration()
.configure()
.addClass(Department.class)
.addClass(Employee.class)
.buildSessionFactory();
}
/*
* 1) Get/load主键查询
2) 对象导航查询
3) HQL查询, Hibernate Query language hibernate 提供的面向对象的查询语言。
4) Criteria 查询, 完全面向对象的查询(Query By Criteria ,QBC)
5) SQLQuery, 本地SQL查询
*/
//4) Criteria 查询
@Test
public void testCriteria()
{
Session session = sf.openSession();
session.beginTransaction();
Criteria criteria = session.createCriteria(Department.class);
// 主键查询
// criteria.add(Restrictions.idEq(3));
criteria.add(Restrictions.eq("deptId", 3));
List list = criteria.list();
System.out.println(list);
session.getTransaction().commit();
session.close();
}
// 5) SQLQuery, 本地SQL查询
// 不能跨数据库平台: 如果改了数据库,sql语句有可能要改。
@Test
public void testSQLQuery()
{
Session session = sf.openSession();
session.beginTransaction();
SQLQuery q = session.createSQLQuery("select * from T_Department;").addEntity(Department.class);
List<Department> list = q.list();
System.out.println(list);
session.getTransaction().commit();
session.close();
}
}3、分页查询
package com.rk.hibernate.o_query;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
public class App_03_Page
{
private static SessionFactory sf;
static
{
sf = new Configuration()
.configure()
.addClass(Department.class)
.addClass(Employee.class)
.buildSessionFactory();
}
// 分页查询:先查询总记录数,再分页查询
@Test
public void testPage()
{
Session session = sf.openSession();
session.beginTransaction();
Query q = session.createQuery("from Department");
// 总记录数
ScrollableResults scroll = q.scroll();
scroll.last();
//ScrollableResults.getRowNumber()
//Get the current location in the result set. The first row is number 0, contrary to JDBC.
int totalCount = scroll.getRowNumber() + 1;
// 设置分页参数
q.setFirstResult(2);//从0开始
q.setMaxResults(5);
//显示结果
List<Department> list = q.list();
System.out.println("总记录数是" + totalCount+"条");
for(Department d : list)
{
System.out.println(d);
}
session.getTransaction().commit();
session.close();
}
}标签:hibernate
原文地址:http://lsieun.blog.51cto.com/9210464/1826985