• JavaWeb学习:Hibernate的API


    一、Configuration:加载配置文件

    1、加载数据库连接配置文件

      1.1、属性配置文件(hibernate.properties)  

        // 1.1.属性文件加载
        Configuration configuration=new Configuration();
        // 1.2.加载映射文件
        configuration.addResource("com/marw/util/Customer.hbm.xml");    

      1.2、hibernate.cfg.xml    

    Configuration configuration=new Configuration().configure();

    2、加载映射配置文件

      2.1、对属性配置文件(hibernate.properties)加载映射文件

        configuration.addResource("com/marw/util/Customer.hbm.xml"); 

    二、SessionFactory:内部维护了Hibernate的连接池和Hibernate的二级缓存。是线程安全的对象。一个项目创建一个对象即可。

      配置连接池

        1、导入jar包

        2、配置c3p0到核心配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
        <!-- 
            以上规约内容是 hibernate-core-5.x.Final.jar包中
            org.hibernate => hibernate-configuration-3.0.dtd 
        -->
    <hibernate-configuration>
        <session-factory>
            <!-- 连接数据库基本参数 -->
            <property name="hibernate.connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
            <property name="hibernate.connection.url">jdbc:sqlserver://localhost:1433;databaseName=HibernateDB;</property>
            <property name="hibernate.connection.username">sa</property>
            <property name="hibernate.connection.password">AAA@111</property>
            
            <!-- 配置Hibernate的方言 -->
            <property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
            <!-- 可选配置start -->
            <!-- 控制台打印sql语句 -->
            <property name="hibernate.show_sql">true</property>
            <!-- 控制台打印sql语句 格式化-->
            <property name="hibernate.format_sql">true</property>
            
            <property name="hibernate.hbm2ddl.auto">update</property>
            <!-- 可选配置end -->
            
            <!-- 配置C3P0连接池 -->
            <property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
            <!--在连接池中可用的数据库连接的最少数目 -->
            <property name="c3p0.min_size">5</property>
            <!--在连接池中所有数据库连接的最大数目  -->
            <property name="c3p0.max_size">20</property>
            <!--设定数据库连接的过期时间,以秒为单位,
            如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 -->
            <property name="c3p0.timeout">120</property>
             <!--每3000秒检查所有连接池中的空闲连接 以秒为单位-->
            <property name="c3p0.idle_test_period">3000</property>
            
            <!-- 配置映射 -->
            <mapping resource="com/marw/util/Customer.hbm.xml"/>
        </session-factory>
    </hibernate-configuration>

      一个项目只创建一个SessionFactory

    package com.marw.util;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    
    /**
    * @Title: HibernateUtils
    * @Description: 
    * @author: marw
    * @date 2020/11/03 17:00:26
    */
    public class HibernateUtils {
        private static Configuration confg;
        
        private static SessionFactory factory;
        
        static {
        confg=new Configuration().configure();
        factory=confg.buildSessionFactory();
        }
        
        public static Session openSession() {
        return factory.openSession();
        }
    }
    @Test
        public void demo2() {
        Session session=HibernateUtils.openSession();
        // 4.开启事务(Hibernate版本5不用手动开启事务,要兼容版本3需要手动开启事务)
        Transaction transaction=session.beginTransaction();
        // 5.编写代码
        Customer customer=new Customer();
        customer.setCust_name("zhang");
        
        session.save(customer);
        // 6.提交事务
        transaction.commit();
        // 7.资源释放
        session.close();
        }

    三、Session:Hibernate与数据库的链接对象。不是线程安全的(必须定义在方法内部,不能作为全局变量)。与数据库交互桥梁。

      Session中的API    

        保存方法:

          Serializable save(Object obj);

        查询方法:

          T get(Class c,Serializable id);

          T load(Class c,Serializable id);

        get方法和load方法的区别?

          get:立即加载,返回值为对象,查询一个找不到的对象,返回null

          load:延迟加载,返回值为代理对象,查询一个找不到的对象,返回ObjectNotFoundException    

        更新方法:

          void update(Object obj);

      @Test
        public void demo3() {
        Session session=HibernateUtils.openSession();
        Transaction transaction=session.beginTransaction();
        // 1.直接修改,不该修改的字段也被修改了
        /*
         * Customer customer=new Customer(); 
         * customer.setCust_name("zhang");
         * session.update(customer);
         */
        
        // 2.先查询,再修改,只会修改我们要修改的字段
        Customer customer=session.get(Customer.class, 1L);
        customer.setCust_name("zhang");    
        session.update(customer);
        
        // 6.提交事务
        transaction.commit();
        // 7.资源释放
        session.close();
        }

        删除方法:

          void delete(Object obj);      

      @Test
        public void demo4() {
        Session session=HibernateUtils.openSession();
        Transaction transaction=session.beginTransaction();
        // 1.直接删除
        /*
         * Customer customer=new Customer(); 
         * customer.setCust_id("1L");
         * session.delete(customer);
         */
        
        // 2.先查询,再删除,如果有级联关系使用查询后删除
        Customer customer=session.get(Customer.class, 2L);
        session.delete(customer);
        
        // 6.提交事务
        transaction.commit();
        // 7.资源释放
        session.close();
        }

        保存或更新:

          void saveOrUpdate(Object obj)    

        @Test
        public void demo5() {
        Session session=HibernateUtils.openSession();
        Transaction transaction=session.beginTransaction();
        /*
         * Customer customer=new Customer(); 
         * customer.setCust_name("lisi");
         * session.saveOrUpdate(customer);
         */
        
        Customer customer=new Customer();
        customer.setCust_id(3L);
        customer.setCust_name("wangwu");
        session.saveOrUpdate(customer);
        
        // 6.提交事务
        transaction.commit();
        // 7.资源释放
        session.close();
        }

        查询所有

    @Test
        public void demo6() {
        Session session=HibernateUtils.openSession();
        Transaction transaction=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<Object[]> list= query.list();
        for (Object[] objects : list) {
            System.out.println(Arrays.toString(objects));
        }
        // 6.提交事务
        transaction.commit();
        // 7.资源释放
        session.close();
        }

       ①、HQL

    @Test
        public void demoQuery() {
        Session session = HibernateUtils.openSession();
        Transaction transaction = session.beginTransaction();
        // 简单查询
        String hql = "from Customer";
    
        // 条件查询 -- 在hibernate4.1之后已经对HQL查询参数中的占位符做了改进
    
        String hql = "from Customer where cust_name like ?";
        // 第一种:
        String hql = "from Customer where cust_name like ?0";
        Query query = session.createQuery(hql);
        // 设置条件
        query.setParameter(0, "z%");
        // 第二种
        String hql = "from Customer where cust_name like :cust_names";
        Query query = session.createQuery(hql);
        // 设置条件
        query.setParameter(cust_names, "z%");
    
        // 分页查询
        String hql = "from Customer where cust_name like :cust_name";
        Query<Customer> query = session.createQuery(hql);
        query.setParameter("cust_name", "z%");
        // 设置分页
        query.setFirstResult(0);
        query.setMaxResults(3);
    
        List<Customer> list = query.list();
        for (Customer customer : list) {
            System.out.println(customer);
        }
    
        transaction.commit();
        }

      ②、Criteria:QBC Query By Criteria

    @Test
        public void demoCriteria() {
        Session session = HibernateUtils.openSession();
        Transaction transaction = session.beginTransaction();
        //查询所有
        /*
         * Criteria criteria = session.createCriteria(Customer.class); 
         * List<Customer> list = criteria.list();
         */
        
        //设置条件
        Criteria criteria = session.createCriteria(Customer.class);
        //criteria.add(Restrictions.like("cust_name", "zh",MatchMode.START));//相当于criteria.add(Restrictions.like("cust_name", "zh%"));
        //分页
        criteria.setFirstResult(0);
        criteria.setMaxResults(3);
        List<Customer> list = criteria.list();
        for (Customer customer : list) {
            System.out.println(customer);
        }
    
        transaction.commit();
        session.close();
        }

      注意:HQL、QBC两个Demo在实现分页调用setFirstResult和setMaxResults方法一直报java.lang.UnsupportedOperationException: query result offset is not supported的异常

    解决方法:修改hibernate方言 

    <property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>

     改为

    <property name="hibernate.dialect">org.hibernate.dialect.SQLServer2008Dialect</property>

    Control输出内容

    Hibernate: 
        WITH query AS (SELECT
            inner_query.*,
            ROW_NUMBER() OVER (
        ORDER BY
            CURRENT_TIMESTAMP) as __hibernate_row_nr__ 
        FROM
            ( select
                this_.cust_id as cust_id1_0_0_,
                this_.cust_name as cust_nam2_0_0_,
                this_.cust_source as cust_sou3_0_0_,
                this_.cust_industry as cust_ind4_0_0_,
                this_.cust_level as cust_lev5_0_0_,
                this_.cust_phone as cust_pho6_0_0_,
                this_.cust_mobile as cust_mob7_0_0_ 
            from
                cst_customer this_ ) inner_query ) SELECT
                cust_id1_0_0_,
                cust_nam2_0_0_,
                cust_sou3_0_0_,
                cust_ind4_0_0_,
                cust_lev5_0_0_,
                cust_pho6_0_0_,
                cust_mob7_0_0_ 
            FROM
                query 
            WHERE
                __hibernate_row_nr__ >= ? 
                AND __hibernate_row_nr__ < ?
  • 相关阅读:
    记处理PostgreSQL连接太多的问题
    记服务器迁移上云出现故障
    PostgreSQL-迁移同步序列
    为什么你的pgbouncer连接这么慢
    TS基础知识储备
    前端实在好用的工具类库 【后续持续添加若有请留言添加积累供大家使用】
    Vue 3 + Typescript + Vite2.0 搭建移动端 代码规范以及注意的点
    flutter2.0 环境搭建(window环境下Mac自行查看官网即可)
    vite2.0+vue3+ts前端最新热门技术项目搭建
    React官方状态管理库—— Recoil
  • 原文地址:https://www.cnblogs.com/WarBlog/p/13921567.html
Copyright © 2020-2023  润新知