欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

在Java中使用ModelMapper簡化Shapefile屬性轉(zhuǎn)JavaBean實戰(zhàn)過程

 更新時間:2025年02月11日 11:16:00   作者:夜郎king  
本文介紹了在Java中使用ModelMapper庫簡化Shapefile屬性轉(zhuǎn)JavaBean的過程,對比了原始的set方法和構(gòu)造方法,展示了如何使用ModelMapper進行動態(tài)屬性映射,從而減少手動編寫轉(zhuǎn)換代碼的工作量,通過示例代碼,展示了如何使用GeoTools讀取Shapefile屬性并將其轉(zhuǎn)換為JavaBean對象

前言

        在現(xiàn)代軟件開發(fā)中,尤其是在多層架構(gòu)中,經(jīng)常需要將數(shù)據(jù)從一個域?qū)ο筠D(zhuǎn)換到另一個域?qū)ο螅蛘邚臄?shù)據(jù)庫結(jié)果集轉(zhuǎn)換到業(yè)務(wù)對象。手動編寫這些轉(zhuǎn)換代碼不僅耗時,而且容易出錯。我們需要一種自動化的方式來處理這些轉(zhuǎn)換,減少了開發(fā)工作量和潛在的錯誤。JavaBean是一種遵循特定編寫規(guī)范的Java類,通常具有g(shù)et和set方法來訪問私有屬性,以及一個無參構(gòu)造函數(shù)。JavaBean是我們平時的開發(fā)過程當中遇到最多的類,不管它是DO、DTO、VO或者POJO等等,這些類都是以JavaBean的形式存在的。

        在之前的系列博客中,尤其是涉及空間數(shù)據(jù)管理和查詢的后臺設(shè)計中。大家如果認真注意的話,我們分別在空間數(shù)據(jù)庫中創(chuàng)建一張與屬性字段對應(yīng)的空間表。而在采用MVC的開發(fā)模式中,模型層通常會對應(yīng)一個與空間表對應(yīng)的空間表。與成熟的ORM映射不同的是,ORM框架自動的會將數(shù)據(jù)庫中的字段快速得與JavaBean的屬性進行對應(yīng),在執(zhí)行查詢語句的時候可以直接關(guān)聯(lián)。但是在處理空間數(shù)據(jù)時,比如使用GDAL或者GeoTools來進行數(shù)據(jù)讀取時,目前暫時沒有找到成熟的框架或者組件支持空間屬性表與JavaBean的快速映射需求。

        本文以Java語言為例,主要講解如何使用Java語言進行空間數(shù)據(jù)的讀取,空間屬性信息的讀取使用GeoTools,文章首先介紹最原始的做法,即在對象中自定義轉(zhuǎn)換方法來實現(xiàn)轉(zhuǎn)換,然后詳細介紹一種基于ModelMapper的空間屬性映射實現(xiàn)方法。ModelMapper在Java的其它領(lǐng)域應(yīng)用很多,但是在GIS領(lǐng)域中使用的還不多。如果您是一名GISER,同時也面臨著屬性信息映射的問題,不妨來這里交流討論。

一、原始的處理辦法

        在介紹本文的處理辦法之前,首先依然來看一下最原始的處理辦法是什么。由此,可以對比不同的處理辦法的不同點,也可以發(fā)現(xiàn)其有點。關(guān)于如何讀取空間屬性信息,不管是使用GDAL或者GeoTools,不管是Gdb數(shù)據(jù)或者Shapefile數(shù)據(jù),之前的系列博客都進行了簡單的說明。因此想了解具體的讀取過程的,可以翻閱之前的博客。因此這里只將轉(zhuǎn)換的過程進行說明。

1、使用Set方法來轉(zhuǎn)換

        首先來介紹調(diào)用對象實例的Set方法來進行轉(zhuǎn)換。這種情況使用與空間屬性表的字段不是很多,我們在轉(zhuǎn)換時可以先從空間屬性表中分別讀取出具體的字段,然后再調(diào)用對應(yīng)的JavaBea的Set方法來進行字段的映射和轉(zhuǎn)換。比如在進行省份的空間屬性信息轉(zhuǎn)換的代碼如下所示:

List<Province> list = new ArrayList<Province>();
for (int i = 0; i < featureCount; i++) {
	Feature feature = layer.GetFeature(i);
	String code = feature.GetFieldAsString("province_c");
	String name = feature.GetFieldAsString("province_n");
	String type = feature.GetFieldAsString("type");
	Geometry geom = feature.GetGeometryRef();
	String wkt = geom.ExportToWkt();
	Province p = new Province();
	p.setCode(code);
	p.setName(name);
	p.setType(type);
	p.setGeom(wkt);
}

        上面是一個使用GDAL解析空間數(shù)據(jù)時的屬性映射的實例代碼。 這種方式相信大家很熟悉,通過創(chuàng)建Province對象后,再分別從feature中讀取省份信息,最后設(shè)置到實例對象中,最后再保存到數(shù)據(jù)庫中。

2、使用構(gòu)造方法轉(zhuǎn)換

        除了使用set方法來進行設(shè)置,我們也可以使用構(gòu)造方法來進行屬性賦值。與set方法相比,構(gòu)造方法可以統(tǒng)一設(shè)置,不需逐行進行設(shè)置。這樣代碼顯得比較優(yōu)雅,可讀性也高。構(gòu)造方法是將屬性賦值的過程抽象都對象的構(gòu)造方法中,這樣實現(xiàn)代碼的整體復用。這里以城市對象構(gòu)造方法為例:

public City(String provinceCode, String provinceName, String cityCode, String cityName, String type, String geom) {
	super();
	this.provinceCode = provinceCode;
	this.provinceName = provinceName;
	this.cityCode = cityCode;
	this.cityName = cityName;
	this.type = type;
	this.geom = geom;
}

        然后在解析的過程中就可以直接調(diào)用構(gòu)造方法的模式簡化設(shè)置的過程,代碼如下:

List<City> list = new ArrayList<City>();
for (int i = 0; i < featureCount; i++) {
	Feature feature = layer.GetFeature(i);
	String code = feature.GetFieldAsString("province_c");
	String name = feature.GetFieldAsString("province_n");
	String cityCode = feature.GetFieldAsString("city_code");
	String cityName = feature.GetFieldAsString("city_name");
	String type = feature.GetFieldAsString("type");
	Geometry geom = feature.GetGeometryRef();
    String wkt = geom.ExportToWkt();
	list.add(new City(code,name,cityCode,cityName,type,wkt));
}
cityService.saveBatch(list,100);

        可以從代碼中看到,通過構(gòu)造方法的方式來進行賦值,能極大的減少set方法的調(diào)用,能減少許多的代碼調(diào)用??梢钥吹剑还苁褂媚姆N方式,我們都需要有一個從feature中根據(jù)屬性名解析字段,不得不說,這種方式于我們最開始學JDBC的模式非常相似,那么有什么辦法實現(xiàn)動態(tài)映射,不需要單獨讀取呢?下面我們就來分享一種方法來進行轉(zhuǎn)換。

二、基于ModelMapper的動態(tài)轉(zhuǎn)換

        既然有了如上的需求場景,那么有什么方法可以實現(xiàn)快速的屬性映射嗎?在Java當中,很多人首選肯定是采用反射,對吧。確實如此,使用反射可以解決我們的問題,實現(xiàn)上述的需求。對于反射,相信很多的朋友可以自行進行編碼。本著不重復造輪子的思路,我們可以從現(xiàn)有的一些成熟工具中來選擇符合我們期望的組件。這里推薦一款轉(zhuǎn)換組件,ModelMapper。

1、ModelMapper簡介

        ModelMapper是一個Java對象映射庫,它能夠?qū)⒁粋€對象的數(shù)據(jù)映射到另一個對象中,從而避免手動編寫數(shù)據(jù)轉(zhuǎn)換代碼。ModelMapper通過使用簡單的配置和API,能夠自動地將源對象的屬性復制到目標對象的屬性中,這在處理不同數(shù)據(jù)層之間的數(shù)據(jù)轉(zhuǎn)換時非常有用。ModelMapper簡化了開發(fā)流程,因為它減少了手動編寫數(shù)據(jù)轉(zhuǎn)換代碼的需要。這不僅提高了開發(fā)效率,還使得代碼更加簡潔和易于維護。通過使用ModelMapper,開發(fā)者可以將更多的精力投入到業(yè)務(wù)邏輯的實現(xiàn)上,而不是數(shù)據(jù)轉(zhuǎn)換的細節(jié)上。ModelMapper提供了高度的靈活性和可配置性。開發(fā)者可以根據(jù)需要自定義映射規(guī)則,例如跳過某些屬性的映射,或者在映射過程中進行條件判斷和自定義轉(zhuǎn)換。這種靈活性使得ModelMapper能夠適應(yīng)各種復雜的數(shù)據(jù)轉(zhuǎn)換場景。

        首先,我們來看一下ModelMapper的官網(wǎng)介紹,modelmapper官網(wǎng)。大家可以先到官網(wǎng)看一下它的相關(guān)介紹可幫助文檔。

2、集成到項目中

        對ModelMapper有了基本的了解之后,我們來看一下如何將ModelMapper集成到Java項目當中。首先我們需要使用Maven來進行資源的引入,在Pom.xml中引入依賴,關(guān)鍵代碼如下所示:

<!--  增加模型映射 add by 夜郎king in 2024.11.11 begin -->
<!-- https://mvnrepository.com/artifact/org.modelmapper/modelmapper -->
<dependency>
	<groupId>org.modelmapper</groupId>
	<artifactId>modelmapper</artifactId>
	<version>3.1.1</version>
</dependency>
<!--  modelmapper add by 夜郎king in 2024.11.11 end -->

        然后在Java中進行相應(yīng)的集成,雖然ModelMapper本身主要作用是用于JavaBean之間的轉(zhuǎn)換,但是也可以在Map和JavaBean之間進行屬性映射。

@Test
public void convertMap2BeanWithUnderscoreNamingConvention() {
	HashMap<String, Object> map = new HashMap<String, Object>();
	map.put("scalerank", 6);
	map.put("LS_NAME", "test241111");
	map.put("MAX_POP10", "23562");
	ModelMapper modelMapper = new ModelMapper();
	Ne10mPopulatedPlaces pp = modelMapper.map(map, Ne10mPopulatedPlaces.class);
	System.out.println(pp);
	System.out.println(pp.getLsName());
	System.out.println(pp.getMaxPop10());
	assertEquals("test241111", pp.getLsName());
	assertEquals(23562L, pp.getMaxPop10());
}

        代碼很簡單,首先定義一個HashMap,map的key是屬性的名字,value是實際的值。然后我們創(chuàng)建ModelMapper,使用默認的轉(zhuǎn)換策略和匹配模式,在這種策略下實現(xiàn)Map向Ne10mPopulatedPlaces對象的轉(zhuǎn)換。Ne10mPopulatedPlaces對象就是之前提到過的人口城市空間屬性數(shù)據(jù)。

        這個類的屬性比較對,大概有137個屬性。針對這么多的屬性映射,不管是采用set方法還是構(gòu)造方法,實現(xiàn)代碼都會非常冗長。運行上面的測試方法后,可以看到如下結(jié)果:

3、Shapefile屬性讀取 

        有了以上的基礎(chǔ),結(jié)合之前的GeoTools的屬性讀取方法,我們來解析屬性表格。解析的思路很簡單,循環(huán)屬性表格,將屬性表列和值組成一個HashMap,表頭為key,值為value的hashMap,然后將這個HashMap轉(zhuǎn)換成對應(yīng)的JavaBean對象。

@Test
public void convertDbf2BeanByDefault() throws Exception {
	File dbfFile = new File(SHP_FILE);
	ShpFiles shpFile = new ShpFiles(dbfFile);
	DbaseFileReader dbfReader = new DbaseFileReader(shpFile, true, Charset.defaultCharset());
	// 讀取 DBF 文件的頭信息
	DbaseFileHeader header = dbfReader.getHeader();
	List<Ne10mPopulatedPlaces> dataList = new ArrayList<Ne10mPopulatedPlaces>(header.getNumRecords());
	List<HashMap<String, Object>> mapList = new ArrayList<HashMap<String,Object>>();
	ModelMapper modelMapper = new ModelMapper();
	while (dbfReader.hasNext()) {
		Row row = dbfReader.readRow();
		HashMap<String, Object> map = new HashMap<String, Object>();
		for (int i = 0; i < header.getNumFields(); i++) {
			map.put(header.getFieldName(i), row.read(i));
		}
		mapList.add(map);
	}
	int index = 0;
	for(HashMap<String, Object> map : mapList) {
		if(index > 10) {
			break;
		}
		Ne10mPopulatedPlaces places = modelMapper.map(map, Ne10mPopulatedPlaces.class);
		System.out.println(places);
		dataList.add(places);
		index ++;
	}
	System.out.println(dataList.size());
	System.out.println("屬性字段數(shù):" + header.getNumFields());
	System.out.println("數(shù)據(jù)記錄數(shù):" + header.getNumRecords());
	dbfReader.close();
}

        也是默認的映射策略和模式,通過上述的代碼可以看到以下輸出:

        可以看到, 通過以上的代碼已經(jīng)成功的實現(xiàn)把HashMap轉(zhuǎn)換成JavaBean,同時可以看到JavaBean的屬性值都成功的進行了賦值。到此,大功告成。

三、總結(jié)

        以上就是本文的主要內(nèi)容,本文以Java語言為例,主要講解如何使用Java語言進行空間數(shù)據(jù)的讀取,空間屬性信息的讀取使用GeoTools,文章首先介紹最原始的做法,即在對象中自定義轉(zhuǎn)換方法來實現(xiàn)轉(zhuǎn)換,然后詳細介紹一種基于ModelMapper的空間屬性映射實現(xiàn)方法。ModelMapper在Java的其它領(lǐng)域應(yīng)用很多,但是在GIS領(lǐng)域中使用的還不多。本文基于ModelMapper解決了在Shapefile文件讀取過程中,如何實現(xiàn)動態(tài)的將屬性表格映射到指定對象的方法進行了詳細介紹。如果您是一名GISER,同時也面臨著屬性信息映射的問題,不妨來這里交流討論。行文倉促,難免有許多不足之處,如有不足,還請各位專家朋友在評論區(qū)留言批評指正,不甚感激。

到此這篇關(guān)于在Java中使用ModelMapper簡化Shapefile屬性轉(zhuǎn)JavaBean實戰(zhàn)的文章就介紹到這了,更多相關(guān)Java轉(zhuǎn)JavaBean內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring data elasticsearch使用方法詳解

    Spring data elasticsearch使用方法詳解

    這篇文章主要介紹了Spring data elasticsearch使用方法詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-01-01
  • Spring MVC結(jié)合Spring Data JPA實現(xiàn)按條件查詢和分頁

    Spring MVC結(jié)合Spring Data JPA實現(xiàn)按條件查詢和分頁

    這篇文章主要為大家詳細介紹了Spring MVC結(jié)合Spring Data JPA實現(xiàn)按條件查詢,以及分頁效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • Assert.assertEquals的使用方法及注意事項說明

    Assert.assertEquals的使用方法及注意事項說明

    這篇文章主要介紹了Assert.assertEquals的使用方法及注意事項說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • Java如何處理json字符串value多余雙引號

    Java如何處理json字符串value多余雙引號

    這篇文章主要介紹了Java如何處理json字符串value多余雙引號,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-03-03
  • 詳解springboot中junit回滾

    詳解springboot中junit回滾

    本篇文章主要介紹了springboot中junit回滾,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • Java 泛型詳解與范例

    Java 泛型詳解與范例

    hello !大家好!今天的主題就是:泛型。在使用集合類時,大家就已經(jīng)接觸到泛型了,那就是每個集合類后面的尖括號<>,這樣一對尖括號,在java中就稱為泛型。那么泛型這一個點,我們又該知道多少呢?我們往下看
    2021-11-11
  • 如何使用spring?boot的程序主線程中異步訪問外部接口

    如何使用spring?boot的程序主線程中異步訪問外部接口

    CompletableFuture.supplyAsync提供了一種強大的工具,使您能夠以異步方式執(zhí)行操作,充分利用多核處理器和提高程序性能,同時保持代碼的清晰性和可維護性,本文給大家介紹使用spring?boot的程序主線程中異步訪問外部接口,感興趣的朋友一起看看吧
    2023-10-10
  • java之CSV大批量數(shù)據(jù)入庫的實現(xiàn)

    java之CSV大批量數(shù)據(jù)入庫的實現(xiàn)

    本文主要介紹了java之CSV大批量數(shù)據(jù)入庫的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-02-02
  • Java及數(shù)據(jù)庫對日期進行格式化方式

    Java及數(shù)據(jù)庫對日期進行格式化方式

    這篇文章主要介紹了Java及數(shù)據(jù)庫對日期進行格式化方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java Collection集合遍歷運行代碼實例

    Java Collection集合遍歷運行代碼實例

    這篇文章主要介紹了Java Collection集合遍歷運行代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-04-04

最新評論