springboot整合hibernate(非JPA)(一)
springboot整合hibernate(非JPA)(一)
springboot整合hibernate,非jpa,若是jpa就简单了,但是公司项目只有hibernate,并要求支持多数据库,因此记录下整合开发了。基本入门可参考官网
https://docs.jboss.org/hibernate/orm/5.5/quickstart/html_single/#tutorial_annotations
为支持多数据库,下面将实现:
1、springboot2.3.7整合hibernate最新稳定版Hibernate ORM 5.5(2021年7月11日21:53:22)
2、实现ID主键自动生成(为支持MySQL、postgre SQL、Oracle)表关联
第二篇移步:https://blog.csdn.net/weixin_44480167/article/details/118662257
一、创建基本springboot项目

二、引入依赖
<!--hibernate的核心-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.5.3.Final</version>
</dependency>
<!--用于hibernate整合spring的支持-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
<!--使用阿里的连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.6</version>
</dependency>
<!--用于ID生成-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>5.7.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
三、配置数据库
application.properties
# 应用名称
spring.application.name=springboot-hibernate
# 数据库驱动:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 数据源名称
spring.datasource.name=defaultDataSource
# 数据库连接地址
spring.datasource.url=jdbc:mysql://localhost:3306/blue?serverTimezone=UTC
# 数据库用户名&密码:
spring.datasource.username=root
spring.datasource.password=123456
# 应用服务 WEB 访问端口
server.port=8080
配置数据源:
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;
@Configurable
public class DataSourceConfig {
@Bean
@ConfigurationProperties("spring.datasource")
public DataSource dataSource() {
DruidDataSource source = new DruidDataSource();
//source.setDriverClassName("com.mysql.cj.jdbc.Driver");
source.setName("test");
source.setInitialSize(1);
//最大活动
source.setMaxActive(10);
source.setMaxWait(60000);
//配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
source.setTimeBetweenEvictionRunsMillis(60000);
//配置一个连接在池中最小生存的时间,单位是毫秒
source.setMinEvictableIdleTimeMillis(300000);
//每分钟打印一次连接状态日志
//source.setTimeBetweenLogStatsMillis(60000);
return source;
}
}
配置Hibernate
package top.lingkang.springboothibernate.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Properties;
@Component
public class HibernateToConfig {
@Resource
private DataSource dataSource;
/**
* 此处bean为根据 hibernate 官网配置文件 hibernate.cfg.xml 改造的
* https://docs.jboss.org/hibernate/orm/5.5/quickstart/html_single/hibernate-tutorials.zip
*
* @return
*/
@Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean bean = new LocalSessionFactoryBean();
bean.setDataSource(dataSource);
// 扫描实体类
bean.setPackagesToScan("top.lingkang.springboothibernate.entity");
Properties properties = new Properties();
properties.setProperty("current_session_context_class", "thread");
DruidDataSource druidDataSource = (DruidDataSource) dataSource;
properties.setProperty("connection.pool_size", String.valueOf(druidDataSource.getMaxActive()));
// 配置方言 mysql 5.7.34
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL57Dialect");
// <!-- 控制台打印SQL -->
properties.setProperty("hibernate.show_sql", "true");
// 制台打印SQL格式化
//properties.setProperty("hibernate.format_sql", "true");
/**
* create:表示启动的时候先drop,再create
* create-drop: 也表示创建,只不过再系统关闭前执行一下drop
* update: 这个操作启动的时候会去检查schema是否一致,如果不一致会做scheme更新
* validate: 启动时验证现有schema与你配置的hibernate是否一致,如果不一致就抛出异常,并不做更新
*/
// 首次启动使用 create 让bean自动生成表,之后使用 update模式即可
properties.setProperty("hibernate.hbm2ddl.auto", "create");
bean.setHibernateProperties(properties);
return bean;
}
}
配置自定义ID生成
package top.lingkang.springboothibernate.config;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.Configurable;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.Type;
import java.io.Serializable;
import java.util.Properties;
/**
* 采用雪花算法生成主键
* 2021年7月11日22:11:55
*/
public class PrimaryGenerator implements Configurable, IdentifierGenerator {
//参数1为终端ID
//参数2为数据中心ID
Snowflake snowflake = IdUtil.getSnowflake(1, 1);
private String pre = "";
@Override
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
String prefix = params.getProperty("prefix");
if (prefix != null)
this.pre = prefix;
}
@Override
public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException {
//雪花算法生成ID
return pre + snowflake.nextIdStr();
}
}
编写实体映射
user表
package top.lingkang.springboothibernate.entity;
import lombok.Data;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
import java.util.Date;
@Data
@Entity
@Table(name = "t_user")
public class UserBean {
// 主键采用string为了兼容更多数据库
@Id
@Column(length = 20)
@GeneratedValue(strategy = GenerationType.AUTO, generator = "gg")
//自定义生成主键
@GenericGenerator(name = "gg", strategy = "top.lingkang.springboothibernate.config.PrimaryGenerator")
private String id;
@Column(length = 40)
private String username;
@Column(length = 64)
private String password;
@Column(length = 20)
private String nickname;
@Column(name = "create_time")
private Date createTime;
}
用户的角色表
package top.lingkang.springboothibernate.entity;
import lombok.Data;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
@Data
@Entity
@Table(name = "T_USER_ROLE")// 大小写不同,用于兼容不同数据库
public class UserRoleBean {
// 主键采用string为了兼容更多数据库
@Id
@Column(length = 24)
@GeneratedValue(strategy = GenerationType.AUTO, generator = "gg")
//自定义生成主键
@GenericGenerator(name = "gg", strategy = "top.lingkang.springboothibernate.config.PrimaryGenerator",
//自定义ID前缀
parameters = {@org.hibernate.annotations.Parameter(name = "prefix", value = "R_")})
private String id;
@Column(name = "user_id",length = 20)
private String userId;
@Column(name = "role_id",length = 20)
private String roleId;
}
首次启动使用 create 模式,启动完成即可生成对应的映射表在数据库:


四、操作数据库
4.1 增
/**
* 此处需要注意,hibernate的增删改需要事务提交,否则不能保存到数据库
* import org.springframework.transaction.annotation.Transactional;
*/
@Transactional
@GetMapping("add")
public Object add() {
UserBean bean = new UserBean();
bean.setCreateTime(new Date());
bean.setUsername("lingkang");
bean.setNickname("凌康");
bean.setPassword("123456");
System.out.println(sessionFactory.getCurrentSession().save(bean));
return bean;
}
hibernate的增删改需要事务提交,否则不能保存到数据库。官网example:

4.2 改
/**
* 此处需要注意,hibernate的增删改需要事务提交,否则不能保存到数据库
* import org.springframework.transaction.annotation.Transactional;
*/
@Transactional
@GetMapping("update")
public Object update() {
Session currentSession = sessionFactory.getCurrentSession();
List<UserBean> id = currentSession.createQuery("from UserBean where id=:id")
.setParameter("id", "1414241573973135360").list();
System.out.println(id);
if (!id.isEmpty()){
UserBean bean = id.get(0);
bean.setNickname("凌康,你好!");
// 更新
currentSession.update(bean);
}
return id;
}

4.3 删除
/**
* 此处需要注意,hibernate的增删改需要事务提交,否则不能保存到数据库
* import org.springframework.transaction.annotation.Transactional;
*/
@Transactional
@GetMapping("delete")
public Object delete() {
// UserBean bean = new UserBean();
// bean.setId("1414240012135960576");
// 缺点,不存在的数据会报异常
// sessionFactory.getCurrentSession().delete(bean);
// 推荐 删除不会报异常
int res = sessionFactory.getCurrentSession().createQuery("delete from UserBean where id=:id")
.setParameter("id", "1414243500257579008").executeUpdate();
System.out.println(res);
return res;
}
4.4 查,留到下一章,
查询比较复杂,存在多对多,一对多、一对一等关系,篇幅原因,留到一下章:
https://blog.csdn.net/weixin_44480167/article/details/118662257
这里贴出hibernate常用的BaseDao公共接口
BaseDao接口
import java.io.Serializable;
import java.util.List;
public interface BaseDao<T> {
T save(T t);
void delete(T entity);
void update(T entity);
T findById(Serializable id);
List<T> findAll();
}
BaseDao接口实现
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.lingkang.demohibernate.dao.BaseDao;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;
@Service
public class BaseDaoImpl<T> implements BaseDao<T> {
@Autowired
private SessionFactory sessionFactory;
@Override
public T save(T entity) {
sessionFactory.getCurrentSession().save(entity);
return entity;
}
@Override
public void delete(T entity) {
sessionFactory.getCurrentSession().delete(entity);
}
@Override
public void update(Object entity) {
sessionFactory.getCurrentSession().update(entity);
}
@Override
public T findById(Serializable id) {
Class tclass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
return (T) sessionFactory.getCurrentSession().get(tclass, id);
}
@Override
public List<T> findAll() {
Class tclass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
return sessionFactory.getCurrentSession().createQuery(
"from " + tclass.getSimpleName()
).list();
}
}
UserDao 继承使用如下:
public interface UserDao extends BaseDao<UserBean>{
}
UserDao 继承使用实现如下:
import org.springframework.stereotype.Service;
import top.lingkang.demohibernate.dao.UserDao;
import top.lingkang.demohibernate.entity.UserBean;
@Service
public class UserDaoImpl extends BaseDaoImpl<UserBean> implements UserDao {
}
调用如下
@Autowired
private UserDao userDao;
@Override
public UserBean saveUser(UserBean bean) {
return userDao.save(bean);
}
springboot整合hibernate(非JPA)(一)的更多相关文章
- springboot整合spring Data JPA
今天敲代码,一连串的错误,我也是服气~果然,我们不是在出bug,就是在找bug的路上…… 今天完成的是springboot整合spring data JPA ,出了一连串的错,真是头大 java.sq ...
- SpringBoot整合Mybatis、SpringBoot整合Spring Data JPA
Springboot Mybatis <?xml version="1.0" encoding="UTF-8"?> <project xmln ...
- SpringBoot 整合 hibernate 连接 Mysql 数据库
前一篇搭建了一个简易的 SpringBoot Web 项目,最重要的一步连接数据库执行增删改查命令! 经过了一天的摸爬滚打,终于成功返回数据! 因为原来项目使用的 SpringMVC + Hibern ...
- Spring Data-Spring整合Hibernate基于JPA规范
JPA:由 Sun 公司提供了一对对于持久层操作的标准(接口+文档) Hibernate:是 Gavin King 开发的一套对于持久层操作的自动的 ORM 框架. Hibernate JPA:是在 ...
- springboot整合spring data jpa 动态查询
Spring Data JPA虽然大大的简化了持久层的开发,但是在实际开发中,很多地方都需要高级动态查询,在实现动态查询时我们需要用到Criteria API,主要是以下三个: 1.Criteria ...
- SpringBoot整合Hibernate Validator实现参数验证功能
在前后端分离的开发模式中,后端对前端传入的参数的校验成了必不可少的一个环节.但是在多参数的情况下,在controller层加上参数验证,会显得特别臃肿,并且会有许多的重复代码.这里可以引用Hibern ...
- SpringBoot整合Hibernate
编写配置文件 <!--配置读取properties文件--> <context:property-placeholder location="classpath:jdbc. ...
- springboot整合hibernate案例
1.运行环境 开发工具:intellij idea JDK版本:1.8 项目管理工具:Maven 4.0.0 2.GITHUB地址 https://github.com/nbfujx/springBo ...
- SpringBoot整合系列-整合JPA
原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9959865.html SpringBoot整合JPA进行数据库开发 步骤 第一步:添加必 ...
- SpringBoot整合StringData JPA
目录 SpringBoot整合StringData JPA application.yml User.class UserRepository.java UserController SpringBo ...
随机推荐
- fatal: 无法访问 'https://github.com/nmww/lingyun.git/':Failed to connect to github.com port 443 after 13 ms: Connection refused
fatal: 无法访问 'https://github.com/nmww/lingyun.git/':Failed to connect to github.com port 443 after 13 ...
- JNI编程之字符串处理
java中的字符串类型是String,对应的jni类型是jstring,由于jstring是引用类型,所以我们不能像基本数据类型那样去使用它,我们需要使用JNIEnv中的函数去处理jstring,下面 ...
- Linux 在多个文件中搜索关键字
摘要:使用grep或者rg在当前目录下所有文件中查找关键字. 在Linux操作系统下,搜索文件中的关键字可帮助用户快速找到所需的信息,满足快速排查问题的需求.在大型系统中,文件可能被保存在多个目录 ...
- 【译】为什么命名“它”为依赖属性(DependencyProperty)
当我们创建新的类和成员时,我们花费了大量的时间和精力是它们尽可能的好用,好理解,好发现.通常我们会遵循.Net框架设计指南,尤其是会不断地研究这个新类与其他类,未来计划等内容之间的关系. 当命名依赖属 ...
- 一个重量级HTTP api的304优化分析与突发失效问题解决
背景 最近查看nginx log排查问题时,意外中发现重量级的主页 list api 304比例已暴跌至不到1%,之前该比例长期维持在30%以上,近期也未改动过相关逻辑,跟进后最终发现是服务端本地ca ...
- html考点
编程: 1.放大镜不考 2.购物不考 广告 html html必不可少的标签 <meta charset="utf-8"/> 引入css jis 外部 注释html , ...
- [C++]线段树 区间修改 单点查询
线段树 区间修改 单点查询 请先阅读上一篇Bolg 算法思想 由于是区间修改 那就把下放的每一个线段给套上一层标记 来表达增加的值 单点查询就把那些标记穿起来就行了 当然 还要加上那原来的值 来举个例 ...
- influxdb 连续查询使用总结
转载请注明出处: 1.定义: InfluxDB 连续查询(Continuous Query)是一种自动化查询类型,该查询会根据定义的时间间隔定期运行,并将结果存储在新的目标测量中.这样的查询通常用于处 ...
- 基于AStyle的代码格式化脚本 [已开源]
这是一个简单的windows端脚本 主要用于C/C++代码的格式化 可以添加到鼠标右键,直接在.C/.H文件上右键格式化代码 具体开源地址 https://gitee.com/svchao/code_ ...
- CF1592C. Bakry and Partitioning
原题链接:CF1592C. Bakry and Partitioning 题意: 给定一个\(n\)个点,\(n - 1\)条边的树,并且每个点都有权值\(w_i\),让你最少割掉一条边最多割掉\(k ...