zoukankan      html  css  js  c++  java
  • Hibernate学习(六)

    Hibernate的三种查询方式

    1、Criteria 查询 ,Query  By Criteria ( QBC )JPA 规范中定义的一种查询方法,但是不推荐使用

    2、HQL : Hibernate Query Language , Hibernate 查询语言 ( 建议使用 )

    3、Native SQL : Native SQL Query , 使用原生 SQL 语句进行查询

    4、OID:根据id查询某一条记录

    • <T> T get(Class<T> entityType,Serializable id) 从数据库汇总查询一条记录并封装成一个相应类型的Java对象

                  默认不支持延迟加载,当id对应的数据不存在时返回null

    • <T> T load(Class<T> theClass,Serializable id)  从数据库汇总查询一条记录并封装成一个相应类型的Java对象

                  默认支持延迟加载,当id对应的数据不存在时抛出ObjectNotFoundException

    • <T> T find(Class<T> entityClass, Object primaryKey)  从数据库汇总查询一条记录并封装成一个相应类型的Java对象    javax.persistence.EntityManager中的

                  默认不支持延迟加载,当id对应的数据不存在时返回null

    5、对象导航方式查询:一个对象关联一个集合(一对多),hibernate会自动检索关联集合的数据

    • 比如一个班级中有多个学生,在班级的持久类中定义了private Set<Student> students属性,可以通过班级持久化类可以获取students。

    Hibernate Query Language

    1、查询所有

    package ecut.query.test.hql;
    
    import java.lang.reflect.Array;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    import org.hibernate.query.Query;
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    import ecut.query.entity.Clazz;
    
    public class TestHibernateQuery1 {
        private SessionFactory factory ;
        private Session session ; 
        
        public @Before void init() {
            // 创建一个 Configuration 对象,用来读取配置文件 ( 默认位置、默认名称 )
            Configuration config = new Configuration();
            // 读取配置文件
            config.configure("ecut/query/hibernate.cfg.xml");
            //config.configure(); // 读取 默认位置 ( 当前 classpath ) 的 默认名称 ( hibernate.cfg.xml ) 的配置文件
    
            // 使用 Configuration 创建 SessionFactory
            factory = config.buildSessionFactory();
            
            // 创建 Session 对象 ( 这里的 Session 是 Java 程序 跟 数据库 之间的 会话 )
            session = factory.openSession();
        }
        
        /** 查询  Clazz 类 对应的表中的所有数据并 封装成  Clazz 对象 组成的 集合 */
        public @Test void query1(){
            
            String HQL = "FROM  Clazz" ; // 建议 所有的 SQL 关键字 一律大写
            
            // 通过 session 对象 来创建一个 查询器
            // session.createQuery( HQL ); // 如果类型不明确,可以采用该方法
            Query<Clazz>  queryer = session.createQuery( HQL , Clazz.class ) ; // 如果类型能够确定,建议指定类型
            System.out.println( "~~~~~~~~~~~~~~~~~~~" );
            List<Clazz> list = queryer.list() ; // 执行查询操作 ( 与 queryer.getResultList() 功能 相似 )
            System.out.println( list.size() );
            
            for( Clazz c : list ){
                System.out.println( c.getName() );
            }
            
        }
        
        /** 查询  Clazz 类 对应的表中的所有数据并 封装成  Clazz 对象 组成的 集合 */
        public @Test void query2(){
            
            String HQL = "SELECT c FROM  Clazz AS c" ; // 建议 所有的 SQL 关键字 一律大写
            
            Query<Clazz>  queryer = session.createQuery( HQL , Clazz.class ) ; 
            System.out.println( "~~~~~~~~~~~~~~~~~~~" );
            List<Clazz> list = queryer.list() ; // 执行查询操作
            
            for( Clazz c : list ){
                System.out.println( c.getName() );
            }
            
        }
        
        /** N + 1 问题  */
        @SuppressWarnings("deprecation")
        public @Test void query3(){
            
            String HQL = "SELECT c FROM  Clazz AS c" ; // 建议 所有的 SQL 关键字 一律大写
            
            Query<Clazz>  queryer = session.createQuery( HQL , Clazz.class ) ;
            
            System.out.println( "~~~~~~~~~~~~~~~~~~~" );
            
            // 第一次查询 ( 查询所有的对象标识符 )
            Iterator<Clazz> it = queryer.iterate(); // 执行查询操作 ( 但是 只获取 每个对象对应的 对象标识符 )
            
            // 每循环一次 就查询一条记录 ( N )
            while( it.hasNext() ){
                Clazz c = it.next();
                System.out.println( c.getId() + " : " + c.getName() );
            }
            
        }
        public @After void destory(){
            session.close();
            factory.close();
        }
    
    }

    HQL语句可以是SELECT c FROM  Clazz AS c 也可以将SELECT省略,除了可以使用list方法,也可以使用iterate方法(已过时)获取,每循环一次就查询一次记录,有N条记录就查询N次,调用iterate方法时也会调用一次查询获取所有对象的标识符,一共查询了N+1次即是N+1问题。

    2、条件查询和排序查询

    package ecut.query.test.hql;
    
    import java.lang.reflect.Array;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    import org.hibernate.query.Query;
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    import ecut.query.entity.Clazz;
    
    public class TestHibernateQuery1 {
        private SessionFactory factory ;
        private Session session ; 
        
        public @Before void init() {
            // 创建一个 Configuration 对象,用来读取配置文件 ( 默认位置、默认名称 )
            Configuration config = new Configuration();
            // 读取配置文件
            config.configure("ecut/query/hibernate.cfg.xml");
            //config.configure(); // 读取 默认位置 ( 当前 classpath ) 的 默认名称 ( hibernate.cfg.xml ) 的配置文件
    
            // 使用 Configuration 创建 SessionFactory
            factory = config.buildSessionFactory();
            
            // 创建 Session 对象 ( 这里的 Session 是 Java 程序 跟 数据库 之间的 会话 )
            session = factory.openSession();
        }
    
        /** 使用 条件过滤 和 排序 */
        public @Test void query4(){
            
            String HQL = "FROM  Clazz AS c WHERE c.id > 4 ORDER BY c.id DESC" ;
            
            Query<Clazz>  queryer = session.createQuery( HQL , Clazz.class ) ; 
    
            List<Clazz> list = queryer.list() ; // 执行查询操作
            
            for( Clazz c : list ){
                System.out.println( c.getId() + " : " + c.getName() );
            }
            
        }
    
        
        public @After void destory(){
            session.close();
            factory.close();
        }
    
    }

    3、标量查询(投影查询)

    package ecut.query.test.hql;
    
    import java.lang.reflect.Array;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    import org.hibernate.query.Query;
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    import ecut.query.entity.Clazz;
    
    public class TestHibernateQuery1 {
        private SessionFactory factory ;
        private Session session ; 
        
        public @Before void init() {
            // 创建一个 Configuration 对象,用来读取配置文件 ( 默认位置、默认名称 )
            Configuration config = new Configuration();
            // 读取配置文件
            config.configure("ecut/query/hibernate.cfg.xml");
            //config.configure(); // 读取 默认位置 ( 当前 classpath ) 的 默认名称 ( hibernate.cfg.xml ) 的配置文件
    
            // 使用 Configuration 创建 SessionFactory
            factory = config.buildSessionFactory();
            
            // 创建 Session 对象 ( 这里的 Session 是 Java 程序 跟 数据库 之间的 会话 )
            session = factory.openSession();
        }
       /** 标量查询: 查询单个属性 */
        public @Test void query5(){
            
            String HQL = "SELECT c.name FROM  Clazz AS c" ;
            
            Query<String>  queryer = session.createQuery( HQL , String.class) ; 
    
            List<String> list = queryer.list() ; // 执行查询操作
            
            for( String o : list ){
                System.out.println( o );
            }
            
        }
        
        /** 标量查询: 查询多个属性 */
        public @Test void query6(){
            
            String HQL = "SELECT c.id , c.name FROM  Clazz AS c" ;
            
            Query<?>  queryer = session.createQuery( HQL ) ; 
    
            List<?> list = queryer.list() ; // 执行查询操作
            
            for( Object o : list ){
                Class<?> c = o.getClass(); // 获得当前元素的类型
                if( c.isArray() ) {
                    int length = Array.getLength( o ); // 用  java.lang.reflect.Array 中的方法获取数组长度
                    // 用反射的方式遍历数组
                    for( int i = 0 ; i < length ; i ++ ){
                        Object e = Array.get( o ,  i ) ; // Object e = o[ i ] ;
                        System.out.print( e );
                        System.out.print( "	");
                    }
                    System.out.println();
                }
            }
            
        }
        
        /** 标量查询: 查询多个属性 */
        public @Test void query7(){
            
            String HQL = "SELECT c.id , c.name FROM  Clazz AS c" ;
            
            Query<Object[]>  queryer = session.createQuery( HQL , Object[].class ) ; 
    
            List<Object[]> list = queryer.list() ; // 执行查询操作
            
            for( Object[] array : list ){
                if( array == null || array.length == 0 ){
                    System.out.println( "没有数据" );
                } else {
                    for( int i = 0 , n = array.length ; i < n ; i++ ){
                        Object e = array[ i ] ; 
                        System.out.print( e + "	" );
                    }
                    System.out.println();
                }
            }
            
        }
        
        /** 查询多个属性返回实体类型的对象 */
        public @Test void query8(){
            
            // String HQL = "SELECT new Clazz( c.id , c.name ) FROM  Clazz AS c" ;
            
            String HQL = "SELECT new Clazz( c.name , c.id ) FROM  Clazz AS c" ;
            
            Query<Clazz>  queryer = session.createQuery( HQL ,Clazz.class ) ; 
    
            List<Clazz> list = queryer.list() ; // 执行查询操作
            
            for( Clazz c : list ){
                if( c != null ) {
                    System.out.println( c.getId() + " : " + c.getName() );
                }
            }
            
        }
        
        /** 查询单个或多个属性,并返回 map 组成的 List 集合 */
        @SuppressWarnings("rawtypes")
        public @Test void query9(){
            
            // 如果没有通过 AS 关键字指定 属性的 别名,
            // 那么将来的 Map 集合中 key 是按照 属性出现的顺序对应的索引 ( 不是数字类型而是 String 类型 )
            // String HQL = "SELECT new map( c.id , c.name ) FROM  Clazz AS c WHERE c.id = 1 " ;
            
            // 使用 AS 关键字指定  属性的 别名 ,将的 Map 集合中 key 的名称就是这里的 别名
            String HQL = "SELECT new map( c.id AS id , c.name AS name ) FROM  Clazz AS c" ;
            
            Query<Map>  queryer = session.createQuery( HQL ,Map.class ) ; 
    
            List<Map> list = queryer.list() ; // 执行查询操作
            
            for( Map map : list ){
                System.out.println( map.get( "id" ) + " : " + map.get( "name" ) );
            }
            
            /*
            for( Map map : list ){
                Set<Entry> entrySet =  map.entrySet();
                for ( Entry e : entrySet ){
                    //System.out.println( e.getKey() + " : " + e.getKey().getClass().getName() );
                    // System.out.println( e.getValue() + " : " + e.getValue().getClass().getName() );
                     System.out.println( e.getKey() + " : " + e.getValue() );
                    
                }
            }
            */
            
        }
        
        public @After void destory(){
            session.close();
            factory.close();
        }
    
    }

    标量查询返回的是由Object数组组成的List集合,可以利用反射去进行遍历。也可以将字段封装到对象中,使用SELECT new Clazz( c.id , c.name ) FROM Clazz AS c这种格式的HQL,并需要在持久化类中指定与之对应的有参构造,才可以完成封装。或者将对象封装到一个map(本质是HashMap,但是HQL中只能写Map)中。

    4、多表查询

    package ecut.query.test.hql;
    
    import java.lang.reflect.Array;
    import java.util.List;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    import org.hibernate.query.Query;
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    import ecut.query.entity.Clazz;
    import ecut.query.entity.Student;
    
    public class TestHibernateQuery2 {
        private SessionFactory factory ;
        private Session session ; 
        
        public @Before void init() {
            // 创建一个 Configuration 对象,用来读取配置文件 ( 默认位置、默认名称 )
            Configuration config = new Configuration();
            // 读取配置文件
            config.configure("ecut/query/hibernate.cfg.xml");
            //config.configure(); // 读取 默认位置 ( 当前 classpath ) 的 默认名称 ( hibernate.cfg.xml ) 的配置文件
    
            // 使用 Configuration 创建 SessionFactory
            factory = config.buildSessionFactory();
            
            // 创建 Session 对象 ( 这里的 Session 是 Java 程序 跟 数据库 之间的 会话 )
            session = factory.openSession();
        }
        
        /** 使用 表连接进行查询 ( 内连接 ) */
        public @Test void query10(){
            
            // select * from t_class c , t_student s where c.id = s.class_id ;
            // select * from t_class c inner join t_student s on c.id = s.class_id ;
            // select * from t_class c cross join t_student s where c.id = s.class_id ;
            String HQL = "FROM Clazz AS c , Student AS s WHERE c.id = s.clazz.id" ;
            
            Query<?> queryer = session.createQuery( HQL );
            
            List<?> list = queryer.list();
            
            System.out.println( list.size() );
            
            for( Object o : list ){
                Class<?> c = o.getClass();
                if( c.isArray() ){
                    final int length = Array.getLength( o ) ;
                    for( int i = 0 ; i < length ; i ++ ){
                        Object e = Array.get( o ,  i ) ; // Object e = o[ i ] ;
                        System.out.print( e + "	" );
                    }
                    System.out.println();
                }
            }
            
        }
        
        /** 连接查询 ( Clazz 对应表 跟  Clazz 中 students 对应的表 进行连接 ) */
        public @Test void query11(){
            
            // select * from t_class c inner join t_student s on c.id = s.class_id ;
            String HQL = "FROM Clazz AS c JOIN c.students" ;
            
            Query<?> queryer = session.createQuery( HQL );
            
            List<?> list = queryer.list();
            
            System.out.println( list.size() );
    
            for( Object o : list ){
                Class<?> c = o.getClass();
                if( c.isArray() ){
                    final int length = Array.getLength( o ) ;
                    for( int i = 0 ; i < length ; i ++ ){
                        Object e = Array.get( o ,  i ) ; // Object e = o[ i ] ;
                        System.out.print( e + "	" );
                    }
                    System.out.println();
                }
            }
            
        }
        
        /** 连接查询 ( 使用 fetch 关键字 ) */
        public @Test void query12(){
            
            // 使用 fetch 关键字后,下面的 HQL 语句执行后返回 由 Clazz 对象组成的 List 集合
            // Student 对象被自动添加到 相应 的班级对象的 students 集合中
            String HQL = "FROM Clazz AS c JOIN fetch c.students" ;
            
            Query<Clazz> queryer = session.createQuery( HQL , Clazz.class );
            
            List<Clazz> list = queryer.list();
            
            System.out.println( list.size() );
            
            for( Clazz c : list ){
                System.out.println( c.getName() + " : " + c.getStudents().size() );
            }
            
        }
        
        /** 使用 DISTINCT 剔除重复数据 */
        public @Test void query13(){
            
            String HQL = "SELECT DISTINCT c FROM Clazz AS c JOIN fetch c.students" ;
            
            Query<Clazz> queryer = session.createQuery( HQL , Clazz.class );
            
            List<Clazz> list = queryer.list();
            
            System.out.println( list.size() );
            
            for( Clazz c : list ){
                System.out.println( c.getName() + " : " + c.getStudents().size() );
            }
            
        }
        
        /** 使用左外连接: 查询所有班级 及 各班级的学生 ( 暂时没有学生的班级也列出来 ) */
        public @Test void query14(){
            //SELECT * FROM t_class c LEFT JOIN  t_student AS s ON  s.class_id = c.id
            String HQL = "SELECT DISTINCT c FROM Clazz AS c LEFT JOIN fetch c.students" ;
            
            Query<Clazz> queryer = session.createQuery( HQL , Clazz.class );
            
            List<Clazz> list = queryer.list();
            
            System.out.println( list.size() );
            
            for( Clazz c : list ){
                System.out.println( c.getName() + " : " + c.getStudents().size() );
            }
            
        }
        
        /** 使用左外连接: 查询每个学生及其班级信息,如果某个学生没有明确班级,也列出来 */
        public @Test void query15(){
            
            String HQL = "FROM Student AS s  LEFT  OUTER  JOIN fetch s.clazz" ;
            
            Query<Student> queryer = session.createQuery( HQL , Student.class );
            
            List<Student> list = queryer.list();
            
            System.out.println( list.size() );
            
            for( Student c : list ){
                System.out.println( c.getName() + " : " + c.getClazz() );
            }
            
        }
        
        public @After void destory(){
            session.close();
            factory.close();
        }
    
    }

     使用迫切内连接(fetch 关键字)后,执行返回 由 Clazz 对象组成的 List 集合,Student 对象被自动添加到 相应 的班级对象的 students 集合中,而不是默认返回的object[]。另外可以使用DISTINCT 删除重复数据。HQL中使用LEFT OUTER JOIN来实现左连接。

    5、HQL参数传递

    • 使用 ? 做参数占位符
      package ecut.query.test.hql;
      
      import java.util.List;
      
      import org.hibernate.Session;
      import org.hibernate.SessionFactory;
      import org.hibernate.cfg.Configuration;
      import org.hibernate.query.Query;
      import org.junit.After;
      import org.junit.Before;
      import org.junit.Test;
      import ecut.query.entity.Student;
      
      public class TestHibernateQuery3 {
          private SessionFactory factory ;
          private Session session ; 
          
          public @Before void init() {
              // 创建一个 Configuration 对象,用来读取配置文件 ( 默认位置、默认名称 )
              Configuration config = new Configuration();
              // 读取配置文件
              config.configure("ecut/query/hibernate.cfg.xml");
      
              //config.configure(); // 读取 默认位置 ( 当前 classpath ) 的 默认名称 ( hibernate.cfg.xml ) 的配置文件
      
              // 使用 Configuration 创建 SessionFactory
              factory = config.buildSessionFactory();
              
              // 创建 Session 对象 ( 这里的 Session 是 Java 程序 跟 数据库 之间的 会话 )
              session = factory.openSession();
          }
          
          /** 使用 ? 做参数占位符 */
          public @Test void query16(){
              
              String HQL = "FROM Student AS s  WHERE s.id BETWEEN ? AND ? " ;
              
              Query<Student> queryer = session.createQuery( HQL , Student.class );
              
              queryer.setParameter( 0 , 5 ); // JDBC是从1开始,HQL的参数占位符的索引从 0 开始
              queryer.setParameter( 1 , 10 );
              
              List<Student> list = queryer.list();
              
              System.out.println( list.size() );
              
              for( Student c : list ){
                  System.out.println( c.getId() + " : " + c.getName()  );
              }
              
          }
      public @After void destory(){ session.close(); factory.close(); } }

      JDBC是从1开始,HQL的参数占位符的索引从 0 开始。

    • 使用 命名 参数占位符
      package ecut.query.test.hql;
      
      import java.util.List;
      
      import org.hibernate.Session;
      import org.hibernate.SessionFactory;
      import org.hibernate.cfg.Configuration;
      import org.hibernate.query.Query;
      import org.junit.After;
      import org.junit.Before;
      import org.junit.Test;
      import ecut.query.entity.Student;
      
      public class TestHibernateQuery3 {
          private SessionFactory factory ;
          private Session session ; 
          
          public @Before void init() {
              // 创建一个 Configuration 对象,用来读取配置文件 ( 默认位置、默认名称 )
              Configuration config = new Configuration();
              // 读取配置文件
              config.configure("ecut/query/hibernate.cfg.xml");
      
              //config.configure(); // 读取 默认位置 ( 当前 classpath ) 的 默认名称 ( hibernate.cfg.xml ) 的配置文件
      
              // 使用 Configuration 创建 SessionFactory
              factory = config.buildSessionFactory();
              
              // 创建 Session 对象 ( 这里的 Session 是 Java 程序 跟 数据库 之间的 会话 )
              session = factory.openSession();
          }
      /** 使用 命名 参数占位符 */
          public @Test void query17(){
              
              String HQL = "FROM Student AS s  WHERE s.id BETWEEN :start AND :end " ;
              
              Query<Student> queryer = session.createQuery( HQL , Student.class );
              
              queryer.setParameter( "start" , 5 ); // 参数占位符的索引从 0 开始
              queryer.setParameter( "end" , 10 );
              
              List<Student> list = queryer.list();
              
              System.out.println( list.size() );
              
              for( Student c : list ){
                  System.out.println( c.getId() + " : " + c.getName()  );
              }
              
          }
          
          public @After void destory(){
              session.close();
              factory.close();
          }
      
      }

    6、HQL实现更新和删除

    package ecut.query.test.hql;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    import org.hibernate.query.Query;
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    import ecut.query.entity.Student;
    
    public class TestHibernateQuery4 {
        private SessionFactory factory ;
        private Session session ; 
        
        public @Before void init() {
            // 创建一个 Configuration 对象,用来读取配置文件 ( 默认位置、默认名称 )
            Configuration config = new Configuration();
            // 读取配置文件
            config.configure("ecut/query/hibernate.cfg.xml");
    
            //config.configure(); // 读取 默认位置 ( 当前 classpath ) 的 默认名称 ( hibernate.cfg.xml ) 的配置文件
    
            // 使用 Configuration 创建 SessionFactory
            factory = config.buildSessionFactory();
            
            // 创建 Session 对象 ( 这里的 Session 是 Java 程序 跟 数据库 之间的 会话 )
            session = factory.openSession();
        }
        
        /** 使用 HQL 方式支持 update */
        public @Test void update(){
            
            //String HQL = "UPDATE Student AS s SET s.name = ? WHERE id = ? " ;
            String HQL = "UPDATE Student AS s SET s.name = :name WHERE s.id = :id " ;
            
            Query<?> queryer = session.createQuery( HQL );
            
            queryer.setParameter( "name" , "张无忌" );
            queryer.setParameter( "id" , 2 );
            
            session.getTransaction().begin();
            
            int count = queryer.executeUpdate();
            
            session.getTransaction().commit();
            
            System.out.println( "受影响的记录数: " +  count );
            
        }
    
        /** 使用 HQL 方式支持 delete */
        public @Test void delete(){
            
            String HQL = "DELETE  FROM Student AS s WHERE s.id = :id " ;
            
            Query<?> queryer = session.createQuery( HQL );
            
            queryer.setParameter( "id" , 8 );
            
            session.getTransaction().begin();
            
            int count = queryer.executeUpdate();
            
            session.getTransaction().commit();
            
            System.out.println( "受影响的记录数: " +  count );
            
        }
        
        /** 使用 HQL 方式不支持 insert into */
        public @Test void insert(){
            
            // 错误: String HQL = "INSERT INTO Student ( id , name ) VALUES ( ? , ? )" ;
            
            Student s = new Student();
            s.setName( "林平之" );
            
            session.getTransaction().begin();
            session.save( s );
            session.getTransaction().commit();
            
        }
        
        public @After void destory(){
            session.close();
            factory.close();
        }
    
    }

    HQL 支持更新和删除,但是不支持插入。

    Native SQL Query

    1、标量查询(投影查询)

    package ecut.query.test.sql;
    
    import java.util.List;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    import org.hibernate.query.NativeQuery;
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    import ecut.query.entity.Clazz;
    
    public class TestNativeSQLQuery {
    
        private SessionFactory factory ;
        private Session session ;
    
        public @Before void init() {
            
            Configuration config = new Configuration();
            config.configure("ecut/query/hibernate.cfg.xml");
    
            //config.configure(); 
        
            factory = config.buildSessionFactory();
            
            session = factory.openSession();
        }
        //标量查询
        public @Test void query1(){
            
            String SQL = "SELECT id , name FROM t_class" ;
            
            // SQLQuery queryer = session.createSQLQuery( SQL ); // 过时
            // NativeQuery<?> queryer = session.createNativeQuery( SQL );
            NativeQuery<Object[]> queryer = session.createNativeQuery( SQL , Object[].class );
            
            List<Object[]> list = queryer.list();
            
            for( Object[] o : list ){
                System.out.println( o[ 0 ] + " : " + o[ 1 ]);
            }
            
        }
        
        public @Test void query2(){
            
            String SQL = "SELECT name FROM t_class" ;
            
            NativeQuery<?> queryer = session.createNativeQuery( SQL );
            
            List<?> list = queryer.list();
            
            for( Object o : list ){
                System.out.println( o + " : " + o.getClass().getName() );
            }
            
        }
        
        /** 执行 SQL 语句并将结果集中的数据 封装到 指定的实体类型的对象中 */
        public @Test void query3(){
            
            String SQL = "SELECT id , name FROM t_class" ;
            
            NativeQuery<Clazz> queryer = session.createNativeQuery( SQL , Clazz.class );
            
            List<Clazz> list = queryer.list();
            
            for( Clazz c : list ){
                System.out.println( c.getId() + " : " + c.getName() ) ;
            }
            
        }
       public @After void destory(){
            session.close();
            factory.close();
        }
    
    }

    可以在List中指定具体的类型实现对字段的封装,不再是保存为Object数组。

    2、排序查询

    package ecut.query.test.sql;
    
    import java.util.List;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    import org.hibernate.query.NativeQuery;
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    import ecut.query.entity.Clazz;
    
    public class TestNativeSQLQuery {
    
        private SessionFactory factory ;
        private Session session ;
    
        public @Before void init() {
            
            Configuration config = new Configuration();
            config.configure("ecut/query/hibernate.cfg.xml");
    
            //config.configure(); 
        
            factory = config.buildSessionFactory();
            
            session = factory.openSession();
        }
       /** 使用 ? 做参数占位符 */
        public @Test void query4(){
            
            String SQL = "SELECT id , name FROM t_class WHERE id > ? ORDER BY id DESC" ;
            
            NativeQuery<Clazz> queryer = session.createNativeQuery( SQL , Clazz.class );
            
            queryer.setParameter( 1 , 5 ); // 执行 SQL 语句跟 执行 HQL 语句不同,这里的索引跟JDBC一致,从 1 开始
            
            List<Clazz> list = queryer.list();
            
            for( Clazz c : list ){
                System.out.println( c.getId() + " : " + c.getName() ) ;
            }
            
        }
    
        /** 使用 命名 参数占位符 */
        public @Test void query5(){
            
            String SQL = "SELECT id , name FROM t_class WHERE id > :id ORDER BY id DESC" ;
            
            NativeQuery<Clazz> queryer = session.createNativeQuery( SQL , Clazz.class );
            
            queryer.setParameter( "id" , 5 ); 
            
            List<Clazz> list = queryer.list();
            
            for( Clazz c : list ){
                System.out.println( c.getId() + " : " + c.getName() ) ;
            }
            
        }
    public @After void destory(){
            session.close();
            factory.close();
        }
    
    }

    SQL中也可以通过使用?做参数占位符和使用命名参数占位符,但是与HQL不同的是SQL和JDBC一样参数占位符的索引从 1 开始。

    3、SQL实现更新、插入和删除操作

    package ecut.query.test.sql;
    
    import java.util.List;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    import org.hibernate.query.NativeQuery;
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    import ecut.query.entity.Clazz;
    
    public class TestNativeSQLQuery {
    
        private SessionFactory factory ;
        private Session session ;
    
        public @Before void init() {
            
            Configuration config = new Configuration();
            config.configure("ecut/query/hibernate.cfg.xml");
    
            //config.configure(); 
        
            factory = config.buildSessionFactory();
            
            session = factory.openSession();
        }
     public @Test void insert(){
            
            String SQL = "INSERT INTO t_class ( id , name ) VALUES ( :id , :name )" ;
            
            NativeQuery<?> queryer = session.createNativeQuery( SQL );
            
            queryer.setParameter( "id" , 8 ); 
            queryer.setParameter( "name" ,  "计算机科学技术" );
            
            session.getTransaction().begin();
            int count = queryer.executeUpdate();
            System.out.println( count );
            session.getTransaction().commit();
            
        }
        
        public @Test void update(){
            
            String SQL = "UPDATE t_class SET name = :name WHERE id = :id" ;
            
            NativeQuery<?> queryer = session.createNativeQuery( SQL );
            
            queryer.setParameter( "id" , 8 ); 
            queryer.setParameter( "name" ,  "大数据与云计算" );
            
            session.getTransaction().begin();
            int count = queryer.executeUpdate();
            System.out.println( count );
            session.getTransaction().commit();
            
        }
        
        public @Test void delete(){
            
            String SQL = "DELETE FROM t_class WHERE id = :id" ;
            
            NativeQuery<?> queryer = session.createNativeQuery( SQL );
            
            queryer.setParameter( "id" , 8 ); 
            
            session.getTransaction().begin();
            int count = queryer.executeUpdate();
            System.out.println( count );
            session.getTransaction().commit();
            
        }
        
        public @After void destory(){
            session.close();
            factory.close();
        }
    
    }

    SQL可以实现插入操作但是HQL无法实现插入操作。

    转载请于明显处标明出处:

    https://www.cnblogs.com/AmyZheng/p/9324192.html

  • 相关阅读:
    poj-2888-矩阵+polya
    hdu-2865-polya+dp+矩阵+euler函数
    poj-2154-polya+euler函数
    poj-1026-置换
    poj-2369-置换
    2017.2.15 开涛shiro教程-第二十一章-授予身份与切换身份(二) controller
    2017.2.13 开涛shiro教程-第十二章-与Spring集成(二)shiro权限注解
    2017.2.13 开涛shiro教程-第十二章-与Spring集成(一)配置文件详解
    2017.2.12 开涛shiro教程-第八章-拦截器机制
    2017.2.12 开涛shiro教程-第七章-与Web集成
  • 原文地址:https://www.cnblogs.com/AmyZheng/p/9324192.html
Copyright © 2011-2022 走看看