spring boot 整合Hibernate
简单的做法
实现方式
配置文件
无需在properties文件有特殊设置,在service层别忘了事务注解@Transactional
代码
使用spring boot JPA的Reppository,不用自己写DAO层,很方便;假设你已经导入了依赖,那么在DAO层(或者说Repository)你就只需要继承接口:
@Repository
public interface UserRepository extends JpaRepository<User, Integer>{
public User findById(Long id);
public User save(User user);
//自己的操作
@Query(value = "SELECT u FROM User u WHERE name=:name")
public User findName(@Param("name") String name);
}
不要忘了使用注解@Repository,之后,你就可以CRUD了。JpaRepository接口已经有了很多数据库操作,可以直接调用,还可以自己通过@Query定义操作。
需要注意
在test方法或者逻辑层需要特别注意事物,只有在@Transactional标注的方法里才会有事物,并且如果需要查询实体中的集合,就需要将操作包在事物里。
其他的做法
自己管理session的获取,此时session可以是spring接管的也可以是刚刚打开的,使用session自己封装DAO层,使用懒加载时可以在需要实体类中的集合时提前使用update方法。
实现方式
配置文件
#...数据库和数据源设置...省略
#hibernate事务设置,这样spring boot才会在事务中接管session,这三条设置很重要!!!
spring.jpa.properties.hibernate.transaction_manager=org.springframework.orm.hibernate5.HibernateTransactionManager
spring.jpa.properties.hibernate.allow_update_outside_transaction=true
spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext
spring.transaction.rollback-on-commit-failure=true
#Hibernate 其他设置
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQL82Dialect
DAO层示例
BaseDao用来获取session,在service层尽量使用getCurrentSession方法
@Repository
public class BaseDaoImpl implements BaseDao {
@Autowired
private EntityManagerFactory entityManagerFactory;
/**
* get a hibernate.Session don't need be closed
* @return hibernate.Session
*/
public Session getCurrentSession() {
return entityManagerFactory.unwrap(SessionFactory.class).getCurrentSession();
}
/**
* get a hibernate.Session need be closed
* @return hibernate.Session
*/
@Bean
public Session openSession() {
return entityManagerFactory.unwrap(SessionFactory.class).openSession();
}
}
UserDao
@Repository
public interface UserDaoImpl implements UserDao{
@Autowired
BaseDao baseDaoImpl;
//...使用baseDaoImpl实现增删改查
}
UserService
在service层别忘了使用事务
@Service
@Transactional
public class UserServiceImpl implements UserService{
@Autowired
UserDao userDaoImpl;
//使用userDaoImpl完成业务
}
使用update方法避免no session异常
//在查询有集合的实体之后,由于懒加载的原因,session已经关闭,所以如果再使用该实体将会抛出no session异常
//解决方法就是使用update更新实体的集合
Session session = baseDaoImpl.openSession();
session.update(entity);
//继续操作实体
entity.getXXXs();
//...
//关闭session
session.close();
总结
- 第一种方式是比较新的做法,在2.3.1版本可以成功运行
- 第二种方法比较过时,但是更灵活
- 两种方式都需要特别注意事物!