Java进阶01:Hibernate教程

2023-11-14

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来完成。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java进阶01:Hibernate教程 的相关文章

随机推荐

  • 如何破解Studio 3T (MongoDB可视化工具)

    首先新建一个记事本 写入如下内容 echo off ECHO 重置Studio 3T的使用日期 FOR f tokens 1 2 i IN reg query HKEY CURRENT USER Software JavaSoft Pref
  • MOS管漏电流产生的原因

    功耗是由漏电流引起的 尤其是在较低阈值电压下 了解MOS晶体管漏电流的六种不同原因 1 反向偏置pn结泄漏电流 在晶体管操作期间 MOS晶体管的漏极 源极和衬底结被反向偏置 因此 器件的漏电流被反向偏置 这种漏电流可能是由反向偏置区域中的少
  • windows自带磁盘修复命令chkdsk的使用方法

    在电脑使用过程会因突然断电或者是非正常关机等原因导致磁盘受损 这里介绍Windows系统自带chkdsk命令修复硬盘 2022 10 26补充 专业硬盘维修的朋友告诉我此命令不要随意使用 尤其硬盘已经有坏道 用该方法可能导致更严重的问题 大
  • python数据抓取中空格的影响

    在python数据抓取中 多一个空格或少一个空格 中间的差异的很大的 抓取一个网站 在定位后 只抓取前五行 无意中多了一个空格 数据一直不能正常显示 经过调试后 将空格去掉 定位的数据正常显示 如下
  • Matplotlib基本参数设置

    文章目录 Matplotlib基本参数设置 1 添加图标题 坐标轴标题 图例 2 添加坐标轴范围 画布网格 3 添加图形标注 4 改变横坐标和纵坐标上的刻度 ticks 5 中文支持相关设置 6 定义图形样式 Matplotlib基本参数设
  • python3集成matplotlib画图中文乱码的解决方法

    问题描述 在python中使用matplotlib画图 里面的中文会显示乱码方块 解决方法前提依赖 这是由于matplotlib默认使用的字体中不包含中文字符引起的 可以通过将中文字符加入到默认字体中解决 前提 查找本地都有哪些中文字体 打
  • 利用机器学习进行恶意代码分类

    原文链接 http drops wooyun org tips 8151 最近在Kaggle上微软发起了一个恶意代码分类的比赛 并提供了超过500G的数据 解压后 有意思的是 取得第一名的队伍三个人都不是搞安全出身的 所采用的方法与我们常见
  • IOC与DI总结

    编写流程 基于XML 导入jar包 4 1 gt beans core context expression commons logging 编写目标类 dao和service spring配置文件 IoC
  • Flutter获取屏幕及设备信息

    获取状态栏高度 import dart ui MediaQueryData fromWindow window padding top MediaQuery of context padding top 获取系统默认的AppBar等高度 位
  • web前端技术练习题

    选择题 1 以下哪个不属于Web前端开发的核心技术 A HTML C JavaScript B CSS D Java 2 关于HTML说法错误的是 A HTML标签的嵌套结构可以描述成一个网状结构 B 在 title 和 title 标签之
  • C语言字符型数据(一)—简单的恺撒密码

    首先声明 这些内容主要是面向C语言的初学者 尤其是正在学习C语言的学生 学习C语言的字符型数据时 首先需要记住两条重要特性 1 字符型数据存储的是字符的ASCII码值 2 由于ASCII码值本质上是一个整数 因此字符型数据可以像整数一样做加
  • MySQL行级锁、表级锁、页级锁详细介绍

    页级 引擎 BDB 表级 引擎 MyISAM 理解为锁住整个表 可以同时读 写不行行级 引擎 INNODB 单独的一行记录加锁 表级 直接锁定整张表 在你锁定期间 其它进程无法对该表进行写操作 如果你是写锁 则其它进程则读也不允许行级 仅对
  • python学习 - 存钱问题

    问题描述 父亲准备为小龙的四年大学生活一次性储蓄一笔钱 使用整存零取的方式 控制小龙每月月初取1000元准备这个月使用 假设银行整存零取的年息为1 71 请算出父亲至少需要存入多少钱才行 问题分析 这个问题是一个典型的递推问题 分析存钱和取
  • 蓝牙协议栈实现模式分析

    蓝牙协议栈实现模式分析 广州大学信息与机电工程学院 510405 邹艳碧 广州大学理学院 510405 吴智量 广州大学信息与机电工程学院 510405 李朝晖 摘要 蓝牙技术是未耒无线通信的一个重要的研究方向 本文主要介绍了蓝牙 技术的体
  • Matlab 仿真BPSK调制下传输的误码率

    BPSK Binary Phase Shift Keying 把模拟信号转换成数据值的转换方式之一 利用偏离相位的复数波浪组合来表现信息键控移相方式 我们可以用Matlab仿真其传输误码率 m文件内容如下 传输1000000个码 随机 1
  • 基于java springboot vue仓库管理系统源码(毕设)

    开发环境及工具 大于Jdk1 8 大于mysql5 5 idea eclipse vscode webstorm 技术说明 Springboot mybatis vue elementui 代码注释齐全 没有多余代码 适合学习 毕设 二次开
  • 优雅地测试Exception:@Rule

    使用 Rule测试Exception 导入库 import org junit Rule import org junit rules ExpectedException 声明错误期望对象 Rule public ExpectedExcep
  • javaweb项目总结思路

    JAVAweb项目思路指南 本次项目所用技术 第一章 需求 系统用户模块 员工管理模块 系统权限功能 第二章 数据库设计 创建数据库 用户表 员工表 第三章 架构选择 第四章 搭建系统开发 搭建系统开发环境 编写实体类 编写user实体类
  • 类和对象【默认成员函数】

    全文目录 类的6个默认成员函数 构造函数 特性 析构函数 特性 拷贝构造函数 特性 赋值运算符重载 运算符重载 赋值运算符重载 前置 和 后置 const 成员 取地址及const取地址操作符重载 类的6个默认成员函数 每个类不管有没有内容
  • Java进阶01:Hibernate教程

    1 什么是Hibernate Hibernate是一个开放源码的ORM Object Relational Mapping 对象关系映射 框架 它对JDBC进行了轻量级的封装 使得Java开发人员可以使用面向对象的编程思想来操作数据库 2