这里对Hibernate的查询作一个补充。
1.SQL原生查询
2.命名SQl查询
3.常见的锁
1.Sql原生查询(SQLQuery)
步骤:
1.获得session对象
2.编写原生sql语句
3.通过session的createSQLQuery方法查询对象
4.选择标量查询与实体查询用addScalar()和addEntity()
5.调用List方法返回查询集
标量查询
所谓标量查询就是限制查询出的结果。用addScalar()方法有两个用处,1.得到的数据名称 2.指定该数据的类型。
session.createSQLQuery(select * from student)
.addScalar(name,StandardBasicTypes.STRING)
.addScalar(id,StandardBasicTypes.INT)
.list();
返回的object结果集就只会有name(string)和id(int)字段的元素
实体查询
把查询的结果赋给一个实体对象(bean)。addEntity()就可以指定一个要赋给的对象
session.createSQLQuery(select *from students)
.addEntity(Students.class)
.list();
返回一个Object结果集,里面有一个Student的实体对象
如果想查询多个实体的话,就用别名操作
session.createSQLQuery(select * from student as s,teacher as t)
.addEntity("s",Student.class)
.addEntity("t",Student.class)
.list();
如果查询的多个对象是关联或者继承关系的化,最好用addJoin()
session.createSQLQuery(select * from student as s,teacher as t)
.addEntity("s",Student.class) 第二步
.addJoin("t","s.Teacher") 第三步
.list();
第二步时,就已经返回了一个Student对象,这时所关联的Teacher也被初始化,第三步时就不用再从数据库获得,直接把它赋值给别名为t的对象就可以了。
2.命名SQL查询
命名sql就是把sql查询从语句中提取出来,通过注解来管理。每次就直接调用注解就可以了,这样减少了耦合性。
Hibernate允许使用@NamedNativeQuery注解来定义命名的原生SQL查询,如果有多个命名查询,则使用@NamedNativeQueries注解来管理。
@NamedNativeQuery注解支持的属性:
name:指定命名SQL查询的名称 必须具备属性
query 指定命名SQL查询的查询语句 必须具备属性
resultClass 在简单查询中将查询结果映射成指定实体类的实例,类似于addEntity()作用。 非必须具备属性
resultSetMapping 该属性指定一个SQL结果映射的名称(该结果映射需要使用@SqlResultSetMapping定义),用于使用该结果映射来转换查询结果集。
简单查询时我们使用resultClass将查询结果转化为相应实体就可以了,但是如果是查询数据列较多,而且程序希望同时进行标量查询、实体查询,那就必须借助于resultSetMapping。
@NamedNativeQuery(name="test",query("select * from student"),resultClass=Student.class)
调用:List list=session.getNameQuery(test);
@SqlResultSetMapping支持的属性
name 指定SQL结果映射的名称(上面说的,咱们通过resultSetMapping引用)必需属性
entities 该属性的值为@EntityResult注解数组,每个@EntityResult注解定义一个实体查询
columns 该属性的值为@ColumnResult注解数组,每个@ColumnResult注解定义一个标量查询
class 该属性的值为@ConstructorResult注解数组,每个@ConstructorResult负责将指定的多列转化为普通类对应的属性
上面的@ColumnResult注解作用类似于SQLQuery对象的addScalar()作用,将结果集转换为标量查询,有几个@ColumnResult注解就相当于调用几次SQLQuery的addScalar()方法。
同样@EntityResult注解作用类似于SQLQuery对象的addEntity()作用,将结果集转换为标量查询,有几个@EntityResult注解就相当于调用几次SQLQuery的addEntity()方法。
@NamedNativeQuery(name="test",query(select * from student,teacher),resultSetMapping="Mapping")
@SqlResultSetMapping(name="Mapping",entities={@EntityResult(EntityResult=student.class),@EntityResult(EntityResult=teacher.class)},columns={@ColumnResult(name="name",type=String.class)})
调用:List list=session.getNameQuery("test");
3.锁
1.悲观锁,故名思意,它会用悲观的态度看待数据库操作,他默认数据库会被同时操错,使数据出错。所以每当有人操作数据库时它会将数据库锁定
怎么用:query.setLockOptions(LockOptions.UPGRADE) 使用Query对象
session.load(Account.class, 1, LockMode.UPGRADE); 使用session对象
那么每次有sql语句操作数据库时,后面都会自动跟一个for updata
2.乐观锁
使用版本的机制,它会在数据库中放一个version,每次操作数据库后,版本号+1,如果用户发现数据库当前版本与所读的版本不一样,那么用户就无法操作数据库了。
实现,在实体类中加入字段version,并加入注解@version
网友评论