标签: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