hibernate原生sql
① hibernate如何执行原生sql插入 即用hibernate执行insert into table values();
首先帮你要知道,有很多技术框架可以的。就说通过通过hibernate的ORM吧。
写个POJO类,再调用它的对象,PO;
创建session对象,
Session s=HibernateSessionFactory.getSession();
s.save(PO);
Transaction tx=s.beginTransaction();
tx.commit();
② Hibernate中CriteriaQuery可以使用原生sql作为排序条件么
Hibernate对原生SQL查询的支持和控制是通过SQLQuery接口亏唤芹实现的,这种销毕方式弥补了HQL、Criterion查询的不足,在操作和使用上往往更加的自由和灵活,如果使用得当,数据库操作的效率还会得到不同程度的提升。
Hibernate对原生
SQL查询的支持和控制是通过SQLQuery接口实现的。通过Session接口,我们能够很方便的创建一个SQLQuery(SQLQuery是一个接口,在Hibernate4.2.2之前,默认返回的是SQLQuery的实现类——SQLQueryImpl对象,在下文中出现的SQLQuery如非注明,都是指该子类)对象来进行原生SQL查询:
session.createSQLQuery(String sql);
SQLQuery实现了Query接口,因此你可以使用Query接口中提供的API来获取数据。
最简单的示例
//获取所有查询结果
session.createSQLQuery("select * from note").list();
//仅获取第一条结果
session.createSQLQuery("select * from note where id = 1").uniqueResult();
使用预处理SQL
预处理SQL的好处自然不必多说,除了众所周知的能够防止SQL注入攻击外,还能够在一定程度上提高SQL的查询效率。SQLQuery提供了众多的接口来分别设置不同类型的参数,诸如setBigDecimal、setBinary、setDouble等,详参SQLQuery的javaDoc,此处不再赘述。这里仅重点说一下通用的SQL参数设置接口setParameter。
如下代码示范了如何使用SQLQuery执行预处理SQL:
SQLQuery query = session.createSQLQuery("select * from note where id = ?");
//设置第一个参数的值为12,即查询ID=12的note
query.setParameter(0, 12);
List list = query.list();
...
这里需要注明一点,无论是通过不同类型参数的设置接口来设置SQL参数,还是通过setParameter来设置参数,下标都是从0开始的,而不是从1开始的!
使用自定义的结果转换器处理查询结果
SQLQuery
接口预留了setResultTransformer接口以实现使用用户自定义的ResultTransformer结果集转换器处理查询结果。
ResultTransformer接口非常简单,只有两个方法,分别用来转换单行数据和所有结果数据。经过自定义ResultTransformer生成的实体,并未加入Session,因此是非受管实体。
如下代码,示范了如何将单行数据装入LinkedHashMap对象中:
query.setResultTransformer(new ResultTransformer() {
@Override
public Object transformTuple(Object[] values, String[] columns) {
Map<String, Object> map = new LinkedHashMap<String, Object>(1);
int i = 0;
for(String column : columns){
map.put(column, values[i++]);
}
return map;
}
@Override
public List transformList(List list) {
return list;
}
});
如果不设置自定义的ResultTransformer转换器,则Hibernate将每行返回结果的数据按照结果列的顺序装入Object数组中。
这里介绍一个工具类:Transformers,它提供了一些常用的转换器,能够帮助我们快速转换结果集,如Transformers.aliasToBean(Note.class)能够将查询结果依别名注入到Note实体中。
使用标量
使用链冲SQLQuery执行原生SQL时,Hibernate会使用ResultSetMetadata来判定返回的标量值的实际顺序和类型。如果要避免过多的使用ResultSetMetadata,或者只是为了更加明确的指名返回值,可以使用addScalar()。
session.createSQLQuery("select * from note where id = 1")
.addScalar("id", LongType.INSTANCE)
.addScalar("name", StringType.INSTANCE)
.addScalar("createtime", DateType.INSTANCE);
这个查询指定了SQL查询字符串,要返回的字段和类型.它仍然会返回Object数组,但是此时不再使用ResultSetMetdata,而是明确的将id,name和
createtime按照Long,
String和Date类型从resultset中取出。同时,也指明了就算query是使用*来查询的,可能获得超过列出的这三个字段,也仅仅会返回这三个字段。
对全部或者部分的标量值不设置类型信息也是可以的:
session.createSQLQuery("select * from note where id = 1")
.addScalar("id")
.addScalar("name")
.addScalar("createtime", DateType.INSTANCE);
没有被指定类型的字段将仍然使用ResultSetMetdata获取其类型。注意,字段不区分大小写,同时不能够指定不存在的字段!
关于从ResultSetMetaData返回的java.sql.Types是如何映射到Hibernate类型,是由方言(Dialect)控制的。假若某个指定的类型没有被映射,或者不是你所预期的类型,你可以通过Dialet的registerHibernateType调用自行定义。
如果仅指定了一个scalar,那么...
Date createTime = (Date)session.createSQLQuery("select * from note where id = 1")
.addScalar("createtime", DateType.INSTANCE)
.uniqueResult();
如果我们的SQL语句使用了聚合函数,如count、max、min、avg等,且返回结果仅一个字段,那么Hibernate提供的这种提取标量结果的方式就非常便捷了。
实体查询
上面的查询都是返回标量值的,也就是从resultset中返回的“裸”数据。下面展示如何通过addEntity()让原生查询返回实体对象。
session.createSQLQuery("select * from note where id = 1").addEntity(Note.class);
session.createSQLQuery("select id,name,createtime from note where id = 1").addEntity(Note.class);
这个查询指定SQL查询字符串,要返回的实体。假设Note被映射为拥有id,name和createtime三个字段的类,以上的两个查询都返回一个List,每个元素都是一个Note实体。
假若实体在映射时有一个many-to-one的关联指向另外一个实体,在查询时必须也返回那个实体,否则会导致发生一个"column
not found"的数据库错误。这些附加的字段可以使用*标注来自动返回,但我们希望还是明确指明,看下面这个具有指向Dog的many-to-one的例子:
session.createSQLQuery("select id,note,createtime,author from note where id = ?").addEntity(Note.class);
author字段即为Note实体和Author实体的关联字段,只需在查询时得到该字段的值,Hibernate即可使用该值找到对应的关联实体。如上例中,note.getAuthor()即可返回当前Note所属的Author对象。
处理关联和集合类
通过提前抓取将Author连接获得,而避免初始化proxy带来的额外开销也是可能的。这是通过addJoin()方法进行的,这个方法可以让你将关联或集合连接进来。
session.createSQLQuery("select {note.*}, {author.*} from note note, user author where note.author = author.id")
.addEntity("note", Note.class)
.addJoin("author", "note.author");
上面的例子是多对一的关联查询,反过来做一对多的关联查询也是可以的。如下的例子中,author.notes表示该用户发表的所有日记(Note),Set集合类型:
session.createSQLQuery("select {author.*},{note.*} from note note, user author where author.id = ? and note.author = author.id")
.addEntity("author", User.class)
.addJoin("note", "author.notes");
注意:join查询会在每行返回多个实体对象,处理时需要注意。
别名和属性引用
假若SQL查询连接了多个表,同一个字段名可能在多个表中出现多次,这会导致SQL错误。不过在我们可以通过使用占位符来完美地解决这一问题。
其实在上例中已经用到了占位符:
session.createSQLQuery("select {note.*}, {author.*} from note note, user author where note.author = author.id")
.addEntity("note", Note.class)
.addJoin("author", "note.author");
这个查询指明SQL查询语句,其中包含占位附来让Hibernate注入字段别名,查询并返回的实体。
上面使用的{note.*}和{author.*}标记是作为“所有属性”的简写形式出现的,当然你也可以明确地罗列出字段名。但如下的范例代码中我们让Hibernate来为每个属性注入SQL字段别名,字段别名的占位符是表别名
+ . + 属性名。
注意:属性名区分大小写,而且不能够在where子句中使用占位符。
SQLQuery query = session.createSQLQuery("select note.id as {note.id},note as {note.note},createtime as {note.createTime},author as {note.author}, {author.*} from note, user author where note.id = ? and note.author = author.id");
query.addEntity("note", Note.class);
query.addJoin("author", "note.author");
大多数情况下,上面的别名注入方式可以满足需要,但在使用更加复杂的映射,比如复合属性、通过标识符构造继承树,以及集合类等等情况下,则需要更加复杂的别名注入方式。
下表列出了使用别名注射参数的不同方式:
③ Hibernate4 升级到Hibernate5 中 sql查询注意事项
在 Hibernate4 中,利用原生宏数SQL语句查询时,
1、可使用Session.createSQLQuery(sql)建立Qurey(org.hibernate.Query),
2、可使用Query.setParameter(int index, Object obj),对sql语句中的参数根据位置进行参数值动态绑定;
升级到 Hibernate5 后
1、org.hibernate.Query被标记为@Deprecated
2、Session().createSQLQuery(sql)返回类型为org.hibernate.query.Query;
3、并且Session().createSQLQuery也已经被标记为@Deprecated;
4、可使用Session().createNativeQuery(sql)代替createSQLQuery。
5、createNativeQuery返回的Query, 不可 通过setParameter(int index, Object obj) 根据位置 进行参数值动态绑定碰绝穗; 只可以 通过setParameter(String paramname, Object obj) 按参数名称绑定 。
6、createNativeQuery(sql)中的sql语句中的 查询笑卜占位符
只可使用 命名参数 方式进行编写。
上问错误例子中,将导致如下错误:
④ hibernate 中原生sql like 怎么写
hibernate本来就支持 原sql 调用执行sql的方法就行了 调用方法的时候注意看所需的参数
@Autowired
private SessionFactory sessionFactory;
sessionFactory.getCurrentSession().createSQLQuery(sql);
这样就可以了
⑤ hibernate的三种查询方式
1.1、SQL概述
HQL是Hibernate Query Language的缩写,提供更加丰富灵活、更为强大的查询能力;HQL接近SQL`语句查询语法。
完整的HQL语句形式如下:
select | update | delete … from … where … group by … having … order by … asc|desc
其中的update、delete为Hibernate3中所新添加的功能,可见HQL查询非常类似于标准SQL查询。HQL查询在整个Hibernate实体操作体系中占核心地位。
String hql = "HQL语句";
Query query = session.createQuery(hql);
List list = query.list(); //查询得到多个实体对象集合
Object result = query.uniqueResult(); //查询得到一个实体对象
int x = query.executeUpdate(); //执行update或delete语句悄陵,返回数据表受影响行数
1.2、实体查询
查询过程中表名使用类名,列名使用属性名,类名和属性名称区分大小写
String hql="from Users";//from 实体类类型名称
Query query = session.createQuery(hql);
List<Users> list = query.list();
for (Users user : list) {
System.out.println(user);
}
1.3、带where的查询
Query query = session.createQuery("from Users where uid=3");
Users user = (Users) query.uniqueResult();//uniqueResult 单一对象
System.out.println(user);
Query query = session.createQuery("from Users where uid>5");
List<燃雹Users>皮运帆 list = query.list();
for (Users user : list) {
System.out.println(user);
}
1.3、属性查询
查询部分属性
String hql="select u.uid,u.uname,u.upwd from Users u where u.uname='张三'";
Query query = session.createQuery(hql);
List<Object[]> list = query.list();
for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));
}
String hql="select new Users(u.uname,u.upwd) from Users u where u.uname='张三'";
Query query = session.createQuery(hql);
List<Users> list = query.list();
for (Users user : list) {
System.out.println(user);
}
1.4、实体的更新和删除
从hibernate 3版本开始才支持
//更新
String hql="update Users set uname='王五',upwd='321' where uid=3";
int res = session.createQuery(hql).executeUpdate();
//删除
String hql="delete from Users where uid=3";
int res = session.createQuery(hql).executeUpdate();
/*
返回值结果:
正整数:表受影响的行数据
0: 语句正常执行,但没有行受影响
负整数:通常是-1,执行HQL语句是一条查询语句
*/
HQL语句不能做添加
1.5、分组与排序
排序
处理方式和SQL语句中的排序是一样的
String hql="from Users order by uid";
Query query = session.createQuery(hql);
List<Users> list = query.list();
for (Users user : list) {
System.out.println(user);
}
order by语句只能出现在语句的最后位置
分组
处理方式和SQL语句中分组查询相同
分组语句需要处理筛选,只能使用having语句,而不能使用where语句。
String hql = "select e.dept.deptno, count(e) from Emp e group by dept.deptno";
String hql = "select e.dept.deptno, count(e) from Emp e group by dept.deptno having count(e)>=5";
1.6、参数绑定
使用占位参数
String hql="from Users where uid=? or uname=?";
Query query = session.createQuery(hql);
//索引从0开始
query.setInteger(0, 3);//query.setParameter(0, 3);
query.setString(1, "张三");//query.setParameter(1, "张三");
List<Users> list = query.list();
for (Users user : list) {
System.out.println(user);
}
使用参数名称
String hql = "from Users where uid=:no1 or uid=:no2";
Query query = session.createQuery(hql);
query.setInteger("no1", 1);
query.setInteger("no2", 3);
//....
可以使用点位参数和名称参数混合使用
String hql = "from User where uid=? or uid=:no2";
Query query = session.createQuery(hql);
query.setInteger(0, 7788);
query.setInteger("no2", 7566);
//....
//使用点位参数和名称参数混合使用,所有点位参数必须放在前面,一旦有名称参数出现,其后将不能再出现占位参数
1.7、连接查询
--SQL语句:查询员工姓名、薪资、部门名称
SELECT ENAME,SAL,DNAME
FROM EMP e JOIN DEPT d ON e.DEPTNO=d.DEPTNO
SELECT ENAME,SAL,DNAME FROM EMP,DEPT WHERE EMP.DEPTNO=DEPT.DEPTNO
没有on语句
能被连接到查询中的必须是主查询对象的子属性
String hql="SELECT e.ename, e.sal, e.dept.dname FROM Emp e";
//HQL连接查询
String hql="SELECT e.ename, e.sal, d.dname FROM Emp e JOIN e.dept d";
String hql = "SELECT e FROM Emp e JOIN e.dept"; //JOIN将没有意义
String hql = "FROM Emp e JOIN e.dept";
Query query = session.createQuery(hql);
List<Object[]> list = query.list();
//List集合中的数组中会保存两个元素:
//0:主数据(Emp)
//1:从数据(Dept)
//查询编号为7788的员工信息,同时将对应的dept信息和manager信息查询并保存在对应的子属性中
String hql = "FROM Emp e JOIN FETCH e.dept d JOIN FETCH e.manager m WHERE e.empno=7788";
Query query = session.createQuery(hql);
Emp emp = (Emp) query.uniqueResult();
System.out.println(emp);
System.out.println(emp.getManager());
System.out.println(emp.getDept());
1.8、分页
String hql = "from Users";
Query query = session.createQuery(hql);
query.setFirstResult(0);
query.setMaxResults(2);
2、QBC查询
QBC(Query By Criteria)查询就是通过使用Hibernate提供的Query By Criteria API来查询对象,这种API封装了SQL语句的动态拼装,对查询提供了更加面向对象的功能接口。
QBC查询最重要的三个类:
Restrictions 条件限制
Projections 列设射
Order 排序
2.1、查询实现
Criteria criteria = session.createCriteria(Users.class);
//session.createCriteria("entity.Users");
//session.createCriteria(Users.class, "别名");
List<Dept> list = criteria.list();
//查询单行结果(如果结果有两行或更多,会报错)
Object uniqueResult = criteria.uniqueResult();
2.2、Projections 列投射
语法:
//查询uname属性
Criteria criteria = session.createCriteria(Users.class);
PropertyProjection property = Projections.property("name");
criteria.setProjection(property);
List<Object> result = criteria.list();
//查询uname, upwd属性
Criteria criteria = session.createCriteria(Users.class);
//1.创建投射列表
ProjectionList projectionList = Projections.projectionList();
//2.向投射列表中添加列投射
PropertyProjection property1 = Projections.property("uname");
PropertyProjection property2 = Projections.property("upwd");
projectionList.add(property1).add(property2);
//3.将投射列表设置到准则中
criteria.setProjection(projectionList);
List<Object> result = criteria.list();
返回值类型 方法名称 描述
PropertyProjection Projections.property 指定某属性
AggregateProjection Projections.avg 求平均值
CountProjection Projections.count 统计某属性的数量
CountProjection Projections.countDistinct 统计某属性不同值的数量
PropertyProjection Projections.groupProperty 指定某个属性为分组属性
AggregateProjection Projections.max 求最大值
AggregateProjection Projections.min 求最小值
ProjectionList Projections.projectionList 创建一个ProjectionList对象
Projection Projections.rowCount 查询结果集中的记录条数
AggregateProjection Projections.sum 求某属性的合计
2.3、Restrictions 条件限制
语法:
Criteria criteria = session.createCriteria(Users.class);
Criterion notNull = Restrictions.isNotNull("comm");
criteria.add(notNull); //添加一个条件(如果添加了多个条件,默认条件之间使用and连接)
List<Users> list = criteria.list();
返回值类型 方法名称 描述
SimpleExpression Restrictions.eq 等于(equal)
Criterion Restrictions.allEq 使用Map,Key/Valu进行多个等于的比对
SimpleExpression Restrictions.gt 大于(great than)
SimpleExpression Restrictions.ge 大于等于(great than or equal)
SimpleExpression Restrictions.lt 小于(less than)
SimpleExpression Restrictions.le 小于等于(less than or equal)
Criterion Restrictions.between 对应SQL的between
SimpleExpression Restrictions.like 对应SQL的like
Criterion Restrictions.in 对应SQL的in
LogicalExpression Restrictions.and and关系
LogicalExpression Restrictions.or or关系
Criterion Restrictions.isNull 为空
Criterion Restrictions.sqlRestriction SQL限定查询
Criterion Restrictions.not 取反
2.3、Order排序
语法:
Criteria criteria = session.createCriteria(Dept.class);
criteria.addOrder(Order.asc("name"))
.addOrder(Order.desc("loc"));
//SELECT * FROM DEPT ORDER BY name ASC, loc DESC
返回值类型 方法名称 描述
Order Order.asc(String propertyName) 升序
Order Order.desc(String propertyName) 降序
2.4、分页查询
Criteria criteria = session.createCriteria(Dept.class);
int pageNum = 2, pageSize = 5;
criteria.setFirstResult((pageNum-1)*pageSize); //查询起始行下标
criteria.setMaxResults(pageSize); //查询的最大行数
List list = criteria.list();
//setFirstResult方法和setMaxResults方法同样可以在SQLQuery及Query类型上使用
3、原生SQL查询
1、查询
String sql = "select uid,uname,upwd from _users";
List list = session.createSQLQuery(sql).list();
for(Object obj : list){
System.out.println(obj);
}
2、 addEntity()
String sql = "select uid,uname,upwd from _users";
// addEntity()可以告诉Hibernate你想要封装成对象的类型,然后自动为你封装
SQLQuery query = session.createSQLQuery(sql).addEntity(Users.class);
List<User> list = query.list();
for(Users user : list){
System.out.println(user.getUname());
}
3、 uniqueResult
String sql = "select uid,uname,upwd from _users where uid = 2";
SQLQuery query = session.createSQLQuery(sql).addEntity(Users.class);
Users user = (Users) query.uniqueResult();//返回单一对象
System.out.println(user.getUname());
USB Microphone https://www.soft-voice.com/
Wooden Speakers https://www.zeshuiplatform.com/
亚马逊测评 www.yisuping.cn
深圳网站建设www.sz886.com
⑥ springboot hibernate运行原生sql语句
1.配置文尺春件设置
spring.jpa.properties.hibernate.current_session_context_class = org.springframework.orm.hibernate5.SpringSessionContext
2.创建hibernate sessionFactory config
3.创建陵笑耐升睁接口
4.实现
这样就能在springboot中运行原生sql语句了