springboot+kotlin+gradle+hibernate学习笔记

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值