Hibernate 将 Java 类映射到数据库表中,从 Java 数据类型中映射到 SQL 数据类型中,并把开发人员从 95% 的公共数据持续性编程工作中解放出来。是传统 Java 对象和数据库服务器之间的桥梁,用来处理基于 O/R 映射机制和模式的那些对象。
Hibernate 优势
Hibernate 使用 XML 文件来处理映射 Java 类别到数据库表格中,并且不用编写任何代码。
为在数据库中直接储存和检索 Java 对象提供简单的 APIs。
如果在数据库中或任何其它表格中出现变化,那么仅需要改变 XML 文件属性。
抽象不熟悉的 SQL 类型,并为我们提供工作中所熟悉的 Java 对象。
Hibernate 不需要应用程序服务器来操作。
操控你数据库中对象复杂的关联。
最小化与访问数据库的智能提取策略。
提供简单的数据询问。
build.gradle.kts
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("org.springframework.boot") version "2.3.7.RELEASE"
id("io.spring.dependency-management") version "1.0.10.RELEASE"
kotlin("jvm") version "1.3.72"
kotlin("plugin.spring") version "1.3.72"
}
group = "com"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_1_8
configurations {
compileOnly {
extendsFrom(configurations.annotationProcessor.get())
}
}
repositories {
mavenLocal() //配置先从本地仓库寻找jar包,优先寻找上一个配置,找到不执行下面的配置
mavenCentral() //配置从中央仓库寻找
google() //第三方仓库
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
// https://mvnrepository.com/artifact/org.hibernate/hibernate-core
implementation("org.hibernate:hibernate-core:5.6.10.Final")
runtimeOnly("mysql:mysql-connector-java:5.1.6")
compileOnly("org.projectlombok:lombok")
annotationProcessor("org.projectlombok:lombok")
testImplementation("org.springframework.boot:spring-boot-starter-test") {
exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
}
// https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter
implementation("com.alibaba:druid-spring-boot-starter:1.2.8")
// https://mvnrepository.com/artifact/org.springframework/spring-orm
implementation("org.springframework:spring-orm:5.3.21")
// https://mvnrepository.com/artifact/cn.hutool/hutool-core
implementation("cn.hutool:hutool-core:5.8.4")
}
tasks.withType<Test> {
useJUnitPlatform()
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "1.8"
}
}
application.yml
server:
port: 8080
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
name: defaultDataSource
url: jdbc:mysql://localhost:3306/people?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
password: 123456
username: root
配置数据源
package com.spring_hibernate.config
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
class DataSourceConfig {
@Bean
@ConfigurationProperties("spring.datasource")
fun dataSource(): DataSource? {
val source = DruidDataSource()
//source.setDriverClassName("com.mysql.cj.jdbc.Driver");
source.isBreakAfterAcquireFailure = true
source.name = "root"
source.initialSize = 1
//最大活动
source.maxActive = 10
source.maxWait = 60000
//配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
source.timeBetweenEvictionRunsMillis = 60000
//配置一个连接在池中最小生存的时间,单位是毫秒
source.minEvictableIdleTimeMillis = 300000
//每分钟打印一次连接状态日志
//source.setTimeBetweenLogStatsMillis(60000);
return source
}
}
配置hibernate
package com.spring_hibernate.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 java.util.*
import javax.annotation.Resource
import javax.sql.DataSource
@Component
class HibernateToConfig {
@Resource
private val dataSource: DataSource? = null
/**
* 此处bean为根据 hibernate 官网配置文件 hibernate.cfg.xml 改造的
* https://docs.jboss.org/hibernate/orm/5.5/quickstart/html_single/hibernate-tutorials.zip
*
* @return
*/
@Bean
fun sessionFactory(): LocalSessionFactoryBean? {
val bean = LocalSessionFactoryBean()
if (dataSource != null) {
bean.setDataSource(dataSource)
}
// 扫描实体类
bean.setPackagesToScan("com.spring_hibernate.entity")
val properties = Properties()
properties.setProperty("current_session_context_class", "thread")
val druidDataSource = dataSource as DruidDataSource?
properties.setProperty("connection.pool_size", druidDataSource!!.maxActive.toString())
// 配置方言 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", "update")
bean.setHibernateProperties(properties)
return bean
}
}
在配置hibernate时,需要配置实体类的包,然后在 properties.setProperty(“hibernate.hbm2ddl.auto”, “create”) 在第一次启动时,就会根据类对象,创建数据表,但是在这之前需要指定数据库,在application.yml中进行指定,本demo使用的是MySQL5.1.6的驱动,所以在application.yml中是com.mysql.jdbc.Driver,要是使用更高版本的驱动,需要使用com.mysql.cj.jdbc.Driver
自定义主键生成
package com.spring_hibernate.util
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.*
/**
* 采用雪花算法生成主键
* 2021年7月11日22:11:55
*/
class PrimaryGenerator : Configurable, IdentifierGenerator {
var snowflake: Snowflake? = IdUtil.getSnowflake(1, 1)
private var pre = ""
@Throws(MappingException::class)
override fun configure(type: Type, params: Properties, serviceRegistry: ServiceRegistry) {
val prefix = params.getProperty("prefix")
if (prefix != null) pre = prefix
}
@Throws(HibernateException::class)
override fun generate(session: SharedSessionContractImplementor, `object`: Any): Serializable {
//雪花算法生成ID
return pre + snowflake!!.nextIdStr()
}
}
实体类
package com.spring_hibernate.entity
import lombok.Data
import org.hibernate.annotations.GenericGenerator
import java.util.*
import javax.persistence.*
@Data
@Entity
@Table(name = "t_user")
class UserBean {
// 主键采用string为了兼容更多数据库
@Id
@Column(length = 20)
@GeneratedValue(strategy = GenerationType.AUTO, generator = "gg") //自定义生成主键
@GenericGenerator(name = "gg", strategy = "com.spring_hibernate.util.PrimaryGenerator")
val id: String? = null
@Column(length = 40)
var username: String? = null
@Column(length = 64)
var password: String? = null
@Column(length = 20)
var nickname: String? = null
@Column(name = "create_time")
var createTime: Date? = null
}
在第一次运行完之后,就会在指定数据库创建表,该表的字段和上面的实体类一一对应
controller
package com.spring_hibernate.controller
import com.spring_hibernate.entity.UserBean
import com.spring_hibernate.service.UserBeanService
import com.spring_hibernate.util.R
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.transaction.annotation.Transactional
import org.springframework.web.bind.annotation.*
@RestController
@RequestMapping("/user")
class UserBeanController {
@Autowired
lateinit var userBeanService: UserBeanService
@Transactional
@PostMapping
fun insertOne(@RequestBody userBean: UserBean): R<*> {
return userBeanService.insertOne(userBean)
}
@Transactional
@PutMapping
fun updateOne(@RequestBody userBean: UserBean):R<*>{
return userBeanService.updateOne(userBean)
}
@Transactional
@DeleteMapping
fun deleteOne(@RequestBody userBean: UserBean): R<*>{
return userBeanService.deleteOne(userBean)
}
@Transactional
@GetMapping
fun getOne(id:String):R<*>{
return userBeanService.getOne(id)
}
@Transactional
@GetMapping("/all")
fun getAll():R<*>{
return userBeanService.getAll()
}
}
这里的R还是自己封装好的返回值类型
dao层
package com.spring_hibernate.service.impl
import com.spring_hibernate.entity.UserBean
import com.spring_hibernate.service.UserBeanService
import com.spring_hibernate.util.R
import org.hibernate.SessionFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Repository
import java.util.*
@Repository
class UserBeanServiceImpl : UserBeanService {
@Autowired
lateinit var sessionFactory:SessionFactory
override fun insertOne(userBean: UserBean): R<*> {
userBean.createTime = Date()
val line = sessionFactory.currentSession.save(userBean)
println("line::$line")
return R.ok(line,"插入成功")
}
override fun updateOne(userBean: UserBean): R<*> {
val user:UserBean = sessionFactory
.currentSession
.createQuery("from UserBean where id=:id")
.setParameter("id", userBean.id).uniqueResult() as UserBean
user.nickname = userBean.nickname
user.username = userBean.username
user.password = userBean.password
sessionFactory.currentSession.update(user)
return R.ok(null,"修改数据")
}
override fun deleteOne(userBean: UserBean): R<*> {
val res = sessionFactory.currentSession
.createQuery("delete from UserBean where id=:id")
.setParameter("id", userBean.id).executeUpdate()
return R.ok(res,"删除成功")
}
override fun getOne(id: String): R<*> {
val user:UserBean = sessionFactory
.currentSession
.createQuery("from UserBean where id=:id")
.setParameter("id", id).uniqueResult() as UserBean
return R.ok(user,"找到一条记录")
}
override fun getAll(): R<*> {
val list = sessionFactory
.currentSession
.createQuery("from UserBean")
.list()
return R.ok(list,"查询所有")
}
}
上述是一些基本的CRUD操作,需要查找更多的模板代码,可以去如下地址
https://www.w3cschool.cn/hibernate/hvqb1ie5.html