Hibernate入门教程(三)

这篇博客由叩丁狼教育高级讲师钟昕灵撰写,深入浅出地介绍了Hibernate入门知识。内容涵盖了Configuration、SessionFactory、Session、Transaction、Query、Criteria和NativeQuery的使用,帮助读者理解Hibernate中的常用API,包括数据的保存、删除、更新、查询等操作,并提供了实例演示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

讲师:钟昕灵,叩丁狼教育高级讲师。原创文章,转载请注明出处。

在上面的章节中,我们使用Hibernate完成了基本的CRUD,并对相关操作的执行流程进行了分析,相信大家对Hibernate的简单使用有了一定的了解,那么,接下来,我们来了解一下Hibernate中常用的API.

1. Configuration
  • Configuration conf = new Configuration();
    创建配置Configuration对象,同时加载classpath路径下的名称为hibernate.properties的文件
    常用方法:
  • Configuration configure();
    如果创建Configuration对象后不调用该方法,hibernate是默认加载classpath下的hibernate.properties文件
    调用该方法表示加载classpath下名称为hibernate.cfg.xml的配置文件
  • Configuration configure(String configureFileName);
    如果在我们的项目中配置文件的名称不是使用默认的名称,那么可以指定记载的配置文件名称
  • Configuration addResource(String resourceName)
    通常,我们在hibernate.cfg.xml文件中会指定加载的映射文件
<mapping resource="cn/wolfcode/_01_hello/User.hbm.xml" />

如果不使用上面这种配置文件的方式,我们还可以使用addResource方法指定要加载的映射文件

conf.addResource("cn/wolfcode/_01_hello/User.hbm.xml");
  • Configuration addClass(Class persistentClass);
    加载映射文件也可以使用该方法实现,如下
conf.addClass(User.class);

此时hibernate会找和User类同路径的名称为User.hbm.xml的映射文件

  • SessionFactory buildSessionFactory();
    创建SessionFactory对象
    2. SessionFactory

SessionFactory负责管理Session,管理连接池,管理Hibernate二级缓存以及预定义的SQL语句。
SessionFactory是一个重量级的(创建该对象的时候需要加载较多的资源文件,或者说创建对象比较耗时), 线程安全的对象(允许多线程并发访问),基于此,通常在一个hibernate应用中,我们只需要一个SessionFactory对象,所以,我们可以使用如下来创建SessionFactory对象

public class HibernateUtil {

    private static SessionFactory sessionFactory;

    static {
        //当前工具类被加载的时候,执行该静态代码块初始化SessionFactory对象
        sessionFactory = 
                new Configuration()
                    .configure()//加载classpath中的hibernate.cfg.xml文件
                    .buildSessionFactory();
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

HibernateUtil.getSessionFactory() 能够保证在一个应用中只有一个SessionFactory对象

常用API:
Session openSession();从连接池中获取一个连接对象,构造Session对象
Session getCurrentSession();获取和当前线程绑定的连接对象(ThreadLocal),构造Session对象

3. Session

Session是Hibernate程序与数据库之间的桥梁。完成CRUD的操作。Session是一个单线程的对象(线程不安全),需要每个访问数据库的操作创建一个单独的Session对象; 内部维护了Hibernate的一级缓存。
常用API:

  • Serializable save(Object object);
    执行保存操作,hibernate会根据传入的参数对象,拼接出对应的INSERT语句,在事务中进行
  • void delete(Object object);
    执行删除数据操作,将需要删除数据的主键信息封装到一个对象中,然后hibernate为我们自动的生成对应的DELETE语句,在事务中进行
  • void update(Object object);
    执行更新操作,将需要更新的数据封装到一个对象中,然后hibernate为我们生成对应的UPDATE语句,在事务中进行
  • Object get(Class clazz, Serializable id);
    执行单行数据的查询,传入要查询数据的类型,和数据对应的主键id,返回查询到的数据,将其封装到指定类型的对象中,不在事务中进行
  • Query createQuery(String queryString);
    创建查询对象,执行传入的HQL语句
    如:SELECT u FROM User u
    这里的User是Java中的User类,而不是数据库中的user表
  • CriteriaBuilder getCriteriaBuilder();
    Criteria构建器,用来创建Criteria对象,Criteria是一种比hql更面向对象的查询方式
  • NativeQuery createNativeQuery(String sqlString)
    创建本地SQL查询对象,执行传入的SQL语句,这种方式可以执行按需求的,高效率的SQL语句,缺点是会和使用的数据库高度耦合
4. Transaction

hibernate中的事务管理器,封装事务管理的基本操作

void begin();开启事务
void commit();提交事务
void rollback();回滚事务
void boolean isActive();判断当前事务是否是活动有效的

在这里,我们只是将事务相关的API进行了简单的罗列出来,在后面,我们会单独有一节的内容来讨论Hibernate中事务管理相关的内容

5. Query

以面向对象的思想执行数据的各种查询操作
Query query = session.createQuery(hqlString);//hqlString:hibernate提供的hibernate查询语言(Hibernate Query Language)

通过以下案例来熟悉一下Query对象的使用:

  • 查询user表中的所有数据(包含所有的列)
String hql = "FROM User";
List<User> list = session.createQuery(hql).list();

注:

  1. 大家在写hql的时候,可以和之前写过的sql进行对比,sql出现的表或者列分别对应这里的类或者属性,所以在写的时候需要多加注意
  2. 查询所有的列的数据可以使用如上的简写方式,等同于下面的hql
String hql = "SELECT uid,uusername,upassword,uage,uhiredate";
  1. list()方法表示查询多条数据,将结果封装到List集合中
  2. hibernate最终会将结合对应的映射文件,将hql解析为sql(把类名转换为表名,把属性名转换为列名等)
  • 查询user表中的所有数据(包含部分的列,name/age/hiredate)
String hql = "SELECT uname,uage,uhiredate FROM User";
List<User> list = session.createQuery(hql).list();
  • 查询单条数据
    在Query中提供了两个方法用来获取并封装单条数据或单个数据的结果集
    uniqueResult() 和 getSingleResult()
// 查询一行数据将其封装成一个User类型的对象
User user = (User) session.createQuery("FROM User WHERE uusername = ?")
                .setParameter(0, "Neld").uniqueResult();
//查询user表中的总记录数
long count = (long) session.createQuery("select count(uid) FROM User").uniqueResult();
  • 为查询设置查询条件需要的参数
    如果hql的执行需要参数的话,我们可以和sql语句一样的是写方式,使用?作为占位符,然后在执行之前设置参数
    // 使用索引为指定位置的占位符设置参数(从0开始)
    Query setParameter(int position, Object value);
    // 使用参数的名称为参数赋值
    Query setParameter(String paramName, Object value);
方式一:使用索引为参数赋值
List<User> list = session.createQuery("FROM User WHERE age >= ? AND age <= ?")
  .setParameter(0, 10)// 0,表示第一个?占位符
  .setParameter(1, 20)
  .list();

方式二:为参数命名,然后为指定名称的参数赋值,直接将?替换为:参数名的格式
List<User> list = session.createQuery("FROM User 
        WHERE age >= :minAge AND age <= :maxAge")
    .setParameter("minAge", 10)
    .setParameter("maxAge", 20).list();

方式二在关键字查询中使用的较多(多个参数需要的是相同的数据),如:

List<User> list = session.createQuery("FROM Product
        WHERE name LIKE :keyword OR brandName LIKE :keyword")
    .setParameter("keyword", "%e%")//此时只需要为名称为keyword的参数赋值即可
    .list();
  • 分页查询
    Query setFirstResult(int startPosition);//设置查询的第一条数据的索引,从0开始
    Query setMaxResults(int maxResult);//设置一页最多显示数据的条数
List<User> list = session.createQuery(
    "FROM Product WHERE name LIKE :keyword OR brandName LIKE :keyword")
    .setParameter("keyword","%n%")
    .setFirstResult(0)//从索引为0的数据开始查询
    .setMaxResults(2)//每页最多显示两条数据
    .list();

在mysql中对应的sql: LIMIT ?, ?

6. Criteria

主要为了解决多条件查询问题,以面向对象的方式添加条件,无需拼接HQL语句
Criteria criteria = session.createCriteria(User.class);
createCriteria()方法在hibernate5.2之后已经标注为过期,建议使用JAP中的Criteria实现
在此,我们姑且先用用该方法,简单认识一下Criteria对象的使用.例子和上面的一样,目的是通过对比学习效果更直接

  • 查询user表中的所有数据(包含所有的列)
List<User> list = session.createCriteria(User.class).list();
  • 查询单条数据
User user2 = (User) session.createCriteria(User.class)
    .add(Restrictions.eq("uusername", "Neld"))//为查询添加过滤条件
    .uniqueResult();//查询得到单行数据,并封装在一个对象中
  • 为查询设置各种条件
List<User> users = 
    session.createCriteria(User.class)
        // 设置根据uusername的模糊查询,MatchMode.ANYWHERE表示包含设置的参数即可,等同于: %n%
        .add(Restrictions.like("uusername", "n", MatchMode.ANYWHERE))
         // 设置根据uage的范围查询,相当于sql中的between...and
        .add(Restrictions.between("uage", 10, 20))
        // 设置根据uhiredate的范围查询(greater equals),相当于sql中的: >=
        .add(Restrictions.ge("uhiredate", d))
        .list();
  • 分页查询
    同Query对象中的分页实现的方式一样
List<User> users = session.createCriteria(User.class)
    .setFirstResult(0)
    .setMaxResults(2)
    .list();

最后补充一下QBC(Query By Criteria)中的常用限定方法

限定方法描述
Restrictions.eqequal,等于
Restrictions.allEq参数为Map对象,使用key/value进行多个等于的比对,相当于多个Restrictions.eq 的效果
Restrictions.gt大于
Restrictions.ge大于等于
Restrictions.ltless-than, < 小于
Restrictions.leless-equal <= 小于等于
Restrictions.between对应SQL的between子句
Restrictions.like对应SQL的LIKE子句
Restrictions.in对应SQL的in子句
Restrictions.andand 关系
Restrictions.oror 关系
Restrictions.isNull判断属性是否为空,为空则返回true 相当于SQL的 is null
Restrictions.isNotNull与isNull相反 相当于SQL的 is not null
Restrictions.sqlRestrictionSQL限定的查询
Order.asc根据传入的字段进行升序排序
Order.desc根据传入的字段进行降序排序
MatchMode.EXACT字符串精确匹配.相当于”like ‘value’”
MatchMode.ANYWHERE字符串在中间匹配.相当于”like ‘%value%’”
MatchMode.START字符串在最前面的位置.相当于”like ‘value%’”
MatchMode.END字符串在最后面的位置.相当于”like ‘%value’”
7. NativeQuery

这是5.2之后新API,同之前的SQLQuery作用一致,执行传入的SQL语句,因为是直接使用sql语句,相信大家是很熟悉的了,这里我们将上面的一个栗子换成使用NativeQuery对象来实现

String sql = "SELECT * FROM user 
              WHERE username LIKE ? AND age BETWEEN ? AND ? LIMIT ?, ?";
List<Object[]> list2 = session.createNativeQuery(sql)
                 .setParameter(1, "%n%")
                 .setParameter(2, 10)
                 .setParameter(3, 20)
                 .setParameter(4, 0)
                 .setParameter(5, 2)
                 .list();

这里返回的是一个List<Object[]>,hibernate是将没行数据封装在一个Object[]数组中的,所以,需要从数据中获取我们需要的数据

小结

这一节,我们对Hibernate中的常用API作了一个简单的整理和分析,希望对大家在Hibernate的基本API的使用上有所帮助, 可以把这一节的内容当做参考资料来使用


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值