package com.pc.hibernate.test.querymethod;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.pc.hibernate.domain.Customer;
import com.pc.hibernate.utils.HibernateUtils;
/**
* Hibernate中的查询方式:
* OID查询:
* 它就是根据id查询一个实体
* 涉及的方法:
* get(Class clazz,Serializable id):参数1是要查询的实体字节码,参数2:是要查询的id。
* load(Class clazz,Serializable id):参数1是要查询的实体字节码,参数2:是要查询的id。
*
* Hibernate的检索策略
* 类级别检索策略:
* get方法:
* 它永远都是立即加载。返回的对象是实体类类型。
* 立即加载的含义:不管用不用,都马上发起查询。
* load方法:
* 它默认是延迟加载。返回的是实体类对象的代理对象。
* 它可以通过配置的方式改为立即加载。配置的位置是映射文件的class标签。
* 涉及的属性是:lazy。含义就是是否延迟加载。 取值true延迟加载(默认值) false不是延迟加载
* 延迟加载的含义:什么时候用,什么时候真正发起查询。
* @author Switch
*
*/
public class TestOIDQuery {
/**
* 需求:
* 查询id为1的客户
*/
@Test
public void test1() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
Customer customer = session.get(Customer.class, 1L);
transaction.commit();
// 输出1和客户信息
System.out.println(customer.getCustId());
System.out.println(customer);
}
/**
* 需求:
* 查询id为1的客户
*/
@Test
public void test2() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
Customer customer = session.load(Customer.class, 1L);
transaction.commit();
// 输出1和报错could not initialize proxy - no Session
// 当时
// 该方法正确,因为这时候已经不延迟加载了
System.out.println(customer.getCustId());
System.out.println(customer);
}
}
package com.pc.hibernate.test.querymethod;
import java.util.List;
import java.util.Set;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.pc.hibernate.domain.Customer;
import com.pc.hibernate.domain.LinkMan;
import com.pc.hibernate.utils.HibernateUtils;
/**
*
* Hibernate中的查询方式:
* 对象导航查询
* 当我们两个实体类有关联关系时(一对多,多对一等等),在获取一个实体时,可以根据对象的方法,获取该实体关联对象的数据。
* customer.getLinkMans();获取当前客户下的所有联系人
* linkman.getCustomer();获取当前联系人所属客户。
*
* @author Switch
*/
public class TestObjectNavigationQuery {
/**
* 一般情况下我们都会有一个这样的方法:根据id查询一个实体。
* 任何实体都应该有这么个方法
*/
public Customer findById(Long custId){
Session s = HibernateUtils.getCurrentSession();
Transaction tx = s.beginTransaction();
Customer c1 = s.get(Customer.class, custId);
tx.commit();
return c1;
}
/**
* 根据客户id查询联系人信息
* @param custId
* @return
*/
public List findLinkManByCid(Long custId){
Session s = HibernateUtils.getCurrentSession();
Transaction tx = s.beginTransaction();
SQLQuery query = s.createSQLQuery("select * from cst_linkman where lkm_cust_id = ? ");
query.setLong(0, custId);
query.addEntity(LinkMan.class);
@SuppressWarnings("unchecked")
List mans = query.list();
tx.commit();
return mans;
}
/**
* 需求:
* 查询id为1的客户下的所有联系人
*/
@Test
public void test1(){
// 传统的使用方式
List list = findLinkManByCid(1L);
System.out.println(list);
Customer c = findById(1L);
//对象导航查询
// 需要将Customer上对应于LinkMan的关系检索策略的懒加载关闭
Set linkmans = c.getLinkMans();
for(LinkMan linkMan : linkmans){
System.out.println(linkMan);
}
}
/**
* 需求:
* 查询id为5的联系人所属客户
*/
@Test
public void test2() {
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
LinkMan linkMan = session.get(LinkMan.class, 5L);
// 对象导航查询
System.out.println(linkMan.getCustomer());
transaction.commit();
}
}
SELECT * FROM cst_customer c INNER JOIN cst_linkman 1 ON c.cust_id = l.lkm_cust_id;
from Customer c inner join c.linkMans
from Customer c inner join fetch c.linkMans
package com.pc.hibernate.test.querymethod;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.pc.hibernate.domain.Customer;
import com.pc.hibernate.domain.LinkMan;
import com.pc.hibernate.utils.HibernateUtils;
/**
* Hibernate中的查询方式:
* HQL查询:
* 它是使用HQL语句进行查询的。 HQL:Hiberante Query Language
* 涉及的对象:
* Query
* 如何获取Query:
* session.createQuery(String hql);
* HQL语句写法:
* 表名用实体类名称替代
* 字段名用实体类属性名称(get/set方法后面的部分,并且把首字母转小写)
*
* @author Switch
*/
public class TestHQLQuery {
/**
* 查询所有
* 需求:查询所有客户
*/
@Test
public void test1() {
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
// 查询所有客户
Query query = session.createQuery("from Customer");
@SuppressWarnings("unchecked")
List customers = query.list();
transaction.commit();
for (Customer customer : customers) {
System.out.println(customer);
}
}
/**
* 条件查询:
* 需求:
* 查询客户级别是23的,客户名称带有 集 字的
* 给HQL语句加条件用where
* HQL语句的参数占位符也可以使用?
* hibernate中,参数占位符是从0开始的。
*/
@Test
public void test2(){
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
// 查询客户级别是23的,客户名称带有 集 字的
Query query = session.createQuery("from Customer where custLevel = ? and custName like ?");
query.setString(0, "23");
query.setString(1, "%集%");
@SuppressWarnings("unchecked")
List customers = query.list();
transaction.commit();
for (Customer customer : customers) {
System.out.println(customer);
}
}
/**
* 具名查询:
* 给参数占位符提供一个具体的名称
* HQL语句中的写法:
* 需要使用 :参数名称
* 例如: :custLevel :custName
* 参数站位符赋值的写法:
* 需要注意:此处不能写冒号,直接写冒号后面的部分
*/
@Test
public void test3(){
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
// 查询客户级别是23的,客户名称带有 集 字的
// 给参数占位符提供一个具体的名称
Query query = session.createQuery("from Customer where custLevel = :custLevel and custName like :custName");
query.setString("custLevel", "23");
query.setString("custName", "%集%");
@SuppressWarnings("unchecked")
List customers = query.list();
transaction.commit();
for (Customer customer : customers) {
System.out.println(customer);
}
}
/**
* 排序查询:
* 使用HQL语句,给查询结果排序
*
* HQL语句中的排序:
* order by
* asc:升序(默认值)
* desc:降序
*/
@Test
public void test4(){
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
// 按联系人ID降序排序联系人
Query query = session.createQuery("from LinkMan order by lkmId desc");
@SuppressWarnings("unchecked")
List linkMans = query.list();
transaction.commit();
for (LinkMan linkMan : linkMans) {
System.out.println(linkMan);
}
}
/**
* 分页查询
* MySQL中分页关键字:
* Limit
* limit的两个参数: 第一个参数:查询的开始记录索引。(它是从0开始的)
* 第二个参数:每次查询多少条记录。(它是固定的)
* Hibernate中涉及的方法
* setFirstResult(int firstResult):查询的开始记录索引
* setMaxResults(int maxResults):每次查询多少条记录
*/
@Test
public void test5(){
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
//1.获取Query对象
Query query = session.createQuery("from LinkMan");
//2.使用Hibernate提供的方法来设置分页条件
Integer firstResult = 0;
Integer maxResults = 2;
query.setFirstResult(firstResult);
query.setMaxResults(maxResults);
//3.执行query对象的方法
@SuppressWarnings("unchecked")
List list = query.list();
transaction.commit();
for (LinkMan linkMan : list) {
System.out.println(linkMan);
}
}
/**
* 统计查询
* 其实就是在HQL语句中使用聚合函数
* count() sum() avg() max() min()
* 使用聚合函数查询时,如果没有group by,返回的结果集是一行一列的
*
* 聚合函数都不会计算为null的字段。
*
* count(*)和count(主键)是一样的。
*/
@Test
public void test6(){
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 查询一共有多少个联系人
Query query = session.createQuery("select count(lkmId) from LinkMan");
Long count = (Long) query.uniqueResult();
transaction.commit();
System.out.println(count);
}
/**
* 投影查询:
* 当我们查询实体对象时,并不需要所有字段信息,只查询部分,但是还想让他成为一个实体对象。其实就是用部分字段来投影出整个实体对象。
* 使用要求:
* HQL语句:
* 写法必须是 new 实体类名称(查询的字段)
* select new Customer(custId,custName) from Customer
* 注意:如果你的实体类在工程中唯一,则可以直接写类名。如果实体类在工程中不唯一,需要写全限定类名。
* 实体类要求:
* 必须在实体类中提供一个相同参数列表的构造函数。
*
*/
@Test
public void test71(){
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 只获取客户的ID和名字,并封装成客户对象
Query query = session.createQuery("select new Customer(custId, custName) from Customer");
@SuppressWarnings("unchecked")
List customers = query.list();
transaction.commit();
for (Customer customer : customers) {
System.out.println(customer.getCustId() + " " + customer.getCustName());
}
}
@Test
public void test72(){
Session s = HibernateUtils.getCurrentSession();
Transaction tx = s.beginTransaction();
//1.获取Query对象
Query query = s.createQuery("select custId,custName from Customer ");
//2.执行query对象的方法
@SuppressWarnings("unchecked")
List
方法名
|
说明
|
Restrictions.eq
|
等于
|
Restrictions. allEq
|
使用 Map ,使用key/value进行多个等于的比较
|
Restrictions.gt
|
大于>
|
Restrictions.ge
|
大于等于>=
|
Restrictions.lt
|
小于
|
Restrictions.le
|
小于等于<=
|
Restrictions.between
|
对应 SQL 的 between 子句
|
Restrictions.like
|
对应 SQL 的 like 子句
|
Restrictions.in
|
对应 SQL 的 IN 子句
|
Restrictions.and
|
and 关系
|
Restrictions.or
|
or 关系
|
Restrictions.sqlRestriction
|
SQL 限定查询
|
package com.pc.hibernate.test.querymethod;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.junit.Test;
import com.pc.hibernate.domain.Customer;
import com.pc.hibernate.domain.LinkMan;
import com.pc.hibernate.utils.HibernateUtils;
/**
* Hibernate中的查询方式:
* QBC查询:
* Query By Criteria 它是一种更加面向对象的查询方式。
* 它把查询条件都用方法封装了。里面的参数全都需要使用实体类的属性名称。
* 涉及的对象:
* Criteria
* DetachedCriteria
* 获取的方式:
* session.createCriteria(Class clazz);参数指的是要查询的字节码
* 添加条件的方法:
* Criteria的add方法。
* 添加条件涉及的对象:
* Restrictions
*
* @author Switch
*/
public class TestQBCQuery {
/**
* 基本查询:查询所有
*
* 需求:
* 查询所有客户
*/
@Test
public void test1(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//1.获取Criteria对象
Criteria criteria = session.createCriteria(Customer.class);
//2.执行list方法,得到结果集
@SuppressWarnings("unchecked")
List customers = criteria.list();
tx.commit();
for (Customer customer : customers) {
System.out.println(customer);
}
}
/**
* 条件查询
* 需求:查询客户级别是23的,客户名称带有集字的
*/
@Test
public void test2(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//1.获取Criteria对象
Criteria criteria = session.createCriteria(Customer.class);
// 添加条件
criteria.add(Restrictions.eq("custLevel", "23"));
criteria.add(Restrictions.like("custName", "%集%"));
//2.执行list方法,得到结果集
@SuppressWarnings("unchecked")
List customers = criteria.list();
tx.commit();
for (Customer customer : customers) {
System.out.println(customer);
}
}
/**
* 分页查询
*
* 涉及的方法:
* setFirstResult(int firstResult);
* setMaxResults(int maxResults);
* 含义和HQL是一模一样的
*/
@Test
public void test3(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//1.获取Criteria对象
Criteria criteria = session.createCriteria(Customer.class);
criteria.setFirstResult(0);
criteria.setMaxResults(2);
//2.执行list方法,得到结果集
@SuppressWarnings("unchecked")
List customers = criteria.list();
tx.commit();
for (Customer customer : customers) {
System.out.println(customer);
}
}
/**
* 统计查询:
* 使用QBC来添加聚合函数
*
* count() avg() min() max() sum()
*
* 涉及的方法:
* setProjections(Projection p ); 它可以加查询语句的结构。
* 涉及的类:
* Projections
* 该类中提供了一些静态方法
*/
@Test
public void test4(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//1.获取Criteria对象
Criteria criteria = session.createCriteria(Customer.class);
criteria.setProjection(Projections.count("custId"));
//2.执行uniqueResult方法,得到结果
Long result = (Long) criteria.uniqueResult();
tx.commit();
System.out.println(result);
}
/**
* 排序查询
*
* 涉及方法:
* Criteria的addOrder方法。该方法需要一个Order对象作为参数
* Order对象有两个方法:
* desc(String propertyName):按照指定的属性名称,倒序排序。
* asc(String propertyName):按照自顶的属性名称,正序排序。
*/
@Test
public void test5(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//1.获取Criteria对象
Criteria criteria = session.createCriteria(LinkMan.class);
criteria.addOrder(Order.desc("lkmId"));
//2.执行list方法,得到结果集
@SuppressWarnings("unchecked")
List linkMans = criteria.list();
tx.commit();
for (LinkMan linkMan : linkMans) {
System.out.println(linkMan);
}
}
/**
* 离线查询:
* 在线对象:
* Criteria对象。它的获取必须要一个可用的Session来创建。如果Session不能用,则不能创建Criteria。
* 我们使用Criteria进行的查询就是在线查询。
* 离线对象:
* 创建DetachedCriteria不需要一个可用的Session。
* 用DetachedCriteria进行的查询就叫做离线查询
* 涉及的对象
* DetachedCriteria
* 如何获取
* DetachedCriteria.forClass(Class clazz);参数的含义:要查询的实体类
* 如何设置查询条件:
* 和Criteria是一样的
*
* 在实际开发中:多条件查询用此种方式
*/
//Servlet的方法
@Test
public void doGet(){
//1.获取请求参数
String custLevel = "23";
String custName = "集";
//2.查询所有客户
DetachedCriteria dCriteria = DetachedCriteria.forClass(Customer.class);
dCriteria.add(Restrictions.eq("custLevel", custLevel));
dCriteria.add(Restrictions.like("custName", "%"+custName+"%"));
List cs = servicefindAllCustomer(dCriteria);
for(Customer c : cs){
//3.存入请求域中
//4.转向列表页面
System.out.println(c);
}
}
//Service的方法
public List servicefindAllCustomer(DetachedCriteria dCriteria){
return daofindAllCustomer(dCriteria);
}
//Dao中的方法
public List daofindAllCustomer(DetachedCriteria dCriteria){
Session s = HibernateUtils.getCurrentSession();
Transaction tx = s.beginTransaction();
//1.把离线对象激活
Criteria c = dCriteria.getExecutableCriteria(s);
//3.执行list方法,得到结果集
@SuppressWarnings("unchecked")
List list = c.list();
tx.commit();
return list;
}
}
/**
* SQLQuery 它使用的是原始的SQL语句查询
*/
@Test
public void test3() {
Session s = HibernateUtils.getCurrentSession();
Transaction tx = s.beginTransaction();
// 1.获取SQLQuery对象
SQLQuery sqlquery = s.createSQLQuery("select * from cst_customer");// 参数是SQL语句
// 2.执行sqlquery的方法,返回结果集
/*
* List list = sqlquery.list(); for(Object[] os : list){
* System.out.println(
* "-------------每出现一行分割线,表示外层循环执行了一次-------------------");
* for(Object o : os){ System.out.println(o); } }
*/
// 添加实体类字节码,把查询结果转成实体类对象
sqlquery.addEntity(Customer.class);
List cs = sqlquery.list();
for (Customer c : cs) {
System.out.println(c);
}
tx.commit();
}
com.mysql.jdbc.Driver
jdbc:mysql://localhost:3306/mycrm
root
123456
org.hibernate.dialect.MySQLDialect
true
update
org.hibernate.connection.C3P0ConnectionProvider
thread