graphql api graphiql graphql multiple queries in one request

GraphQL EP 6:向資料庫新增(Insert)、修改(Update)、刪除(Delete)資料

使用GraphQL向資料庫新新增(Insert)、修改(Update)、刪除(Delete)資料

開始此篇以前,可以先參考之前的文章【Spring Boot EP 16:再論存取資料庫 – Insert、Update、Delete】,就不再另外論述Spring Boot存取資料庫了。

實作

第1步:延續前一篇【GraphQL EP 5:從資料庫讀取資料並輸出】。

第2步:services的”MarketService.java”中定義資料操作的函數。

package com.example.graphqldemo.services;

import com.example.graphqldemo.entities.MarketEntity;
import java.util.List;

public interface MarketService {

    List<MarketEntity> getAll();

    MarketEntity getByMarketCode(String MarketCode);

    // 新增insertMarket函數
    MarketEntity insertMarket(String MarketCode, String MarketName);

    // 新增updateMarket函數
    Integer updateMarket(String MarketCode, String MarketName);

    // 新增deleteMarket函數
    Boolean deleteMarket(String MarketCode);
}

第3步:repositories的”MarketRepository.java”中撰寫update的SQL語法。

package com.example.graphqldemo.repositories;

import com.example.graphqldemo.entities.MarketEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;

@Repository
public interface MarketRepository extends JpaRepository<MarketEntity, String> {
    @Query(value = "SELECT MARKET_CODE, MARKET_NAME FROM STOCK_MARKET.MARKETS;", nativeQuery = true)
    List<MarketEntity> getAll();

    @Query(value = "SELECT MARKET_CODE, MARKET_NAME FROM STOCK_MARKET.MARKETS WHERE MARKET_CODE=:MARKET_CODE", nativeQuery = true)
    MarketEntity getByMarketCode(@Param("MARKET_CODE") String MarketCode);

    // Update資料
    @Transactional
    @Modifying
    @Query(value = "UPDATE STOCK_MARKET.MARKETS SET MARKET_NAME=:MARKET_NAME WHERE MARKET_CODE=:MARKET_CODE", nativeQuery = true)
    Integer updateMarket(@Param("MARKET_CODE") String MarketCode, @Param("MARKET_NAME") String MarketName);
}

第4步:services的”MarketServiceImpl.java”中實作在”MarketService.java”與”MarketRepository.java”所定義的函數;資料庫的操作同使用Spring Boot Data與純SQL的方法,以此顯示不管什麼方法都不影響GraphQL的功能。

package com.example.graphqldemo.services;

import com.example.graphqldemo.entities.MarketEntity;
import com.example.graphqldemo.repositories.MarketRepository;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;

@Service
@AllArgsConstructor
public class MarketServiceImpl implements MarketService{
    private final MarketRepository marketRepository;

    @Override
    public List<MarketEntity> getAll() {
        return marketRepository.findAll();
    }

    @Override
    public MarketEntity getByMarketCode(String MarketCode) {
        Optional<MarketEntity> marketEntity = marketRepository.findById(MarketCode);
        return marketEntity.orElse(null);
    }

    // 實作insertMarket
    @Override
    public MarketEntity insertMarket(String MarketCode, String MarketName){
        MarketEntity marketEntity = new MarketEntity();
        marketEntity.setMarketCode(MarketCode);
        marketEntity.setMarketName(MarketName);

        // 使用Spring Boot Data的方式寫入資料
        return marketRepository.save(marketEntity);
    }

    // 實作updateMarket
    @Override
    public Integer updateMarket(String MarketCode, String MarketName){
        // 呼叫MarketRepository所撰寫的SQL操作資料庫
        return marketRepository.updateMarket(MarketCode, MarketName);
    }

    // 實作deleteMarket
    @Override
    public Boolean deleteMarket(String MarketCode){
        try {
            // 使用Spring Boot Data的方式刪除資料
            marketRepository.deleteById(MarketCode);
            return true;
        }catch (Exception ex){
            return  false;
        }
    }
}

第5步:在queries中新建”MarketMutation.java”實作GraphQLMutationResolver,以定義GraphQL的查詢方法,而GraphQLMutationResolver特別用於資料新增、更新、刪除,這是與前一篇所使用的GraphQLQueryResolver不同之處。

package com.example.graphqldemo.queries;

import com.example.graphqldemo.entities.MarketEntity;
import com.example.graphqldemo.services.MarketService;
import graphql.kickstart.tools.GraphQLMutationResolver;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

// 實作GraphQLMutationResolver
@Component
@RequiredArgsConstructor
public class MarketMutation implements GraphQLMutationResolver {

    // 宣告MarketService
    private final MarketService marketService;

    // 實作insertMarket,以MarketService內的insertMarket函數來達成
    public MarketEntity insertMarket(String MarketCode, String MarketName){ return marketService.insertMarket(MarketCode, MarketName); }

    // updateMarket,以MarketService內的updateMarket函數來達成
    public Integer updateMarket(String MarketCode, String MarketName){ return marketService.updateMarket(MarketCode, MarketName); }

    // deleteMarket,以MarketService內的deleteMarket函數來達成
    public Boolean deleteMarket(String MarketCode){  return marketService.deleteMarket(MarketCode); }
}

第6步:最後,到resources中的”market.graphqls”來撰寫GraphQL的查詢語法,新增insert、update、delete之用。

# 定義Market的資料模型,對應資料庫的欄位
type Market {
    MarketCode: String!
    MarketName: String
}

# 對應GraphQLQueryResolver的函數設計查詢語法
extend type Query {
    Markets: [Market]!
    Market(MarketCode: String!): Market
}

# 對應GraphQLMutationResolver的函數設計查詢語法
type Mutation {
    insertMarket(MarketCode: String!, MarketName: String!): Market
    updateMarket(MarketCode: String!, MarketName: String!): Int
    deleteMarket(MarketCode: String!): Boolean!
}

通常只有一個Root操作,其餘皆以extend作為開頭,標記為延伸查詢。

第7步:可以在GraphiQL的畫面看到剛才新增的insert、update、delete方法,如下圖:

graphql

第8步:撰寫insert、update、delete的GraphQL語法來執行資料的操作,如下圖,左邊是操作資料的語法,右邊是結果。

graphql

第9步:也可以使用Postman來操作,如下圖,此時HTTP方法記得選擇Post,Mutation不支援Get方法!

graphql postman

相關資訊

更多Mutation語法如官方教學:連結

~ END ~


, , , ,

Related posts

Latest posts