SpringData JPA 使用自定義查詢(不確定表名稱情況)

在使用SpringData JPA組件時,我們一般都是定義實體,定義倉庫接口,然后就可以增刪改查了。

但是在實際業(yè)務(wù)中,很多數(shù)據(jù)表的名稱并不是固定的,比如我們的軌跡表,就是每天一張,類似:track_20210601。

這時如果在實體的@Table注解中再寫明數(shù)據(jù)表名稱就不現(xiàn)實,需要一個途徑去處理此類問題,因為我們的業(yè)務(wù)涉及這種情況的表就兩個,所以這里記錄一種實現(xiàn)這個業(yè)務(wù)的簡單方法。
具體如以下代碼所示:

package com.jns.jpanamingstrategy;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.transaction.Transactional;
import java.util.List;

@SpringBootTest
class JpaNamingStrategyApplicationTests {

    @PersistenceContext
    private EntityManager entityManager;

    // SQL模板
    String insertRecordTmp = "insert into %s(`id`,`name`)values(%d, '%s')";
    String selectRecordTmp = "select `id`,`name` from %s";
    String updateRecordTmp = "update %s set `name`='%s' where `id`=%d";
    String deleteRecordTmp = "delete from %s where `id`=%d";
    String findTableTmp = "select count(TABLE_NAME) from information_schema.`TABLES` where TABLE_SCHEMA='%s' AND TABLE_NAME='%s'";

    @Test
    // 啟用事務(wù)  這個注解必須加
    @Transactional
    void contextLoads() {
        // 數(shù)據(jù)表名稱
        String tableName = "student_01";

        // 判斷數(shù)據(jù)表是否存在
        if (!findSameNameTable("test", tableName)) {
            create(tableName);

            insert(tableName, 1, "kaven");
            insert(tableName, 2, "john");
            insert(tableName, 3, "lily");
        } else {
            System.out.println(tableName + " 已經(jīng)存在!");
        }

        System.out.println("驗證插入");
        select(tableName);

        update(tableName, 1, "han mei mei");

        System.out.println("驗證更新");
        select(tableName);

        delete(tableName, 3);

        System.out.println("驗證刪除");
        select(tableName);
    }

    public void create(String tableName) {
        String createTable = "create table " + tableName + "(`id` int primary key , `name` varchar(50))";
        Query query = entityManager.createNativeQuery(createTable);
        query.executeUpdate();
    }

    public void insert(String tableName, int id, String name) {
        String sql = String.format(insertRecordTmp, tableName, id, name);
        Query query = entityManager.createNativeQuery(sql);
        query.executeUpdate();
    }

    public void select(String tableName) {
        String sql = String.format(selectRecordTmp, tableName);
        Query query = entityManager.createNativeQuery(sql);
        // Object[] 為每一條數(shù)據(jù)每列的值,順序為數(shù)據(jù)表列順序,索引0開始
        List<Object[]> l = query.getResultList();
        for (Object[] o : l) {
            System.out.println(o[0] + "  " + o[1]);
        }
    }

    public void update(String tableName, int id, String name) {
        String sql = String.format(updateRecordTmp, tableName, name, id);
        Query query = entityManager.createNativeQuery(sql);
        query.executeUpdate();
    }

    public void delete(String tableName, int id) {
        String sql = String.format(deleteRecordTmp, tableName, id);
        Query query = entityManager.createNativeQuery(sql);
        query.executeUpdate();
    }


    public boolean findSameNameTable(String TABLE_SCHEMA, String TABLE_NAME) {
        boolean same = false;
        String sql = String.format(findTableTmp, TABLE_SCHEMA, TABLE_NAME);
        Query query = entityManager.createNativeQuery(sql);
        List<Object> l = query.getResultList();
        if (Integer.parseInt(String.valueOf(l.get(0))) > 0) {
            same = true;
        }

        return same;
    }

}

有一個地方需要注意,就是查詢的時候,關(guān)于字段的返回,具體說明如下:


1625807923(1).png

就是當(dāng)查詢語句只有一個字段時,就直接返回該字段的值了,不會再是Object[]數(shù)組了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容