使用 Hibernate 进行 CURD 操作时候,插入、更新、删除操作可以直接用过对持久化实体(PO)实例来进行,对于查询操作,Hibernate 提供了以下3种方式来进行:
- HQL 查询;
- Criteria 条件查询(hibernate 5.x 已经废弃);
- SQL 查询;
Hibernate SQL查询
Hibernate 除了使用自己的HQL进行查询外,还可以使用原生的 SQL 进行查询,同样原生 SQL 也支持命名查询,hibernate 3 之后,命名SQL查询可以用调用储存过程;
SQL 查询是通过
SQLQuery 接口来实现的,SQLQuery 接口是 Query 的子接口,所以 SQLQuery 通用 Query 的方法常用的 API 如下:
SQLQuery | createSQLQuery(String SQLString) | 使用SQL语句(或模板) 创建SQLQuery对象 |
Query | setFirstResults(int index) | 设置返回的结果集从第几条记录开始 |
Query | setMaxResults(int maxNum) | 设置本次放回结果集的最大结果数目 |
SQLQuery | addEntity(Class classType) | 设置实体查询的对应实体类型 |
SQLQuery | addScalar(String key,StandardBasicTypes type) | 设置标量查询的标量类型 |
List | list() | 返回查询的结果列表,以 List<Object> 的方式,返回列表中的每一个 Object 对应一条查询结果记录,Object为一个记录查询结果标量数组或实体对象 |
public static void main (String[] args) throws Exception{
Session session = HibernateUtil.currentSession();
Transaction tran = session.beginTransaction();
//示例1
List list = session.createSQLQuery("select * from users")
.list();
//示例2:使用SQL模板
String sql = "select * from users as u where u.age > :ageVal";
List list2 = session.createSQLQuery(sql)
.setParameter("ageVal",18)
.list();
tran.commit();
HibernateUtil.closeSession();
}
其中SQL模板的占位符同HQL中一样可以使用 “:N”或“?”,详细看:
http://blog.csdn.net/al_assad/article/details/77900663
标量查询
最基本的SQL查询就是返回一个标量列表,与 JDBC 的方式相似,简单的示例如下:
List list = session.createSQLQuery("select * from users")
.addScalar("user_name",StandardBasicTypes.STRING) //抽取标量User表结构中的 “user_name”,“user_age” 字段
.addScalar("user_age",StandardBasicTypes.INTEGER)
.list();
//返回只会包含 “user_name”,"user_age" 字段
for(Object element : list){ //遍历结果
Object[] obj = (Object[])element;
System.out.println(obj[0]+" "+obj[1]);
}
对于以上的例子,假如表结构为 :
User(id,user_name,user_age,user_icon,create_date
)
如果直接
List list = session.createSQLQuery("select * from User").list(),那么 hibernate 回将所有的字段全部自动转化为标量,并返回为 List 中;
按上面的实例使用 addScalar 显式指示标量名称和类型,那么只会返回显式指定的字段标量;
实体查询
如果查询返回某个数据表的全部数据列,且该数据表有对应的持久化类映射,可以使用 addEntity() 将该数据表转化为持久化实体,如下:
List list = session.createSQLQuery("select * from users")
.addEntity(User.class) //将结果标量映射为 User 实体
.list();
for(Object element : list){ //遍历结果
User user = (User)element;
System.out.println(user.getAge()+" "+user.getName());
}
当进行实体查询时,包含关联查询,可以使用 join()方法指定关联实体,如下示例,User 实体和 Article 实体之间的关联关系为 1-N:
List list = session.createSQLQuery("select u.* a.* from users u,article a"
+"where u.user_id = a.user_id")
.addEntity("u",User.class) //将"u"别名的查询结果映射为 User 实体
.join("a",Article.class) //将“a”别名的查询结果映射为 Article 关联实体
.list();
SQL 命名查询
和 HQL 一样,hibernate 也支持 SQL 命名查询,可以将查询有语句放置在实体类的注释中,使用@NamedNativeQuery注解,多个
@NamedNativeQuery注解可以放置在@NamedNativeQueries 注解中;
如下示例:
User.java
@Entity
@Table(name="users")
@NamedNativeQuery(name="query1",query = "select * from user")
public class Users {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
@Column(name="user_id")
private int id;
@Column(name="create_date")
@Temporal(TemporalType.DATE)
private Date createDate;
......
}
Test.java
public class TestHQL {
public static void main (String[] args) throws Exception{
Session session = HibernateUtil.currentSession();
Transaction tran = session.beginTransaction();
List list = session.getNamedQuery("query1") //调用命令查询
.list();
.....
}
}