Springboot + Openjpa 整合 GBase8s 實踐

wj_2021發表於2021-11-25

本文我們將先來介紹JPA以及OpenJPA之間的關係,然後通過一個手把手的應用案例來講述 Springboot 和 Openjpa 整合 GBase8s 。那麼就讓我們開始吧。


JPA

JPA(Java Persistence API)作為Java EE 5.0平臺標準的ORM規範,將得到所有JavaEE伺服器的支援。Sun這次吸取了之前EJB規範慘痛失敗的經歷,在充分吸收現有ORM框架的基礎上,得到了一個易於使用、伸縮性強的 ORM規範。從目 前的開發社群的反應上看,JPA受到了極大的支援和讚揚,JPA作為ORM領域標準化整合者的目標應該不難實現。


JPA由EJB 3.0軟體專家組開發,作為 JSR-220實現的一部分。但它不囿於EJB3.0,你可以在 Web應用、甚至桌面應用中使用。JPA的宗旨是為POJO提供持久化標準規範,由此可見,經過這幾年的實踐探索,能夠脫離容器獨立執行,方便開發和測試的理念已經深入人心了。


JPA包括以下 3方面的技術:


(1)ORM對映後設資料,JPA支援XML和JDK 5.0註解兩種後設資料的形式,後設資料描述物件和表之間的對映關係,框架據此將實體物件持久化到資料庫表中;


(2)JPA 的API,用來操作實體物件,執行CRUD操作,框架在後臺替我們完成所有的事情,開發者從繁瑣的JDBC和SQL程式碼中解脫出來。


(3)查詢語言,這是持久化操作中很重要的一個方面,通過物件導向而非面向資料庫的查詢語言查詢資料,避免程式的SQL語句緊密耦合。


OpenJPA

OpenJPA 是 Apache 組織提供的開源專案,它實現了 EJB 3.0 中的 JPA 標準,為開發者提供功能強大、使用簡單的持久化資料管理框架。OpenJPA 封裝了和關係型資料庫互動的操作,讓開發者把注意力集中在編寫業務邏輯上。


OpenJPA 可以作為獨立的持久層框架發揮作用,也可以輕鬆的與其它 Java EE 應用框架或者符合 EJB 3.0 標準的容器整合。


除了對 JPA 標準的支援之外,OpenJPA 還提供了非常多的特性和工具支援讓企業應用開發變得更加簡單,減少開發者的工作量,包括允許資料遠端傳輸/離線處理、資料庫/物件檢視統一工具、使用快取(Cache)提升企業應用效率等。


資料遠端傳輸 / 離線處理


JPA 標準規定的執行環境是 "本地" 和 "線上" 的。本地是指 JPA 應用中的 EntityManager 必須直接連線到指定的資料庫,而且必須和使用它的程式碼在同一個 JVM 中。線上是指所有針對實體的操作必須在一個 EntityManager 範圍中執行。這兩個特徵,加上 EntityManager 是非序列化的,無法在網路上傳輸,導致 JPA 應用無法適用於企業應用中的 C/S 實現模式。OpenJPA 擴充套件了這部分介面,支援資料的遠端傳輸和離線處理。


資料庫 / 物件檢視統一工具


使 用 OpenJPA 開發企業應用時,保持資料庫和物件檢視的一致性是非常重要的工作,OpenJPA 支援三種模式處理資料庫和物件檢視的一致性:正向對映(Forward Mapping)、反向對映(Reverse Mapping)、中間匹配(Meet-in-the-Middle Mapping),並且為它們提供了相應的工具支援。


正向對映 是指使用 OpenJPA 框架中提供的 org.apache.openjpa.jdbc.meta.MappingTool 工具從開發者提供的實體以及在實體中提供的物件 / 關係對映註釋生成相應的資料庫表。


反向對映 是指 OpenJPA 框架中提供的 org.apache.openjpa.jdbc.meta.ReverseMappingTool 工具從資料庫表生成符合 JPA 標準要求的實體以及相應的物件 / 關係對映註釋內容。


中間匹配 是指開發者負責建立資料庫表、符合 JPA 標準的實體和相應的物件 / 關係對映註釋內容,使用 OpenJPA 框架中提供的 org.apache.openjpa.jdbc.meta.MappingTool 工具校驗二者的一致性。 使用快取提升效率


效能是企業應用重點關注的內容之一,快取是提升企業系統效能的重要手段之一。OpenJPA 針對資料持久化提供多種層次、多方面的快取支援,包括資料、查詢、彙編查詢的快取等。這些快取的應用可以大幅度的提高企業應用的執行效率。


(以上引用自:百度百科)


工程實踐

本案例整合 springboot 和 openjpa 完成基礎資料操作的 restful 服務,工程目錄如下 : 另外:openjpa原生並不支援gbase8s,廠商提供擴充套件版本,可以聯絡廠商獲取對應的openjpa版本。



 


maven配置:


<project xmlns=" xmlns:xsi="

xsi:schemaLocation="

<modelVersion>4.0.0</modelVersion>

<groupId>wang.datahub</groupId>

<artifactId>spring-boot-openjpa-gbasedbt</artifactId>

<version>0.0.1-SNAPSHOT</version>

<packaging>jar</packaging>

<name>lijiaqi</name>

<description>Spring boot app that uses openJpa with gbasedbt instead of hibernate</description>

 

 <!--   <parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>1.2.5.RELEASE</version>

<relativePath/>

</parent>-->

 

<properties>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<java.version>1.8</java.version>

<openjpa.version>3.1.0</openjpa.version>

<spring.boot.version>1.2.5.RELEASE</spring.boot.version>

<spring.version>4.2.1.RELEASE</spring.version>

</properties>

 

<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-data-jpa</artifactId>

<version>${spring.boot.version}</version>

<exclusions>

<exclusion>

<artifactId>hibernate-entitymanager</artifactId>

<groupId>org.hibernate</groupId>

</exclusion>

</exclusions>

</dependency>

 

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-logging</artifactId>

<version>${spring.boot.version}</version>

</dependency>

 

<dependency>

<groupId>org.apache.openjpa</groupId>

<artifactId>openjpa-all</artifactId>

<version>${openjpa.version}</version>

<scope>system</scope>

<systemPath>${project.basedir}/libs/openjpa-all-3.1.0.jar</systemPath>

</dependency>

<dependency>

<groupId>com.gbase</groupId>

<artifactId>gbasedbtjdbc</artifactId>

<version>1.0</version>

<scope>system</scope>

<systemPath>${project.basedir}/libs/gbasedbtjdbc.jar</systemPath>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<version>${spring.boot.version}</version>

<scope>test</scope>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

<version>${spring.boot.version}</version>

 

</dependency>

</dependencies>

<build>

<plugins>

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-compiler-plugin</artifactId>

<version>3.1</version>

<configuration>

<source>${java.version}</source>

<target>${java.version}</target>

<encoding>${project.build.sourceEncoding}</encoding>

<compilerArgument>-Xlint:all</compilerArgument>

<showWarnings>true</showWarnings>

</configuration>

</plugin>

<plugin>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-maven-plugin</artifactId>

<version>${spring.boot.version}</version>

<dependencies>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>springloaded</artifactId>

<version>1.2.4.RELEASE</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-instrument</artifactId>

<version>${spring.version}</version>

</dependency>

</dependencies>

<configuration>

<agent>${settings.localRepository}/org/springframework/spring-instrument/${spring.version}/spring-instrument-${spring.version}.jar</agent>

<agent>${settings.localRepository}/org/apache/openjpa/openjpa/${openjpa.version}/openjpa-${openjpa.version}.jar</agent>

</configuration>

</plugin>

<plugin>

<groupId>org.apache.openjpa</groupId>

<artifactId>openjpa-maven-plugin</artifactId>

<version>${openjpa.version}</version>

<configuration>

<includes>**/entity/*.class</includes>

<addDefaultConstructor>true</addDefaultConstructor>

<enforcePropertyRestrictions>true</enforcePropertyRestrictions>

<sqlFile>src/main/resources/schema.sql</sqlFile>

<persistenceXmlFile>src/main/resources/META-INF/persistence.xml</persistenceXmlFile>

</configuration>

<executions>

<execution>

<id>enhancer</id>

<phase>process-classes</phase>

<goals>

<goal>enhance</goal>

</goals>

</execution>

</executions>

<!-- <dependencies>-->

<!-- <dependency>-->

<!-- <groupId>org.apache.openjpa</groupId>-->

<!-- <artifactId>openjpa</artifactId>-->

<!-- <version>${openjpa.version}</version>-->

<!-- </dependency>-->

<!-- </dependencies>-->

</plugin>

</plugins>

</build>

 

</project>

jpa配置,建立

persistence.xml

放在 

src\main\resources\META-INF

<?xml version="1.0"?>

<persistence version="1.0"

             xmlns=" xmlns:xsi="

             xsi:schemaLocation="

       

        /persistence_1_0.xsd">

    <persistence-unit name="persistence-unit" transaction-type="RESOURCE_LOCAL">

        <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>

<!--        <class>com.openjpa.example.entity.Employee</class>-->

<!--        <class>com.openjpa.example.entity.Manager</class>-->

        <class>wang.datahub.example.entity.Userinfo</class>

        <properties>

            <property name="openjpa.Log" value="DefaultLevel=WARN, Tool=INFO, SQL=TRACE" />

            <property name="openjpa.jdbc.MappingDefaults" value="IndexLogicalForeignKeys=false,IndexDiscriminator=false"/>

            <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>

            <property name="openjpa.jdbc.DBDictionary" value="gbasedbt"/>

            <property name="openjpa.ConnectionURL"

                      value="jdbc:gbasedbt-sqli://172.24.110.229:90881/t1:GBASEDBTSERVER=ol_gbasedbt1210_1;NEWCODESET=UTF8,zh_cn.UTF8,57372;DATABASE=t1;DB_LOCALE=en_US.819;"/>

            <property name="openjpa.ConnectionDriverName"

                      value="com.gbasedbt.jdbc.Driver"/>

            <property name="openjpa.ConnectionUserName"

                      value="gbasedbt"/>

            <property name="openjpa.ConnectionPassword"

                      value="dafei1288"/>

            <property name="openjpa.RuntimeUnenhancedClasses" value="supported" />

        </properties>

    </persistence-unit>

</persistence>

系統配置application.yml


server:

  port: 8088

#  context-path: /

#spring-jpa-data資料庫配置資訊   org.springframework.boot.autoconfigure.jdbc.DataSourceProperties

spring:

  jpa:

    show-sql: true

    generate-ddl: true

    hibernate:

      ddl-auto: create-drop

  datasource:

    driver-class-name: com.gbasedbt.jdbc.Driver

    url: jdbc:gbasedbt-sqli://172.24.110.229:9088/t1:GBASEDBTSERVER=ol_gbasedbt1210_1;NEWCODESET=UTF8,zh_cn.UTF8,57372;DATABASE=t1;DB_LOCALE=en_US.819;

    username: gbasedbt

    password: dafei1288

建立實體類:


package wang.datahub.example.entity;

import javax.persistence.*;

@Entity

@Table

public class Userinfo {

    @Id

    @GeneratedValue(strategy = GenerationType.AUTO)

    private int id;

    @Column

    private String username;

    @Column

    private int age;

    public int getId() {

        return id;

    }

    public void setId(int id) {

        this.id = id;

    }

    public String getUsername() {

        return username;

    }

    public void setUsername(String username) {

        this.username = username;

    }

    public int getAge() {

        return age;

    }

    public void setAge(int age) {

        this.age = age;

    }

    @Override

    public String toString() {

        return "Userinfo{" +

                "id='" + id + '\'' +

                ", username='" + username + '\'' +

                ", age=" + age +

                '}';

    }

}

建立UserinfoRepository 用於完成持久化操作


package wang.datahub.example.repository;

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

import org.springframework.stereotype.Repository;

import wang.datahub.example.entity.Userinfo;

@Repository

public interface UserinfoRepository extends JpaRepository<Userinfo, String> {

}

建立UserinfoService介面,以及其實現類,這裡僅以增加記錄和查詢記錄為例:


package wang.datahub.example.service;

import wang.datahub.example.entity.Userinfo;

import java.util.List;

public interface UserinfoService {

    List<Userinfo> getAll();

    Userinfo saveOne(Userinfo userinfo);

}

UserinfoServiceImpl實現

 

package wang.datahub.example.service.impl;

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

import org.springframework.stereotype.Service;

import wang.datahub.example.entity.Userinfo;

import wang.datahub.example.repository.UserinfoRepository;

import wang.datahub.example.service.UserinfoService;

import java.util.List;

@Service

public class UserinfoServiceImpl implements UserinfoService {

    @Autowired

    private UserinfoRepository userinfoRepository;

    @Override

    public List<Userinfo> getAll(){

        return userinfoRepository.findAll();

    }

    @Override

    public Userinfo saveOne(Userinfo userinfo){

        System.out.println(userinfo);

        return userinfoRepository.saveAndFlush(userinfo);

    }

}

建立Rest介面 UserinfoController


package wang.datahub.example.controller;

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

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestBody;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import org.springframework.web.bind.annotation.RestController;

import wang.datahub.example.entity.Userinfo;

import wang.datahub.example.service.UserinfoService;

import java.util.List;

@RestController

public class UserinfoController {

    @Autowired

    private UserinfoService userinfoService;

    @RequestMapping(value = "/userinfo", method = RequestMethod.GET)

    public List<Userinfo> getAll(){

        return userinfoService.getAll();

    }

    @RequestMapping(value="/userinfo",produces = "application/json;charset=UTF-8", method = RequestMethod.POST)

    public Userinfo save(@RequestBody  Userinfo userinfo){

        return userinfoService.saveOne(userinfo);

    }

}

建立啟動類 App


package wang.datahub.example;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;

import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration;

import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter;

import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;

import org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter;

import org.springframework.transaction.jta.JtaTransactionManager;

import javax.persistence.spi.PersistenceProvider;

import javax.sql.DataSource;

import java.util.HashMap;

import java.util.Map;

@EnableAutoConfiguration

@ComponentScan

public class App {

    public static void main(String[] args) {

        SpringApplication.run(App.class,args);

    }

    @Configuration

    public static class GBasedbtJpaConfig extends JpaBaseConfiguration{

        @Override

        protected AbstractJpaVendorAdapter createJpaVendorAdapter() {

            OpenJpaVendorAdapter jpaVendorAdapter = new OpenJpaVendorAdapter();

            jpaVendorAdapter.setShowSql(true);

//        jpaVendorAdapter.setDatabase(Database.INFORMIX);

            return jpaVendorAdapter;

        }

        @Override

        protected Map<String, Object> getVendorProperties() {

            HashMap<String, Object> map = new HashMap<String, Object>();

//        map.put("openjpa.ConnectionDriverName","com.gbasedbt.jdbc.Driver");

//        map.put("openjpa.ConnectionURL","jdbc:gbasedbt-sqli://172.24.110.229:9088/t1:GBASEDBTSERVER=ol_gbasedbt1210_1;NEWCODESET=UTF8,zh_cn.UTF8,57372;DATABASE=t1;DB_LOCALE=en_US.819;");

//        map.put("openjpa.ConnectionUserName","gbasedbt");

//        map.put("openjpa.ConnectionPassword","dafei1288");

            return map;

        }

    }

}

測試新增資料

POST

Accept: application/json

Content-Type: application/json

{"username":  "jacky", "age":  111}

返回結果


POST

HTTP/1.1 200 OK

Server: Apache-Coyote/1.1

Content-Type: application/json;charset=UTF-8

Transfer-Encoding: chunked

Date: Fri, 05 Nov 2021 03:13:34 GMT

{

  "id": 3252,

  "username": "jacky",

  "age": 111

}

Response code: 200 (OK); Time: 244ms; Content length: 40 bytes

測試新增資料:


GET

Accept: application/json

返回結果:

GET

HTTP/1.1 200 OK

Server: Apache-Coyote/1.1

Content-Type: application/json;charset=UTF-8

Transfer-Encoding: chunked

Date: Fri, 05 Nov 2021 03:12:07 GMT

[

  {

    "id": 3201,

    "username": "mm",

    "age": 11

  },

  {

    "id": 3202,

    "username": "dd",

    "age": 22

  },

  {

    "id": 3251,

    "username": "dd",

    "age": 22

  }

]

Response code: 200 (OK); Time: 33ms; Content length: 112 bytes



原文連結:https://blog.csdn.net/dafei1288/article/details/121424053


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69993860/viewspace-2844000/,如需轉載,請註明出處,否則將追究法律責任。

相關文章