文章目录
- 前言
- pom
- yml配置
- 整合方式
- 1. 依赖直接注入
- 2. 通过ApplicationContext创建Session
- 难点
前言
自由探索SpringBoot整合Hibernate 4.x,本来觉得是个轻松加愉快的事,没想到因为Bean注入的问题卡了挺久。。。以下具体内容。
pom
首先是pom文件,这边我的SpringBoot版本比较新,用的2.5.3:
其次是javax.persistence
包,以及hibernate-entitymanager
包:
其他的加个lombok和数据库connector就OK,可以开始愉快的整合了:
yml配置
这里主要是配置数据库,其他的一律用默认,毕竟只需要做到整合后能用即可:
spring:
datasource:
url: jdbc:mysql://localhost:3306/Grocery
username: root
password: 12345678
driver-class-name: com.mysql.cj.jdbc.Driver
整合方式
1. 依赖直接注入
首先,写个简单的BaseDao:
package com.example.localtests.dao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
@Repository
public class BaseDao {
protected EntityManagerFactory factory;
protected EntityManager manager;
@Autowired
protected void setFactory(EntityManagerFactory factory){
this.factory = factory;
this.manager = factory.createEntityManager();
}
}
这里用的是set方法注入,各位童鞋可以自己选用喜欢的注入方式哈。
然后下面写具体的Dao,这里就直接开始具体查数据:
package com.example.localtests.dao;
import org.springframework.stereotype.Repository;
import javax.persistence.Query;
import java.util.List;
@Repository
public class LocalTestDao extends BaseDao {
public List getResult() {
String sql = "select * from t_ce_port";
Query query = manager.createNativeQuery(sql);
return query.getResultList();
}
}
写了个最简单的SQL来测试。
然后写Service
以及Controller
,都是最快捷的:
Service:
package com.example.localtests.service;
import com.example.localtests.dao.LocalTestDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class LocalService {
private LocalTestDao dao;
@Autowired
private void setDao(LocalTestDao dao){
this.dao = dao;
}
public List getLocalResult(){
return dao.getResult();
}
}
Controller:
package com.example.localtests.controller;
import com.example.localtests.service.LocalService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class LocalController {
private LocalService service;
@Autowired
private void setService(LocalService service){
this.service = service;
}
@GetMapping(path = "/local")
public List getLocalData(){
return service.getLocalResult();
}
}
好了,写完以上就已经可以愉快的测试了,启动项目—然后报错,报错如图:
明明都已经添加了为什么还会Bean Not Found
呢,由于是SpringBoot方式整合,不存在XML写Bean的方式,处理起来很简单,在pom里边加上springBoot对jpa的支持就好了:
非常简单,再次启动,一切正常:
输入http://localhost:8080/local
查询,可以看到返回数据:
2. 通过ApplicationContext创建Session
思路是拿到ApplicationContext
,然后再通过getBean()
方法拿到SessionFactory
,最后创建Session
,第一步写个util:
package com.example.localtests.utils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import javax.persistence.EntityManagerFactory;
@Component
public class ApplicationContextUtils implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(@NotNull ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
public static ApplicationContext getContext() {
return context;
}
public static Session getSession(){
return context.getBean(SessionFactory.class).openSession();
}
}
以上,继承ApplicationContextAware
的标准写法,写一步在Dao中使用Session
对象:
public List getResultFromContext(){
String sql = "select * from t_ce_port where audit_state = 'identification'";
Query query = ApplicationContextUtils.getSession().createNativeQuery(sql);
return query.getResultList();
}
然后调用getResultFromContext()
方法输出结果就ok:
@GetMapping(path = "/localContext")
public List getContextData(){
return service.getContextResult();
}
最后,启动项目访问/localContext
接口,查看数据:
没有问题,完结。
难点
回过头来看其实不是很难,但主要会碰到很奇怪的坑。
DAO层中注入的EntityManager
报npe,即注入的内容为空值,这个其实跟找不到EntityManagerFactory
这个Bean
是同一种问题,即没有把Bean
注入容器,启动项目扫描组件的时候,就会因为扫描不到Bean
报错。
在Spring时期,可以通过配置xml的方式来写入,但在SpringBoot项目里,还是建议用注解形式去写注入。