前言

在 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 則結合兩者優點. 選擇適合的工具可以讓開發更有效率.

參考資料