您的位置:首页 > 数据库

持久化框架Hibernate和Mybatis之原生SQL

2016-10-10 15:40 423 查看
今天项目中遇到一个问题,使用持久化框架Hibernate时,需要为一张数据表中的非主键字段设置自增,每次保存的时候就不用再为该字段设置值,可通过语句
select XXX_SEQ_NAME.nextval from dual


从oracle数据中查询获得该字段的自增值。由于dual是oracle数据库中的虚拟表,所以无法使用hql,这时就需要考虑在hibernate框架下执行原生sql了。

在hibernate中执行原生sql语句通过其提供的SQLQuery对象来执行,QUERY对象执行hql语句。如下所示:

String sql ="select XXX_SEQ_NAME.nextval from dual";
SQLQuery sqlQuery = session.CreateSQLQuery();
List<Object[]> = sqlQuery.list();


这里需要注意查询结果返回的是一个Object类型的数组。如果对返回结果有要求,可使用hibernate将返回结果进行封装。

hibernate获取返回结果

1、使用SQLQuery对象的addScalar()方法进行标量查询。
String sql = "select * from student";
List list = session.createSQLQuery(sql).
addScalar("stu_id",StandardBasicTypes.INTEGER).
addScalar("name", StandardBasicTypes.STRING).
addScalar("age",StandardBasicTypes.INTEGER).list();
List<Object[]> list = sqlQuery.list();


使用这种标量查询的好处显而易见,因为它明确了要返回的字段和类型,可以降低使用ResultSetMetadata对象带来的降低程序性能影响。

2、使用SQLQuery对象的addEntity()方法进行查询。
String sql = "select * from student";
SQLQuery sqlQuery = session.CreateSQLQuery();
sqlQuery.addEntity(Student.class);
List<Student> list = sqlQuery.list();


这种方法可以直接将我们的查询结果转换成我们需要的实体类,但是使用这种方法需要注意:数据表必须又对应的持久化类映射,而且查询返回的是数据表中的全部数据。

3、使用addEntity()多表联合查询。在复杂的台账查询中常常需要多表联合查询,此时可为每张表设定别名,然后调用addEntity()方法将不同数据表转换成对应的不同实体。
String sql = "select s.*,t.* from school as s inner join teacher as t on s.id = t.school_id";
SQLQuery sqlQuery = session.CreateSQLQuery();
sqlQuery.addEntity("s",School.class).addEntity("t",Teacher.class);
List<Object[]> list = sqlQuery.list();
School school = (Student)list.get(0)(0);
Teacher teacher = (Teacher)list.get(0)(1);


在使用hibernate进行查询时,往往需要动态传参,使用参数绑定可以避免sql注入。

hibernate参数绑定

1、具名参数
String querySQL = “from student where stu_id = :studentId”;
Query q = session.createQuery(querySQL).setString("studentId",studentIdString);


参数名称前面的冒号表示这个一个具名参数,原生的hibernate Query接口提供类似的便利方法,用来绑定大多数hibernate内建类型的参数:从setInteger()到setTimestamp()和setLocale()的一切。而且hibernate还提供了绑定持久化实体的方法setEntity();

2、一般参数
String querySQL = "from student  where student.score = :score and student.stu_id = :studentId";
Query q = session.createQuery(querySQL).setParameter("score",theScore,Hibernate.entity(Score.class)).setParameter("studentId",theStudentId,Hibernate.STRING);


此方法允许绑定任何hibernate类型实参。

3、定位参数
String querySQL = “from student where stu_id = ? and stu_name = ?";
Query q = session.createQuery(querySQL).setString(0,studentIdString).setString(1,studentNameString);

Mybatis之原生SQL

关于hibernate的东西先到这里,以后有时间再写。后来,又想到之前自己写了一个小项目用的框架是mybatis,因为比较简单所以没有用到原生SQL的地方。于是乎上网查找mybatis 执行原生SQL,发现非常简单,现在分享出来。
<select id="findRecords" parameterType="String" resultMap="orderTypeResultMap">
${value}
</select>


其实${}格式的语法在Mybatis看来不会进行预处理而会直接把它当成一段可执行的SQL语句;对应的另一种就是#{}语法,MyBatis创建预处理语句属性并以它为背景设置安全的值(比如?)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息