在使用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ù)組了。