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( "\t");
}
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 + "\t" );
}
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 + "\t" );
}
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 + "\t" );
}
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
Hibernate学习(六)的更多相关文章
- Hibernate学习六----------CRUD
© 版权声明:本文为博主原创文章,转载请注明出处 实例 1.项目结构 2.pom.xml <project xmlns="http://maven.apache.org/POM/4.0 ...
- hibernate学习 六 Hibernate缓存
缓存: 如果在集群环境下使用Hibernate时,(集群有节点A ,节点B) 当请求,发往A节点,A在数据库中修改了一条记录,然后节点B的缓存中如何实时的更新节点A修改的新数据 hi ...
- Hibernate学习---缓存机制
前言:这些天学习效率比较慢,可能是手头的事情比较多,所以学习进度比较慢. 在之前的Hibernate学习中,我们无论是CURD,对单表查询还是检索优化,我们好像都离不开session,session我 ...
- Hibernate学习之——搭建log4j日志环境
昨天讲了Hibernate开发环境的搭建以及实现一个Hibernate的基础示例,但是你会发现运行输出只有sql语句,很多输出信息都看不见.这是因为用到的是slf4j-nop-1.6.1.jar的实现 ...
- Hibernate学习笔记(二)
2016/4/22 23:19:44 Hibernate学习笔记(二) 1.1 Hibernate的持久化类状态 1.1.1 Hibernate的持久化类状态 持久化:就是一个实体类与数据库表建立了映 ...
- Hibernate学习笔记(一)
2016/4/18 19:58:58 Hibernate学习笔记(一) 1.Hibernate框架的概述: 就是一个持久层的ORM框架. ORM:对象关系映射.将Java中实体对象与关系型数据库中表建 ...
- Hibernate 学习笔记一
Hibernate 学习笔记一 今天学习了hibernate的一点入门知识,主要是配置domain对象和表的关系映射,hibernate的一些常用的配置,以及对应的一个向数据库插入数据的小例子.期间碰 ...
- Hbase深入学习(六) Java操作HBase
Hbase深入学习(六) ―― Java操作HBase 本文讲述如何用hbase shell命令和hbase java api对hbase服务器进行操作. 先看以下读取一行记录hbase是如何进行工作 ...
- TweenMax动画库学习(六)
目录 TweenMax动画库学习(一) TweenMax动画库学习(二) TweenMax动画库学习(三) Tw ...
- Hibernate学习笔记-Hibernate HQL查询
Session是持久层操作的基础,相当于JDBC中的Connection,通过Session会话来保存.更新.查找数据.session是Hibernate运作的中心,对象的生命周期.事务的管理.数据库 ...
随机推荐
- usage: git remote add [<options>] <name> <url> -f, --fetch fetch the remote branches --tags import all tags and associated objects when fetching
按照git官网提示输入 git pushgit remote add origin git@github.com:***3 / elm-1.git -u 链接git远程仓库 出现错误 usage: g ...
- [转]Vue 2.0——渐进式前端解决方案
前言:框架是什么?为什么要有框架?在众多的框架之中,Vue 独具魅力之处在哪里呢?其背后的核心思想是什么?Vue 究竟火到什么程度?最近发布的 Vue2.0 又做了哪些改进呢?Vue 和 Weex 又 ...
- 【网易官方】极客战记(codecombat)攻略-地牢-高举之剑
关卡连接: https://codecombat.163.com/play/level/the-raised-sword 为了战斗,学会武装你自己. 简介 依照名字攻击每个食人魔.记住,每个食人魔需要 ...
- 线索二叉树的详细实现(C++)
线索二叉树概述 二叉树虽然是非线性结构,但二叉树的遍历却为二又树的结点集导出了一个线性序列.希望很快找到某一结点的前驱或后继,但不希望每次都要对二叉树遍历一遍,这就需要把每个结点的前驱和后继信息记录下 ...
- GitHub网页版基本操作
创建存储库 登录GitHub进入主页,点击头像左边的加号,创建存储库 填写存储库名称.描述,根据需求设置其他选项.点击“Create repository”按钮 创建分支 打开之前创建好的存储库,点击 ...
- next路由跳转监听
next的路由跳转监听事件 { “routeChangeStart”, "beforeHisroryChange" "routeChangeComplete", ...
- 2019冬季PAT甲级第一题
#define HAVE_STRUCT_TIMESPEC #include<bits/stdc++.h> using namespace std; ][]; ][]; ]; string ...
- 解决teamviewer试用期到期的方法
Teamviewer是一款远程控制软件,使用过程中系统弹出“Teamviewer试用版已到期”的提示, 需要用户购买许可证或延长试用期才能继续使用,解决teamviewer试用期到期问题步骤如下: 出 ...
- FILES源代码
FILESの源码 #include <bits/stdc++.h> #include <game.h> #define pause getchar(); #define c ...
- linux 网络数据收发网络流量监控
网卡流量 1.iftop命令 iftop可以用来监控网卡的实时流量(可以指定网段).反向解析IP.显示端口信息.TCP/IP连接等官网:http://www.ex-parrot.com/~pdw/if ...