YashanDB持久化框架操作示例(jpa-hibernate)

1.背景介绍

基本概念:

1.JPA(Java Persistence API)是一种标准化的Java ORM(对象关系映射)规范,它定义了一套用于对象和关系数据库之间进行映射的API。 

2.Spring Data JPA是Spring框架对JPA的封装,它通过提供一系列接口和注解,简化了开发者对JPA的使用。

优势:

1.简化数据访问层开发:Spring Data JPA提供了一个自动生成常见数据访问层代码的机制,开发者只需要定义接口和方法命名规则,无需编写具体的实现代码。

2.提高代码的可读性:借助Spring Data JPA提供的接口和方法命名规则,开发者可以通过简单的方法命名来实现复杂的查询功能,使代码更加简洁和可读。

3.支持多种数据源:Spring Data JPA支持多种数据源(如关系数据库、NoSQL数据库等),开发者可以通过简单的配置切换数据源。

4.集成其他Spring组件:Spring Data JPA可以很方便地与其他Spring组件(如Spring MVC、Spring Boot等)集成,提供一体化的开发体验。

应用场景 在应用程序开发中,Spring Data JPA可以用于处理各种数据库操作,包括增删改查、复杂查询、分页等。开发者只需要定义实体类和接口,Spring Data JPA会根据方法命名规则自动生成具体的查询语句。此外,Spring Data JPA还支持事务管理,可以保证数据库操作的一致性和完整性。极大地简化了数据访问层的开发,提高了开发效率和代码质量。

2.环境说明

以使用Maven为例:

Java环境:Jdk22(安装后需配置)

hibernate-core版本:5.4.32.Final不高于6版本

Springboot版本2.3.12.RELEASEJPA不高于3版本

Maven版本:3.9.8(安装后需配置)

崖山驱动版本:1.6.9

崖山方言包版本:1.0.0

Maven的pom.xml文件:(用于验证整个jpa-hibernate与YashanDB的兼容性,所以涵盖很多的依赖包,如只需其中一种或者几种功能,保留相应的依赖即可。)

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId> 
        <artifactId>spring-boot-starter-data-jpa</artifactId>
        <version>2.3.12.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>5.10.2</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.2</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>RELEASE</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>javax.persistence</groupId>
        <artifactId>javax.persistence-api</artifactId>
        <version>2.2</version>
    </dependency>
</dependencies>

3.添加YashanDB驱动和方言包

打开Idea的ProjectStructure,使用Libraries添加YashanDB驱动,对于多模块,只需要添加到对应的模块即可。(YashanDB驱动:在产品软件包或安装目录的Drivers文件夹中,查找yasdb-jdbc-版本号.jar文件,例如yasdb-jdbc-1.6.9.jar)

也可以将YashanDB驱动上传到本地的Maven私服,然后在Pom文件中引入。

用同样的方式去添加崖山的方言包。(方言包:在产品软件包中,文件名为YashanDialect-for-hibernate5-版本号.jar,例如YashanDialect-for-hibernate5-1.0.0.jar)

注:若maven无法识别,直接在工程目录下建一个lib文件夹,把jar包放进去,然后引进来

 <dependency>
        <groupId>com.yashandb</groupId>
        <artifactId>yashandb-jdbc</artifactId>
        <version>1.6.9</version>
        <scope>system</scope>
        <systemPath>${project.basedir}/lib/yashandb-jdbc-1.6.9.jar</systemPath> 
<!--项目根目录下的lib文件夹下-->
    </dependency>
    <dependency>
        <groupId>org.hibernate.dialect</groupId>
        <artifactId>YasDialect</artifactId>
        <version>1.0.0</version>
        <scope>system</scope>
      <systemPath>${project.basedir}/lib/YashanDialect-for-hibernate5-1.0.0.jar</systemPath> 
<!--项目根目录下的lib文件夹下-->
    </dependency>

4.数据源和jpa-hibernate配置

本文采用application.properties文件进行参数配置。请将下例中的host_ip、port、dbname、username和password修改为实际值。 注意spring.jpa.properties.hibernate.dialect这个配置项,必须设置为org.hibernate.dialect.YasDialect。

spring.application.name=demo
spring.datasource.url=jdbc:yasdb://127.0.0.1:1688/yasdb
spring.datasource.username=regress
spring.datasource.password=regress
spring.datasource.driver-class-name=com.yashandb.jdbc.Driver
#方言必须设置为崖山方言YasDialect
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.YasDialect
#是否自动建表
spring.jpa.properties.hibernate.hbm2ddl.auto=create
#字段名和数据库中对象名的映射关系:
spring.jpa.properties.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy

5.jpa-hibernate功能验证

创建entity

创建User用户的entity,并使其与Table对应。

package com.example.pojo;

import lombok.Data;

import org.hibernate.annotations.ColumnDefault;

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

import javax.persistence.Id;

import javax.persistence.SequenceGenerator;

import javax.persistence.Table;

import java.time.LocalTime;

@Data@Entity@Table(name = "user1")

public class User {

    @Id //hibernate要求必须要一个id(主键),不然会报错

    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ID_GENERATOR")

    @SequenceGenerator(name = "ID_GENERATOR", sequenceName = "user_sequence")

    @ColumnDefault("user_sequence.nextval")

    private int id;

    

    @Column(name = "name")

    private String name;

    public User() {

    }

    public User(String name) {

        this.name = name;

    }

    public User(int id, String name) {

        this.id = id;

        this.name = name;

    }}

定义Repository接口,可以继承JpaRepository,也可以继承CrudRepository,视个人使用习惯或者团队要求自由选择,本例子中使用JpaRepository:

package com.example.dao;

import com.example.pojo.User;

import org.springframework.data.jpa.repository.JpaRepository;

import org.springframework.stereotype.Repository;

@Repository

public interface UserRepository extends JpaRepository<User,Integer> {//注意JpaRepository<User,Integer>这里传入的泛型类型,第一个是我们上面定义的Entity,第二个是Entity的主键的类型//里面可以不实现任何接口,JpaRepository的默认接口已经足够我们使用了。}

主类

package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

创建单元测试类

package com.example;

import com.example.dao.UserRepository;

import com.example.pojo.User;

import org.junit.Before;

import org.junit.Test;

import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.test.context.SpringBootTest;

import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

import static org.junit.Assert.assertEquals;

@RunWith(SpringRunner.class)

@SpringBootTest

public class UserTest {

    @Autowired

    private UserRepository repository;

    @Before

    public void deleteAllUser(){

        repository.deleteAll();

    }



    @Test

    public void testAddUser() {

        User user = new User("sasa");

        repository.save(user);

        List<User> list = repository.findAll();

        assertEquals(1, list.size());

    }}

6.常见问题

(1版本不匹配导致崖山方言包失效

目前崖山方言包只支持hibernate5版本JPA不超过3版本(JPA 3以上版本只支持hibernate 6)示例如下:

解决方法:调整安装版本

(2) 重新加载maven项目后YashanDB驱动和方言包丢失

通过Libraries添加YashanDB驱动和方言包在重新加载maven项目后可能会丢失导致报错

解决方法:直接在工程目录下建一个lib文件夹,把jar包放进去,然后引进

(3) SpringBoot项目报错::Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.

根据问题看出:springboot启动时会自动注入数据源和配置jpa

解决方法:在@SpringBootApplication中排除其注入

@SpringBootApplication(exclude=DataSourceAutoConfiguration.class)

(4) 自增主键的使用

一般情况下,在使用Hibernate持久化框架时,需要定义Entity实体类,实体类中存在一个Id属性,将该属性作为业务表的自增主键列,示例如下:

@Id
@SequenceGenerator(name="generator",sequenceName="user_sequence", allocationSize =1)
@ColumnDefault("user_sequence.nextval")
@GeneratedValue(strategy= GenerationType.AUTO, generator = "generator")
private int id;

在上述示例中,user_sequence为序列名,由您自定义命名。

Note:

  1. 注意保持@SequenceGenerator参数sequenceName和@ColumnDefault中的序列名称一致。

  2. 如果sequenceName指定的序列名是驼峰格式,hibernate会把它改成下划线,和表名,列名等一样处理;但是@ColumnDefault这个注解的value是不处理驼峰格式的,所以就会导致sequenceName和ColumnDefault里面序列器名称不一致,启动时建表会失败,所以注意这里不要用驼峰命名,直接用下划线风格命名。

此外,也可以不指定@ColumnDefault,和@SequenceGenerator。

这时hibernate使用默认序列hibernate_sequence去自增,示例如下:

@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private int id;

(5) 服务启动失败

使用hibernate配置hbm2ddl.auto=validate时,服务启动时会进行校验;当数据库表结构数据类型与Java实体类数据类型不一致时,Schema-validation校验失败;从而导致容器初始化Hibernate SessionFactory时失败。

spring.jpa.properties.hibernate.hbm2ddl.auto=validate

出现这个问题时,我们需要修改数据库表结构,或修改Java实体类数据类型,保持数据库表结构与Java实体类数据类型一致。

或者,将hbm2ddl.auto配置设置为none,服务启动时不进行校验。

(6) 不支持TEXT数据类型

MySQL迁移前,业务中可能使用了TEXT这一数据类型,示例如下:

@Column(name = "file_types", columnDefinition = "TEXT")
private String fileTypes;

迁移后,YashanDB不支持TEXT数据类型,导致报错。

YashanDB虽不支持TEXT类型,但支持CLOB类型,用于保存大量字符数据。因此,建议将TEXT改为CLOB,即columnDefinition = "TEXT"改为columnDefinition = "CLOB"。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值