iT邦幫忙

2021 iThome 鐵人賽

DAY 28
0
Software Development

一個新鮮人如何完轉Spring boot與DevOps從0到101系列 第 28

Spring boot 宣告 MongoDB Document

非常的簡易透過 Spring boot 提供的註解我們可以輕鬆地宣告和使用

@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(collection = "connectivity")
public class Connectivity {
    private String name;

    private Integer number;
    
    private String status;
    
    private Integer signalStrength;
    
    @Field("IPlist") 
    private List<Map<String, Object>> ipList;
    
    private Integer contentRevision;
    
    private String deviceId;
    
    private Long contentTimestamp;
}

Document 則是宣告 collection。
Field annotation 可以幫助與 mongoDB 中定義的 field 進行映射。

@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "gnss")
public class Gnss {
    @Id
    private String id;

    private Integer contentRevision;
    
    private String sensorName;

    private Map<String, Object> coords; // Json format
    
    private Double coordsAccuracy;

    private String service;

    private Double speed;
    
    private Double heading;
    
    private Long timestamp;

    private String deviceId;

    private Long contentTimestamp;
}

那接下來我們要怎樣對 MongoDB 進行一些操作呢 ? 在 Spring boot 中也提供 API 給我們使用如下,透過繼層 MongoRepository 我們就可以有基本的 CRUD 操作。

@Repository
public interface GnssRepository extends MongoRepository<Gnss, String> {
    @Query("{'deviceId' : ?0 }")
    List<GnssMappingVO> getByDeviceId(@Param("id") String id);
}

以下透過 MongoRepository 進行操作

     @Override
    public List<Gnss> getAllGnss() {
        // basic query
        return gnssRepository.findAll();
    }

    @Override
    public Gnss getById(String id) {
        // basic query
        log.debug("Find Gnss by id:{}", id);
        return gnssRepository.findById(id).orElse(null);
    }

當然也可以使用 mongoTemplate 進行存取操作。

@Override
    public List<GnssMappingVO> getListDeviceIdCustom(String id) {
        // Use Query method
        Query query = new Query();
        query.fields().include("id").include("sensorName").include("coords").include("deviceId"); // like SQL SELECT
        query.addCriteria(Criteria.where("deviceId").is(id)); // WHERE condition
        query.with(Sort.by(Sort.Direction.ASC, "sensorName", "deviceId")); // like SQL ORDER BY
        
        List<Gnss> gnssList = mongoTemplate.find(query, Gnss.class);
        List<GnssMappingVO> res = new ArrayList<>();
        /**
         * 回傳資料而外處理
         */
        for (int i=0; i<gnssList.size(); i++){
            GnssMappingVO gnssMappingVO = new GnssMappingVO().builder()
                .id(gnssList.get(i).getId())
                .sensorName(gnssList.get(i).getSensorName())
                .coords(gnssList.get(i).getCoords())
                .deviceId(gnssList.get(i).getDeviceId())
                .build();

                res.add(gnssMappingVO);
        }

        return res;
    }

下面同樣是用另一種方式進行存取使用 Aggregates

    @Override
    public List<Gnss> getListByTimestampRangeBson(GnssListRequestVO queryVO) {
        String deviceId_column = "deviceId";
        String timestamp_column = "timestamp";
        String gps_column = "coords";
        /**
         * User Bson query
         */
        Bson bson = Filters.and(Arrays.asList(
                Filters.eq(deviceId_column, queryVO.getQuery().getDeviceId()),
                Filters.gte(timestamp_column, queryVO.getQuery().getStart().getTime()),
                Filters.lte(timestamp_column, queryVO.getQuery().getEnd().getTime()))); // Like Where condition
        Bson match = Aggregates.match(bson);
        Bson sort = Aggregates.sort(Sorts.ascending(timestamp_column)); // sort
        Bson fields = Aggregates.project(Projections.include(deviceId_column, timestamp_column, gps_column)); // Like SELECT

        AggregateIterable<Document> findIterable = mongoTemplate.getCollection(collection).aggregate(Arrays.asList(match, fields, sort));

        Gson gson = new Gson(); // 轉 JSON
        JsonWriterSettings settings = JsonWriterSettings.builder()
                .dateTimeConverter(new JsonDateTimeCoverter())
                .int64Converter((value, writer) -> writer.writeNumber(value.toString()))
                .build();
        
        List<Gnss> res = StreamSupport.stream(findIterable.spliterator(), false)
                .map(i -> gson.fromJson(i.toJson(settings), Gnss.class))
                .collect(Collectors.toList());

        return res;
    }

MongoDB 在 Spring boot 中提供了很多好用的 API,當然這些東西都是還要讀文件才有的,自幹才是王道


上一篇
Spring boot 與 MongoDB 之連線
下一篇
Spring boot 與 skaffold
系列文
一個新鮮人如何完轉Spring boot與DevOps從0到10130

尚未有邦友留言

立即登入留言