Criteria 接口:
QBC 查询: QUery By Criteria 根据条件查询, 更加的面向对象:
1:开发步骤:
a: 获得一个Criteria 对象:
b: Criteria.add(“条件”).add("").add("");
条件: 单独的封装成了一个对象:Criterion
c:获得条件:
Restrictions;对象, 提供了一系列的方法, 可以获得Criterion 对象:
d: list 方法或者是 uniqueResult方法:
2: 查询所有(一连串的。。。):
条件查询:
多条件查询:
分页查询:
记录数查询:
package com.yidongxueyuan;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.junit.Test;
import com.yidongxueyuan.domain.Customer;
import com.yidongxueyuan.utils.HibernateUtils;
public class TestCriteria {
//查询所有:
@Test
public void method01() throws Exception {
//1:获得session:
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//2:获得Criteria接口:
Criteria criteria = session.createCriteria(Customer.class);
//查询所有:
List<Customer> list = criteria.list();
System.out.println(list);
tx.commit();
}
//条件查询:
@Test
public void method02() throws Exception {
//1:获得session:
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//2:获得Criteria接口:
Criteria criteria = session.createCriteria(Customer.class);
//3:添加查询条件: 将条件封装成了对象: Criterion 对象: 通过Restrictions 对象的静态方法获得
// criteria.add(Restrictions.eq("cust_name", "王导演"));
//4: 多条件组合查询:
List sources = new ArrayList();
sources.add("朋友推荐");
sources.add("广告");
criteria.add(Restrictions.like("cust_name", "%王%")).
add(Restrictions.in("cust_source", sources ));
//查询所有:
List<Customer> list = criteria.list();
System.out.println(list);
tx.commit();
}
//分页查询:
@Test
public void method03() throws Exception {
//1:获得session:
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//2:获得Criteria接口:
Criteria criteria = session.createCriteria(Customer.class);
criteria.setFirstResult(5);//开始的索引
criteria.setMaxResults(5);//每次查询的记录数:
List<Customer> list = criteria.list();
System.out.println(list);
tx.commit();
}
//查询总记录数:
@Test
public void method04() throws Exception {
//1:获得session:
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//方式一: 获得总记录数:
//2:获得Criteria接口:
/* Criteria criteria = session.createCriteria(Customer.class);
// criteria.setProjection(Projections.count("cust_id")).list();
Object num = criteria.setProjection(Projections.count("cust_id")).uniqueResult();
System.out.println(num);*/
//方式二:
Object result = session.createCriteria(Customer.class)
.setProjection( Projections.projectionList()
.add( Projections.rowCount())
).uniqueResult();
System.out.println(result);
tx.commit();
}
// testSQLCriteria
}
SQLQuery接口:
sql语句过于复杂的时候使用,不会自动封装,需要手动封装。
package com.yidongxueyuan;
import static org.junit.Assert.*;
import java.util.List;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.yidongxueyuan.domain.Customer;
import com.yidongxueyuan.utils.HibernateUtils;
public class TestSQLQuery {
@Test
public void test01() throws Exception {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//获得SQLCriteria:
//查询所有:
String sql = "select * from cst_customer ";
SQLQuery sqlQuery = session.createSQLQuery(sql);
//查询的数据手动的封装到实体当中:
sqlQuery.addEntity(Customer.class);
List<Customer> list = sqlQuery.list();
//条件查询: select * from table where xxx and xxxx ;
// 查询记录数:
String sql1= "select count(*) from cst_customer";
SQLQuery sqlQuery2 = session.createSQLQuery(sql1);
Object result = sqlQuery2.uniqueResult();
System.out.println(list);
System.out.println(result);
tx.commit();
}
}
表和表之间的关系:
一对一的关系:
一对多的关系:
多对多的关系:
实现一对多:
开发步骤:
(1)创建表: Customer LinkMan
(2)创建实体:
Customer 实体:
private Set linkMans = new HashSet();
LinkMan 实体: 维护实体和实体之间的关系:
private Customer customer =new Customer();
(3)配置各自的xml映射文件如下:
一的一方
多的一方:
LinkedMan.hbm.xml
<class >
<id>
<property>
<!--
name: 本类属性的名称: customer
class: 属性名称关联的实体类:
column: 多的一方的外键的名称
-->
<many-to- one name="" class="" column="" />
</class>
(4)配置hibernat.cfg.xml
(5)写代码测试一下
package com.yidongxueyuan.test;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.yidongxueyuan.domain.Customer;
import com.yidongxueyuan.domain.LinkedMan;
import com.yidongxueyuan.utils.HibernateUtils;
public class TestDemo {
//测试: 一对多的保存操作:
@Test
public void testName() throws Exception {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//准备客户: 2
Customer cust1= new Customer();
cust1.setCust_name("毕老师");
Customer cust2= new Customer();
cust2.setCust_name("大张老师");
//准备联系人: 3
LinkedMan linedMan1= new LinkedMan();
linedMan1.setLkm_name("凤姐");
LinkedMan linedMan2= new LinkedMan();
linedMan2.setLkm_name("如花");
LinkedMan linedMan3= new LinkedMan();
linedMan3.setLkm_name("翠花");
//建立客户和联系人的关系:
cust1.getLinkMans().add(linedMan1);
cust1.getLinkMans().add(linedMan2);
cust2.getLinkMans().add(linedMan3);
//建立双向关联: 建立联系人和客户的关系:
linedMan1.setCustomer(cust1);
linedMan2.setCustomer(cust1);
linedMan3.setCustomer(cust2);
//保存:
// 保存客户:
session.save(cust1);
session.save(cust2);
//保存联系人:
session.save(linedMan1);
session.save(linedMan2);
session.save(linedMan3);
tx.commit();
}
//测试: 只保存一方是否可以?
// 答案: 不可以:
@Test
public void testName2() throws Exception {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//准备客户: 2
Customer cust1= new Customer();
cust1.setCust_name("毕老师3");
//准备联系人: 3
LinkedMan linedMan1= new LinkedMan();
linedMan1.setLkm_name("凤姐");
LinkedMan linedMan2= new LinkedMan();
linedMan2.setLkm_name("如花");
//建立客户和联系人的关系:
cust1.getLinkMans().add(linedMan1);
cust1.getLinkMans().add(linedMan2);
//建立双向关联: 建立联系人和客户的关系:
linedMan1.setCustomer(cust1);
linedMan2.setCustomer(cust1);
//保存:
// 保存客户:
/*
*
* 保存的时候会抛出异常:
* 瞬时对象异常, 原因: 持久态对象关联了一个瞬时态。
*/
session.save(cust1);
tx.commit();
}
//测试级联保存: 保存客户 级联保存练习人:
@Test
public void testName3() throws Exception {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//准备客户: 2
Customer cust1= new Customer();
cust1.setCust_name("毕老师3");
//准备联系人: 3
LinkedMan linedMan1= new LinkedMan();
linedMan1.setLkm_name("凤姐3");
LinkedMan linedMan2= new LinkedMan();
linedMan2.setLkm_name("如花3");
//建立客户和联系人的关系:
cust1.getLinkMans().add(linedMan1);
cust1.getLinkMans().add(linedMan2);
//建立双向关联: 建立联系人和客户的关系:
linedMan1.setCustomer(cust1);
linedMan2.setCustomer(cust1);
session.save(cust1);
tx.commit();
}
//测试级联保存: 保存联系人, 级联保存客户:
@Test
public void testName4() throws Exception {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//准备客户: 2
Customer cust1= new Customer();
cust1.setCust_name("毕老师4");
//准备联系人: 3
LinkedMan linedMan1= new LinkedMan();
linedMan1.setLkm_name("凤姐4");
LinkedMan linedMan2= new LinkedMan();
linedMan2.setLkm_name("如花4");
//建立客户和联系人的关系:
cust1.getLinkMans().add(linedMan1);
cust1.getLinkMans().add(linedMan2);
//建立双向关联: 建立联系人和客户的关系:
linedMan1.setCustomer(cust1);
linedMan2.setCustomer(cust1);
// session.save(cust1);
session.save(linedMan1);
session.save(linedMan2);
tx.commit();
}
}
如果只保存一边的话,会抛出瞬时对象异常,一个持久态关联了一个瞬时态,不归session管理,所以抛出异常。
如果想只保存一边,级联保存:
在hibernate的映射文件,添加如下(两个实体类的映射文件都要配置!):
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.yidongxueyuan.domain.Customer" table="cst_customer" >
<id name="cust_id" column="cust_id" >
<generator class="native"/>
</id>
<property name="cust_name" column="cust_name" length="21" type="string" not-null="true" unique="false"/>
<property name="cust_source" column="cust_source"/>
<property name="cust_industry" column="cust_industry"/>
<property name="cust_level" column="cust_level"/>
<property name="cust_phone" column="cust_phone"/>
<property name="cust_mobile" column="cust_mobile"/>
<!--
set: 标签:
name:方的该实体类当中属性的名称, 属性的类型是一个set集合类型:
save-update:表明可以进行级联操作:
就是在操作Customer对象的时候, 可以同时操作Customer关联的其他的对象。
-->
<set name="linkMans" cascade="save-update">
<!--
多的一方,外键的名称:
-->
<key column="lkm_cust_id"/>
<!--
one-to-many :
表明表和表之间的关系: 一对多:
class: 放3的是多的一方的全路径名称。
-->
<one-to-many class="com.yidongxueyuan.domain.LinkedMan"/>
</set>
</class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.yidongxueyuan.domain.LinkedMan" table="cst_linkman" >
<id name="lkm_id" column="lkm_id" >
<generator class="native"/>
</id>
<property name="lkm_name" column="lkm_name" />
<property name="lkm_gender" column="lkm_gender"/>
<property name="lkm_phone" column="lkm_phone"/>
<property name="lkm_mobile" column="lkm_mobile"/>
<property name="lkm_email" column="lkm_email"/>
<property name="lkm_qq" column="lkm_qq"/>
<property name="lkm_position" column="lkm_position"/>
<property name="lkm_memo" column="lkm_memo"/>
<!-- 多的一方:
name: 本类属性的名称:
class: 一的一方的类的全路径名称:
column: 在多的一方表的外键的名称:
cascade: 级联操作:
操作联系人的时候 同时可以操作联系人关联的客户信息
-->
<many-to-one name="customer" class="com.yidongxueyuan.domain.Customer" column="lkm_cust_id" cascade="save-update"/>
</class>
</hibernate-mapping>