前言

在 Java 開發中,與資料庫互動是必備技能。這篇文章介紹三種常用的查詢方式:JdbcTemplate、JPA 與 JPQL,幫助你選擇適合的工具來操作資料庫。

JdbcTemplate

Repository 負責與資料庫溝通,運用 SQL 語言來操作 CRUD。

@Repository
public class DemoDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public void addStaff (ExampleEntity exampleEntity) {

        String sql = "INSERT INTO members(id, name) VALUES (?,?);";

        jdbcTemplate.update(sql, exampleEntity.getId(), exampleEntity.getName());
    }
}

常用方法

  • execute:操作資料表相關的 SQL (create, drop…)
  • update / batchUpdate:資料的新增、修改、刪除
  • query / queryForXXX:查詢資料
  • call:Stored Procedure

JPA

Repository extends JpaRepository。

public interface DemoRepository extends JpaRepository<DemoEntity, String> {

    DemoEntity findByGuid(String guid);

    List<DemoEntity> findByGuid(String guid);
}

可以直接使用 JPA 的語法進行查詢,findByGuid = SELECT * FROM Demo WHERE Guid = 'guid';,也可以回傳該物件的 List。但若需要更精細的查詢,可以使用 JPQL

多個主鍵

在 JPA 如果要處理有多個 PK 的話,可以寫一個包含所有主鍵的類。

@Data // lombok 用法等於 @Getter @Setter, 但還有其他東西
public class PrimaryKey implements Serializable {

    private Integer id;

    private Integer userId;
}

Entity 下加入。

@Data
@Entity
@Table (name = "Demo")
@IdClass(Primarykey.class)
@Equa lsAndHashCode (callSuper = true)
@DynamicUpdate
public class DemoEntity {

    @Id
    @Column(name = "id", nullable = false)
    private Integer id;

    @Id
    @Column(name = "user_id", nullable = false)
    private Integer userId;
}

特殊 ID

uniqueidentifier (Transact-SQL) 類型。

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "FileCollection", schema = "dbo")
public class FileCollectionEntity {

    @Id
    @GenericGenerator(name = "generator", strategy = "uuid2")
    @GeneratedValue(generator = "generator")
    @Column(name = "FileGuid", columnDefinition="uniqueidentifier")
    private String fileGuid;
}

這樣就會自動產生特殊的 UUID 了。

JPQL

一樣 extends JpaRepository。

public interface DemoRepository extends JpaRepository<DemoEntity, String> {

    @Query("SELECT COUNT(e) FROM DemoEntity e")
    long countAll();
}

意思是 SELECT COUNT(*) FROM Demo;,然而 JPQL 並不支援 LIMIT 語法,可以用 Pageable 進行限制。

Repository 傳入 Pageable 物件。

public interface DemoRepository extends JpaRepository<DemoEntity, String> {

    @Query("SELECT d.urpn, COUNT(d.urpn) AS t FROM DemoEntity d GROUP BY d.urpn ORDER BY t DESC")
    List<String> countUsRef(Pageable pageable);
}

接著在呼叫的方法加入 PageRequest.of(page, size)

DemoRepository.countUsRef(PageRequest.of(0,10));

意思是第 0 頁,每 10 筆一頁。

總結

Java 提供了多種資料庫查詢方式,JdbcTemplate 提供原生 SQL 操作,JPA 提供物件導向的查詢方式,JPQL 則結合兩者優點。選擇適合的工具可以讓開發更有效率。

參考資料