美文网首页持久层ORM框架
Hibernate入门教程(三)

Hibernate入门教程(三)

作者: 叩丁狼教育 | 来源:发表于2018-05-19 10:14 被阅读95次

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

    在上面的章节中,我们使用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.eq equal,等于
    Restrictions.allEq 参数为Map对象,使用key/value进行多个等于的比对,相当于多个Restrictions.eq 的效果
    Restrictions.gt 大于
    Restrictions.ge 大于等于
    Restrictions.lt less-than, < 小于
    Restrictions.le less-equal <= 小于等于
    Restrictions.between 对应SQL的between子句
    Restrictions.like 对应SQL的LIKE子句
    Restrictions.in 对应SQL的in子句
    Restrictions.and and 关系
    Restrictions.or or 关系
    Restrictions.isNull 判断属性是否为空,为空则返回true 相当于SQL的 is null
    Restrictions.isNotNull 与isNull相反 相当于SQL的 is not null
    Restrictions.sqlRestriction SQL限定的查询
    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的使用上有所帮助, 可以把这一节的内容当做参考资料来使用

    WechatIMG7.jpeg

    相关文章

      网友评论

      本文标题:Hibernate入门教程(三)

      本文链接:https://www.haomeiwen.com/subject/lbsodftx.html