Java进阶01:Hibernate教程

1.什么是Hibernate?
Hibernate是一个开放源码的ORM(Object Relational Mapping,对象关系映射)框架,它对JDBC进行了轻量级的封装,使得Java开发人员可以使用面向对象的编程思想来操作数据库。
2.什么是ORM?
ORM:Object Relational Mapping(对象关系映射)。指的是将一个Java中的对象与关系型数据库中的表建立一种映射关系,从而操作对象就可以操作数据库中的表。
3.为什么要使用Hibernate?
在使用传统的Servlet+JSP+JavaBean+JDBC开发应用系统,针对大型应用系统开发时,需要写多条sql查询语句,过程枯燥繁琐。使用Hibernate可以提高数据访问层的编程效率,也是最流行的ORM框架。
4.Hibernate5下载使用
下载地址:https://sourceforge.net/projects/hibernate/files/hibernate-orm/5.0.7.Final/
5.Hibernate压缩包结构
copy
documentation :Hibernate开发的文档
lib :Hibernate开发包
required :Hibernate开发的必须的依赖包
optional :Hibernate开发的可选的jar包
project :Hibernate提供的项目
二、Hibernate简单配置

1.创建数据库和表

copy
CREATE TABLE cst_customer (
cust_id bigint(32) NOT NULL AUTO_INCREMENT COMMENT ‘客户编号(主键)’,
cust_name varchar(32) NOT NULL COMMENT ‘客户名称(公司名称)’,
cust_source varchar(32) DEFAULT NULL COMMENT ‘客户信息来源’,
cust_industry varchar(32) DEFAULT NULL COMMENT ‘客户所属行业’,
cust_level varchar(32) DEFAULT NULL COMMENT ‘客户级别’,
cust_phone varchar(64) DEFAULT NULL COMMENT ‘固定电话’,
cust_mobile varchar(16) DEFAULT NULL COMMENT ‘移动电话’,
PRIMARY KEY (cust_id)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
2.创建实体类
copy
public class Customer {
private Long cust_id;
private String cust_name;
private String cust_source;
private String cust_industry;
private String cust_level;
private String cust_phone;
private String cust_mobile;
}
3. 创建映射
在实体类Customer所在包中,创建一个名为Customer.hbm.xml的映射文件,在该文件中定义了实体类Customer的属性是如何映射到cst_customer表的列上的。
copy

<?xml version="1.0" encoding="UTF-8"?>
    <!-- 建立类中的普通的属性和表的字段的对应 -->
    <property name="cust_name" column="cust_name" length="32" />
    <property name="cust_source" column="cust_source" length="32"/>
    <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"/>
</class>
4.创建一个Hibernate的核心配置文件 Hibernate的核心配置文件的名称:hibernate.cfg.xml copy <?xml version="1.0" encoding="UTF-8"?>
    <!-- 
    #hibernate.dialect org.hibernate.dialect.MySQLDialect
    #hibernate.dialect org.hibernate.dialect.MySQLInnoDBDialect
    #hibernate.dialect org.hibernate.dialect.MySQLMyISAMDialect
    #hibernate.connection.driver_class com.mysql.jdbc.Driver
    #hibernate.connection.url jdbc:mysql:///test
    #hibernate.connection.username gavin
    #hibernate.connection.password
     -->
     <!-- 数据库驱动 -->
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
     <!-- 数据库url -->
    <property name="hibernate.connection.url">jdbc:mysql:///hibernate</property>
     <!-- 数据库连接用户名 -->
    <property name="hibernate.connection.username">root</property>
     <!-- 数据库连接密码 -->
    <property name="hibernate.connection.password">1234</property>
    <!-- 数据库方言
        不同的数据库中,sql语法略有区别. 指定方言可以让hibernate框架在生成sql语句时.针对数据库的方言生成.
        sql99标准: DDL 定义语言  库表的增删改查
                  DCL 控制语言  事务 权限
                  DML 操纵语言  增删改查
        注意: MYSQL在选择方言时,请选择最短的方言.
     -->
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>


    <!-- #hibernate.show_sql true 
         #hibernate.format_sql true
    -->
    <!-- 将hibernate生成的sql语句打印到控制台 -->
    <property name="hibernate.show_sql">true</property>
    <!-- 将hibernate生成的sql语句格式化(语法缩进) -->
    <property name="hibernate.format_sql">true</property>
    <!-- 
    ## auto schema export  自动导出表结构. 自动建表
    #hibernate.hbm2ddl.auto create      自动建表.每次框架运行都会创建新的表.以前表将会被覆盖,表数据会丢失.(开发环境中测试使用)
    #hibernate.hbm2ddl.auto create-drop 自动建表.每次框架运行结束都会将所有表删除.(开发环境中测试使用)
    #hibernate.hbm2ddl.auto update(推荐使用) 自动生成表.如果已经存在不会再生成.如果表有变动.自动更新表(不会删除任何数据).
    #hibernate.hbm2ddl.auto validate    校验.不自动生成表.每次启动会校验数据库中表是否正确.校验失败.
     -->
    <property name="hibernate.hbm2ddl.auto">update</property>
    <!-- 引入orm元数据
        路径书写: 填写src下的路径
     -->
     <!-- 指定hibernate操作数据库时的隔离级别 
        #hibernate.connection.isolation 1|2|4|8     
        0001    1   读未提交
        0010    2   读已提交
        0100    4   可重复读
        1000    8   串行化
     -->
     <property name="hibernate.connection.isolation">4</property>
     <!-- 指定session与当前线程绑定 -->
     <property name="hibernate.current_session_context_class">thread</property>

    <mapping resource="cn/jzfblog/domain/Customer.hbm.xml" />

</session-factory>
5.编写测试代码 首先创建Configuration类的实例,并通过它来读取并解析配置文件hibernate,cfg.xml。然后创建SessionFactory读取解析映射文件信息,并将Configration对象中所有配置信息拷贝到SessionFactory内存中。接下来,打开Session,让SessionFactory提供链接,并开启事务,之后创建对象,向对象中添加数据,通过session.save()方法完成向数据库中保存数据的操作。最后提交事务,并关闭资源。 copy // 1.加载Hibernate的核心配置文件 Configuration configuration = new Configuration().configure(); // 手动加载映射 // configuration.addResource("com/jzfblog/hibernate/Customer.hbm.xml"); // 2.创建一个SessionFactory对象:类似于JDBC中连接池 SessionFactory sessionFactory = configuration.buildSessionFactory(); // 3.通过SessionFactory获取到Session对象:类似于JDBC中Connection Session session = sessionFactory.openSession(); // 4.手动开启事务: Transaction transaction = session.beginTransaction(); // 5.编写代码 Customer customer = new Customer(); customer.setCust_name("王西"); session.save(customer); // 6.事务提交 transaction.commit(); // 7.资源释放 session.close(); sessionFactory.close(); 三、Hibernate常见配置
1.映射的配置
    1) class标签的配置
        标签用来建立类与表的映射关系。

copy
属性:
name :类的全路径
table :表名(类名与表名一致,table可以省略)
catalog :数据库名
2) id标签的配置
标签用来建立类中的属性与表中的主键的对应关系。
copy
属性:
name :类中的属性名
column :表中的字段名(类中的属性名和表中的字段名如果一致,column可以省略)
length :长度
type :类型
3) property标签的配置
标签用来建立类中的普通属性与表的字段的对应关系。
copy
属性:
name :类中的属性名
column :表中的字段名
length :长度
type :类型
not-null :设置非空
unique :设置唯一
2.Hibernate的核心的配置
2.1 必须的配置
1) 连接数据库的基本的参数
①驱动类
②url路径
③用户名
④密码
2) 方言
2.2 可选的配置
1) 显示SQL:hibernate.show_sql
2) 格式化SQL:hibernate.format_sql
3) 自动建表:hibernate.hbm2ddl.auto
①none :不使用hibernate的自动建表。
②create :如果数据库中已经有表,删除原有表,重新创建,如果没有表,新建表。(测试)
③create-drop:如果数据库中已经有表,删除原有表,执行操作,删除这个表。如果没有表,新建一个,使用完了删除该表。(测试)
④update :如果数据库中有表,使用原有表,如果没有表,创建新表(更新表结构)。
⑤validate :如果没有表,不会创建表。只会使用数据库中原有的表。(校验映射和表结构)。
2.3 映射文件的引入
引入映射文件的位置
copy

3.Hibernate的核心API
3.1 Hibernate配置对象—Configration
Configration类的实例首先定位映射文档的位置,读取这些配置,然后创建一个SessionFactory对象。
1) 加载核心配置文件
hibernate.properties
Configuration cfg = new Configuration();
2) hibernate.cfg.xml
Configuration cfg = new Configuration().configure();
3) 加载映射文件
copy
// 手动加载映射
configuration.addResource(“com/jzfblog/hibernate/Customer.hbm.xml”);
3.2 Session工厂—SessionFactory
充当数据存储源的代理,负责创建Session对象。通常情况下,一个项目只需要一个SessionFactory,当需要操作多个数据库时,可以为每个数据库指定一个SessionFactory。
配置连接池:(了解)
copy

org.hibernate.connection.C3P0ConnectionProvider

5

20

120

3000
抽取工具类
copy
public class HibernateUtils {

public static final Configuration cfg;
public static final SessionFactory sf;

static{
    cfg = new Configuration().configure();
    sf = cfg.buildSessionFactory();
}

public static Session openSession(){
    return sf.openSession();
}

public static Session getCurrentSession(){
    return sf.getCurrentSession();
}

}
3.3 类似Connection连接对象—Session
Session代表的是Hibernate与数据库的链接对象。不是线程安全的。与数据库交互桥梁。
1) 保存方法:
Serializable save(Object obj);
copy
// 保存客户
public void demo1(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();

Customer customer  = new Customer();
customer.setCust_name("王小西");
Serializable id = session.save(customer);
System.out.println(id);
tx.commit();
session.close();

}
2) 查询方法:
T get(Class c,Serializable id);
T load(Class c,Serializable id);
get方法和load方法的区别?
get方法:
采用的是立即加载,执行到这行代码的时候,就会马上发送SQL语句去查询。
查询后返回是真实对象本身。
查询一个找不到的对象的时候,返回null
load方法:
采用的是延迟加载(lazy懒加载),执行到这行代码的时候,不会发送SQL语句,当真正使用这个对象的时候才会发送SQL语句。
查询后返回的是代理对象。javassist-3.18.1-GA.jar 利用javassist技术产生的代理。
查询一个找不到的对象的时候,返回ObjectNotFoundException
copy
// 查询:
public void demo2(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();

// 使用get方法查询
/*Customer customer = session.get(Customer.class, 100l); // 发送SQL语句
System.out.println(customer);*/

// 使用load方法查询
Customer customer = session.load(Customer.class, 200l);
System.out.println(customer);

tx.commit();
session.close();

}
3) 修改方法:
void update(Object obj);
copy
// 修改操作
public void demo3(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();

// 直接创建对象,进行修改
/*Customer customer = new Customer();
customer.setCust_id(1l);
customer.setCust_name("王聪");
session.update(customer);*/

// 先查询,再修改(推荐)
Customer customer = session.get(Customer.class, 1l);
customer.setCust_name("王小贱");
session.update(customer);

tx.commit();
session.close();

}
4) 删除方法:
void delete(Object obj);
copy
// 删除操作
public void demo4(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();

// 直接创建对象,删除

/* Customer customer = new Customer();
customer.setCust_id(1l);
session.delete(customer);*/

// 先查询再删除(推荐)--级联删除
Customer customer = session.get(Customer.class, 2l);
session.delete(customer);

tx.commit();
session.close();

}
5) 保存或更新:
void saveOrUpdate(Object obj)
copy
// 保存或更新
public void demo5(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();

/*Customer customer  = new Customer();
customer.setCust_name("王凤");
session.saveOrUpdate(customer);*/

Customer customer = new Customer();
customer.setCust_id(3l);
customer.setCust_name("李如花");
session.saveOrUpdate(customer);

tx.commit();
session.close();

}
6) 查询所有:
copy
// 查询所有
public void demo6(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();

// 接收HQL:Hibernate Query Language 面向对象的查询语言
/*Query query = session.createQuery("from Customer");
List<Customer> list = query.list();
for (Customer customer : list) {
    System.out.println(customer);
}*/

// 接收SQL:
SQLQuery query = session.createSQLQuery("select * from cst_customer");
List<Objects[]> list = query.list();
for (Objects[] object : list) {
    System.out.println(Arrays.toString(object));
}
tx.commit();
session.close();

}
四、持久化类的编写规则

1.什么是持久化?
    1) 持久化
        将内存中的一个对象持久化到数据库的过程,其中Hibernate框架正是持久化框架。
    2) 持久化类
        一个Java类与数据库的表建立了映射关系,那么该类在Hibernate中称为是持久化类。
2.编写规则?
    ①对持久化类提供一个无参数构造方法,原因:Hibernate底层需要使用反射生成实例。
    ②属性需要私有,对私有属性提供public的get和set方法,原因:Hibernate中获取,设置对象的值。
    ③对持久化类提供一个唯一标识OID与数据库主键对应,原因:数据库中通过主键确定是否是同一个记录。
    ④持久化类中属性尽量保证使用包装类类型,原因:基本数据类型默认是0,包装类类型默认值是null。
    ⑤持久化类不要用final进行修饰,原因:使得持久化类不能产生子类,从而不会产生代理对象,延迟加载策略就会失效。

五、主键生成策略

1.主键的分类
    1) 自然主键
        主键的本身就是表中的一个字段(实体中一个具体的属性)。
    2) 代理主键
        主键的本身不是表中必须的一个字段(不是实体中的某个具体的属性)。
2.生成策略
    1) increment
        Hibernate中提供的自动增长机制,适用short、int、long类型的主键,在单线程中使用。
    2) identity
        数据库底层的自动增长机制,适用short、int、long类型的主键。(支持Mysql,不支持Oracle)
    3) sequence
        采用序列的方式,适用short、int、long类型的主键。(支持Oracle、不支持Mysql)
    4) uuid
        适用于字符串类型的主键,使用Hibernate中的随机方式生成字符串主键。
    5) native
        本地策略,可以在identity和sequence之间自由切换。
    6) assigned
        Hibernate放弃外键的管理,需要通过手动编写程序或者用户自己设置。

六、持久化类的三种状态

1.瞬时态
    这种对象没有唯一标识OID,被session所管理。
2.持久态
    这种对象有唯一标识OID,被session所管理。
3.脱管态
    这种对象有唯一标识OID,没有被session管理。

copy
// 测试三种状态
public void demo1(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();

Customer customer  = new Customer(); // 瞬时态对象:没有持久化标识OID,没有被session管理
customer.setCust_name("王小西");
Serializable id = session.save(customer); // 持久化对象:有持久化标识OID,被session管理
tx.commit();
session.close();

System.out.println(customer); // 脱管态对象:有持久化标识OID,没有被session管理

}
4.持久化对象的状态转换
1) 瞬时态转化到其他态
获取瞬时态:使用new关键词创建。
瞬时态转化为持久态:执行Session的save()或saveOrUpdate()方法。
瞬时态转化为脱管态:为瞬时态对象设置持久化标识OID。
2) 持久态转化到其他态
获取持久态:通过Hibernate中session的get、load、Query查询等方法从数据库中获得。
持久态转化为瞬时态:执行Session的delete方法。
持久态转化为脱管态:执行Session的evict()、close()或clear()方法。
3) 脱管态转化到其他态
获取脱管态:不能直接获得,需通过其他态进行转化。
脱管态转化到瞬时态:将脱管态对象的持久化标识OID设置为null。
脱管态转化为持久态:执行Session的update()、saveUpdate()或lock()方法。
七、Hibernate的一级缓存

1.什么是缓存?
    是一种优化的方式,将数据存入到内存中,使用的时候直接从缓存中获取,不用通过存储源。
2.Hibernate的缓存
    一级缓存:称为是Session级别的缓存,一级缓存生命周期与Session一致(由Session中的一系列Java集合构成,自带不可卸载)。
    二级缓存:是SessionFactory级别的缓存,需要配置缓存。
3.Hibernate中的事务管理
    除了在代码中对事务开启,提交和回滚操作外,还可以在Hibernate的核心配置文件中对事务进行配置。

copy

4

thread
八、Hibernate其他API

1.Query
    1) 基本查询:

copy
//基本查询
public void fun1(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//1> 书写HQL语句
String hql = " from Customer "; // 查询所有Customer对象
//2> 根据HQL语句创建查询对象
Query query = session.createQuery(hql);
//3> 根据查询对象获得查询结果
List list = query.list(); // 返回list结果
//query.uniqueResult();//接收唯一的查询结果

System.out.println(list);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联

}
2) 别名查询
copy
//别名查询
public void demo3() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
// 别名的查询
/*
* Query query = session.createQuery(“from Customer c”);
* List list = query.list();
*/

Query query = session.createQuery("select c from Customer c");
List<Customer> list = query.list();

for (Customer customer : list) {
    System.out.println(customer);
}
tx.commit();

}
3) 排序查询
copy
//排序查询
public void demo4() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
// 排序的查询
// 默认情况
// List list = session.createQuery(“from Customer order by cust_id”).list();
// 设置降序排序 升序使用asc 降序使用desc
List list = session.createQuery(“from Customer order by cust_id desc”).list();

for (Customer customer : list) {
    System.out.println(customer);
}
tx.commit();

}
4) 条件查询
按位置绑定
copy
//条件查询
public void fun3(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//1> 书写HQL语句
String hql = " from Customer where cust_id = ? "; // 查询所有Customer对象
//2> 根据HQL语句创建查询对象
Query query = session.createQuery(hql);
//设置参数
//query.setLong(0, 1l);
query.setParameter(0, 1l);
//3> 根据查询对象获得查询结果
Customer c = (Customer) query.uniqueResult();

System.out.println(c);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联

}
按名称邦定
copy
//条件查询
public void fun4(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//1> 书写HQL语句
String hql = " from Customer where cust_id = :cust_id "; // 查询所有Customer对象
//2> 根据HQL语句创建查询对象
Query query = session.createQuery(hql);
//设置参数
query.setParameter(“cust_id”, 1l);
//3> 根据查询对象获得查询结果
Customer c = (Customer) query.uniqueResult();

System.out.println(c);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联

}
5) 投影查询
查询对象的某个或某些属性。
copy
// 投影查询
public void demo6() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();

// 投影查询
// 单个属性
/*
 * List<Object> list = session.createQuery("select c.cust_name from Customer c").list(); 
 * for (Object object : list) { 
 *  System.out.println(object); 
 * }
 */

// 多个属性:
/*
 * List<Object[]> list = session.createQuery("select c.cust_name,c.cust_source from Customer c").list(); 
 * for(Object[] objects : list) {
 *   System.out.println(Arrays.toString(objects)); }
 */

// 查询多个属性,但是我想封装到对象中。
List<Customer> list = session.createQuery("select new Customer(cust_name,cust_source) from Customer").list();
for (Customer customer : list) {
    System.out.println(customer);
}
tx.commit();

}
6) 分页查询
copy
//分页查询
public void fun5(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//1> 书写HQL语句
String hql = " from Customer "; // 查询所有Customer对象
//2> 根据HQL语句创建查询对象
Query query = session.createQuery(hql);
//设置分页信息 limit ?,?
query.setFirstResult(1);
query.setMaxResults(1);
//3> 根据查询对象获得查询结果
List list = query.list();

System.out.println(list);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联

}
7) 分组统计查询
copy
//分组统计查询
public void demo8() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();

// 聚合函数的使用:count(),max(),min(),avg(),sum()
Object object = session.createQuery("select count(*) from Customer").uniqueResult();
System.out.println(object);
// 分组统计:
List<Object[]> list = session.createQuery("select cust_source,count(*) from Customer group by cust_source").list();
for (Object[] objects : list) {
    System.out.println(Arrays.toString(objects));
}
tx.commit();

}
8) 多表查询
copy
//HQL的多表查询
public void demo9() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
// SQL:SELECT * FROM cst_customer c INNER JOIN cst_linkman l ON c.cust_id = l.lkm_cust_id;
// HQL:内连接 from Customer c inner join c.linkMans
/*
* List<Object[]> list = session.createQuery(“from Customer c inner join c.linkMans”).list();
* for (Object[] objects : list) {
* System.out.println(Arrays.toString(objects));
* }
*/

// HQL:迫切内连接 其实就在普通的内连接inner join后添加一个关键字fetch. from Customer c inner join fetch c.linkMans
List<Customer> list = session.createQuery("select distinct c from Customer c inner join fetch c.linkMans").list();// 通知hibernate,将另一个对象的数据封装到该对象中

for (Customer customer : list) {
    System.out.println(customer);
}
tx.commit();

}
2.Criteria
1) 基本查询
copy
//基本查询
public void fun1(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------

//查询所有的Customer对象
Criteria criteria = session.createCriteria(Customer.class);

List<Customer> list = criteria.list();

System.out.println(list);

//Customer c = (Customer) criteria.uniqueResult();

//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联 

}
2) 排序查询
copy
//排序查询
public void demo2(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();

// 排序查询
Criteria criteria = session.createCriteria(Customer.class);
// criteria.addOrder(Order.asc("cust_id")); // 升序
criteria.addOrder(Order.desc("cust_id")); // 降序
List<Customer> list = criteria.list();

for (Customer customer : list) {
    System.out.println(customer);
}

tx.commit();

}
3) 条件查询
copy
//条件查询
//HQL语句中,不可能出现任何数据库相关的信息的
// > gt
// >= ge
// < lt
// <= le
// == eq
// != ne
// in in
// between and between
// like like
// is not null isNotNull
// is null isNull
// or or
// and and
public void fun2(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//创建criteria查询对象
Criteria criteria = session.createCriteria(Customer.class);
//添加查询参数 => 查询cust_id为1的Customer对象
criteria.add(Restrictions.eq(“cust_id”, 1l));
//执行查询获得结果
Customer c = (Customer) criteria.uniqueResult();
System.out.println©;
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联
}
4) 分页查询
copy
//分页查询
public void fun3(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//创建criteria查询对象
Criteria criteria = session.createCriteria(Customer.class);
//设置分页信息 limit ?,?
criteria.setFirstResult(1);
criteria.setMaxResults(2);
//执行查询
List list = criteria.list();

System.out.println(list);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联

}
5) 查询总记录数
copy
//查询总记录数
public void fun4(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//创建criteria查询对象
Criteria criteria = session.createCriteria(Customer.class);
//设置查询的聚合函数 => 总行数
criteria.setProjection(Projections.rowCount());
//执行查询
Long count = (Long) criteria.uniqueResult();

System.out.println(count);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联

}
6) 离线条件查询
脱离session使用
copy
//离线条件查询
public void demo6(){
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Customer.class);
detachedCriteria.add(Restrictions.like(“cust_name”, “李%”));

Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();

Criteria criteria = detachedCriteria.getExecutableCriteria(session);
List<Customer> list = criteria.list();
for (Customer customer : list) {
    System.out.println(customer);
}
transaction.commit();

}
3.SQLQuery
1) 基本查询
copy
//基本查询
public void fun1(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//1 书写sql语句
String sql = “select * from cst_customer”;

//2 创建sql查询对象
SQLQuery query = session.createSQLQuery(sql);

//3 调用方法查询结果
List<Object[]> list = query.list();
//query.uniqueResult();

for(Object[] objs : list){
    System.out.println(Arrays.toString(objs));
}

//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联

}
copy
//基本查询
public void fun2(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//1 书写sql语句
String sql = “select * from cst_customer”;

//2 创建sql查询对象
SQLQuery query = session.createSQLQuery(sql);
//指定将结果集封装到哪个对象中
query.addEntity(Customer.class);

//3 调用方法查询结果
List<Customer> list = query.list();

System.out.println(list);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联

}
2) 条件查询
copy
//条件查询
public void fun3(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//1 书写sql语句
String sql = "select * from cst_customer where cust_id = ? ";

//2 创建sql查询对象
SQLQuery query = session.createSQLQuery(sql);

query.setParameter(0, 1l);
//指定将结果集封装到哪个对象中
query.addEntity(Customer.class);

//3 调用方法查询结果
List<Customer> list = query.list();

System.out.println(list);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联

}
3) 分页查询
copy
//分页查询
public void fun4(){
//1 获得session
Session session = HibernateUtils.openSession();
//2 控制事务
Transaction tx = session.beginTransaction();
//3执行操作
//-------------------------------------------
//1 书写sql语句
String sql = "select * from cst_customer limit ?,? ";

//2 创建sql查询对象
SQLQuery query = session.createSQLQuery(sql);

query.setParameter(0, 0);
query.setParameter(1, 1);
//指定将结果集封装到哪个对象中
query.addEntity(Customer.class);

//3 调用方法查询结果
List<Customer> list = query.list();

System.out.println(list);
//-------------------------------------------
//4提交事务.关闭资源
tx.commit();
session.close();// 游离|托管 状态, 有id , 没有关联

}
九、Hibernate一对多关联映射

1.一的情况配置
    1) 创建持久类(假如一个客户有多个联系人)

copy
// 一个客户有多个联系人:客户中应该放有联系人的集合。
private Set linkMans = new HashSet();
2) 客户的映射
copy

2.多的情况配置 1) 创建持久类(一个联系人对应一个客户) copy // 面向对象的ORM private Customer customer; 2) 联系人的映射 copy 十、Hibernate一对多级联操作
1.什么叫做级联
    级联指的是,操作一个对象的时候,是否会同时操作其关联的对象。
2.什么是级联的方向性
    操作一的一方的时候,是否操作到多的一方。
    操作多的一方的时候,是否操作到一的一方。
3.级联保存或更新
    1) 保存客户

copy

... 2) 保存联系人 copy 4.级联删除 删除一边的时候,同时将另一方的数据也一并删除。 copy ... 十一、Hibernate多对多关联映射
1.用户的配置(用户与角色多对多关系)

copy

2.角色的配置(角色与用户多对多关系) 因为多对多的关系中,采用的是中间表查询,所以必须有一方放弃外键维护权,一般由被动的一方放弃。 copy 十二、Hibernate的抓取策略(优化)
1.什么是延迟加载?
    也可以说是懒加载,执行到该行代码的时候,不会发送语句去进行查询,在真正使用这个对象的属性的时候才会发送SQL语句进行查询。
2.延迟加载的分类
    1) 类级别的延迟加载
        指的是通过load方法查询某个对象,是否采用延迟。(使懒加载失效:在class标签上配置的lazy属性或使用final修饰持久类)。
    2) 关联级别的延迟
        指的是在查询到某个对象的时候,查询其关联的对象,是否采用延迟加载。(使懒加载失效:在set或many-to-one标签上配置lazy属性)。
3.什么是抓取策略?
    Hibernate的抓取策略是Hibernate提升性能的一种手段,可以在获取关联对象的时候,对发送的语句进行优化,往往需要与延迟加载配合使用。
4.set上的fetch和lazy

copy
fetch:抓取策略,控制SQL语句格式
select :默认值,发送普通的select语句,查询关联对象
join :发送一条迫切左外连接查询关联对象
subselect :发送一条子查询查询其关联对象
lazy:延迟加载,控制查询关联对象的时候是否采用延迟
true :默认值,查询关联对象的时候,采用延迟加载
false :查询关联对象的时候,不采用延迟加载
extra :极其懒惰。
在实际开发中,一般都采用默认值。如果有特殊的需求,可能需要配置join。
5.many-to-one上的fetch和lazy
copy
fetch:抓取策略,控制SQL语句格式。
select :默认值,发送普通的select语句,查询关联对象。
join :发送一条迫切左外连接。
lazy:延迟加载,控制查询关联对象的时候是否采用延迟。
proxy :默认值,proxy具体的取值,取决于另一端的上的lazy的值。
false :查询关联对象,不采用延迟。
no-proxy :(不会使用)
在实际开发中,一般都采用默认值。如果有特殊的需求,可能需要配置join。
6.批量抓取
同时查询多个对象的关联对象的时候,可以采用批量抓取进行优化。如果要实现批量抓取,可以通过配置batch-size来完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值