调用存储过程并使用 Hibernate 将本机查询结果映射到 POJO

x33g5p2x  于2021-10-16 转载在 其他  
字(3.4k)|赞(0)|评价(0)|浏览(274)

在上一篇文章中,我们学习了如何使用 JPA SqlResultSetMapping 在没有实体类的情况下调用 PL/SQL 存储过程并将结果集映射到 POJO。

在本文中,我们将使用 Hibernate ResultTransformer 调用一个 PL/SQL 存储过程并将结果列表映射到 POJO,而不使用 JPA。

我们将使用我们在本文中创建的 SpringHibernateDemo 应用程序。

让我们开始吧

创建存储过程

我们将创建一个存储过程来查询我们之前创建的用户表。

DELIMITER $
CREATE PROCEDURE `SP_USER_INFO`()
BEGIN
    SELECT USER_ID AS id, DISPLAY_NAME AS name, EMAIL as email FROM USER;
END$
DELIMITER ;

创建 POJO 类

创建一个字段名称与本机 SQL 查询中使用的别名匹配的 POJO。

UserDTO.java
package com.javachinna.model;

import java.math.BigInteger;

import lombok.Data;

@Data
public class UserDTO {
	private BigInteger id;
	private String name;
	private String email;
}

注意: 我们已经将 id 字段声明为 BigInteger,因为 Hibernate 将整数值返回为 BigInteger

创建存储库

UserInfoRepository.java
package com.javachinna.repo;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.query.Query;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.javachinna.model.UserDTO;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Repository
@Transactional
public class UserInfoRepository {

	@Autowired
	private SessionFactory sessionFactory;

	@SuppressWarnings("unchecked")
	public List<UserDTO> getUerInfo() {
		Session session = null;
		Transaction transaction = null;
		List<UserDTO> list = null;
		try {
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			Query query = session.createNativeQuery("{call SP_USER_INFO()}").setResultTransformer(Transformers.aliasToBean(UserDTO.class));
			list = query.getResultList();
			transaction.commit();
		} catch (Exception e) {
			log.error("Exception occurred", e);
			if (transaction != null) {
				transaction.rollback();
			}
		} finally {
			session.close();
		}
		return list;
	}
}

我们使用了 Hibernate AliasToBeanResultTransformer,它允许我们将结果转换为用户指定的类,该类将通过 setter 方法或字段匹配存储过程的本机 SQL 查询中使用的别名

注意:setResultTransformer 在 Hibernate 5.2 中已弃用,并且没有替代方法可以使用。 它过早被弃用为了在 Hibernate 6 中引入 @FunctionInterface 作为替代。因此,我们必须使用弃用的方法,直到它发布后迁移到 Hibernate 6。

创建 JUnit 测试

创建测试配置

TestConfig.java

TestConfig 是一个 Spring 配置类,它指定要扫描带注释组件的基本包。

package com.javachinna.test;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = { "com.javachinna" })
public class TestConfig {

}

创建 JUnit 测试类

DemoApplicationTests.java

@ExtendWith注解用于为注解的测试类或测试方法注册SpringExtension

SpringExtensionSpring TestContext Framework 集成到 JUnit 5 的 Jupiter 编程模型中。

@ContextConfiguration 定义了类级元数据,用于确定如何为集成测试加载和配置 ApplicationContext

@Test 注释表示被注释的方法是 test 方法。

package com.javachinna.test;

import java.util.List;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import com.javachinna.model.UserDTO;
import com.javachinna.repo.UserInfoRepository;

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = { TestConfig.class })
public class DemoApplicationTests {

	@Autowired
	private UserInfoRepository userInfoRepository;

	@Test
	public void getUserInfoTest() {
		List<UserDTO> list = userInfoRepository.getUerInfo();
		Assertions.assertNotNull(list);
	}
}

运行测试

源代码

https://github.com/JavaChinna/spring-hibernate-integration

结论

这就是所有的人。在本文中,我们研究了如何使用 Hibernate 在没有实体类的情况下将 SP 结果集映射到 POJO。

相关文章