eclipse学习(第三章:ssh中的Hibernate)——10.Hibernate使用原生sql语句

前言(建议看一下,有版本差距)

本文参考自https://www.w3cschool.cn/hibernate/wrg81ieb.html后做的一些实践日志记录。
使用createSQLQuery这个方法就能写sql了,随便你写啥都行,我下面举例说明一下查找,其实删除修改更新那些应该都可以的。

其中旧版本的hibernate(5.2以前的),它可以直接使用SQLQuery。
举例来看看吧

SQLQuery q = session.createSQLQuery(sql);
q.setParameter("id", "1");
q.addEntity(Address.class);
addresses = q.getResultList();

在新的版本hibernate(5.2以后),SQLQuery会显示过时了。这个时候被替换成了NativeQuery

NativeQuery nq = session.createNativeQuery(sql);
nq.addEntity(Address.class);
nq.setParameter("id", "1");
addresses = nq.getResultList();

使用原生sql语句

单表使用标量查询

首先我得先说一下什么叫标量查询,标量查询其实就是只查部分数据。这里我并没有获取address的全部数据

public List<Object[]> scalarQuery(){
		Transaction transaction = null;
		Session session = sessionFactory.openSession();
		List<Object[]> addressList = null;
		try {
			transaction = session.beginTransaction();
			
			String sql = "select id , provinces , address_detail from address";
			NativeQuery nativeQuery = session.createNativeQuery(sql);
			
			//这里是对每一个要筛选出来的数据进行指定,指定查询结果包含哪些数据列---没有被addScalar选出的列将不会包含在查询结果中
			//指定查询结果中数据列的数据类型
			nativeQuery.addScalar("id",StandardBasicTypes.STRING);
			nativeQuery.addScalar("provinces",StandardBasicTypes.STRING);
			nativeQuery.addScalar("address_detail",StandardBasicTypes.STRING);
			
			//以下这种做法也可以,不过方法已过期,不建议使用
//			nativeQuery.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
			
			addressList = nativeQuery.getResultList();
			transaction.commit();
		}catch (HibernateException he) {
			if(null != transaction) {
				transaction.rollback();
			}
			addressList = null;
		}finally {
			session.close();
		}
		return addressList;
	}

单表实体类查询

查询结果对应实体类

public List<Address> entityQuery(){
		Transaction transaction = null;
		Session session = sessionFactory.openSession();
		List<Address> addressList = null;
		try {
			transaction = session.beginTransaction();
			
			String sql = "select * from address where id = :id";
			NativeQuery nativeQuery = session.createNativeQuery(sql);
			nativeQuery.addEntity(Address.class);
			nativeQuery.setParameter("id", "2");
			
			addressList = nativeQuery.getResultList();
			transaction.commit();
		}catch (HibernateException he) {
			if(null != transaction) {
				transaction.rollback();
			}
			addressList = null;
		}finally {
			session.close();
		}
		return addressList;
	}

多表联查标量,部分数据

public List<Object[]> manyTableScalarQuery(){
		Transaction transaction = null;
		Session session = sessionFactory.openSession();
		List<Object[]> addressList = null;
		try {
			transaction = session.beginTransaction();
			
			String sql = "select s.name , a.address_detail from address a, student s where a.student_id = s.id";
			NativeQuery nativeQuery = session.createNativeQuery(sql);
			
			//标量查询只需要将返回的数据类型指定即可
			nativeQuery.addScalar("a.address_detail",StandardBasicTypes.STRING);
			nativeQuery.addScalar("s.name",StandardBasicTypes.STRING);
			
			addressList = nativeQuery.getResultList();
			transaction.commit();
		}catch (HibernateException he) {
			if(null != transaction) {
				transaction.rollback();
			}
			addressList = null;
		}finally {
			session.close();
		}
		return addressList;
	}

多表联查返回实体类

public List<Object[]> manyEntity(){
		Transaction transaction = null;
		Session session = sessionFactory.openSession();
		List<Object[]> addressList = null;
		try {
			transaction = session.beginTransaction();
			
			String sql = "select s.* , a.* from address a, student s where a.student_id = s.id";
			NativeQuery nativeQuery = session.createNativeQuery(sql);
			
			nativeQuery.addEntity(Student.class);
			nativeQuery.addEntity(Address.class);
			
			//这里我不是很想这么做,因为这里有几个原因,第一个这个方法过时,第二个你创建一个新实体类那么查询语句的结果都要设置别名还有建一个对应的新实体类,我觉得很麻烦
//			nativeQuery.setResultTransformer(Transformers.aliasToBean("对应的新实体类名称"));
			
			
			//这里不做一个转换的话,这个list的第一个元素里面是数组类型,第一个位置放student,第二个位置放address,跟你addEntity的顺序有关,做一个类型转换就能拿出来数据。将object转为对应的实体类即可
			addressList = nativeQuery.getResultList();
			transaction.commit();
		}catch (HibernateException he) {
			if(null != transaction) {
				transaction.rollback();
			}
			addressList = null;
		}finally {
			session.close();
		}
		return addressList;
	}

中途出现的异常

Caused by: java.sql.SQLException: Column ‘id’ not found.

这里你千万不要以为是你写错了sql或者是字段映射错误。
这是因为你在做标量查询,标量查询不需要指定对应的实体类,只需要指定对应的返回属性类型。你加入了那就会报错。删掉以下内容即可。

nativeQuery.addEntity(Student.class);
nativeQuery.addEntity(Address.class);

项目地址

如果你看上面的代码依旧没法理解,你可以下载下面的项目来看看是怎么运行的,数据库建表语句也在里面了。
https://gitee.com/mrchen13427566118/ssh_hibernate_learn里面的ssh_hibernate_native_sql项目。
打开方式可以看这篇的第三点https://blog.csdn.net/weixin_43987277/article/details/116936221

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值