ביצוע מסגרות מיפוי של Java

1. מבוא

יצירת יישומי ג'אווה גדולים המורכבים ממספר שכבות דורשים שימוש במספר מודלים כגון מודל התמדה, מודל תחום או מה שמכונה DTO. שימוש במספר דגמים לשכבות יישום שונות ידרוש מאיתנו לספק דרך למיפוי בין שעועית.

פעולה זו באופן ידני יכולה ליצור במהירות הרבה קוד לבישול ולצרוך זמן רב. למזלנו, ישנן מספר מסגרות מיפוי אובייקטים עבור Java.

במדריך זה, נשווה את הביצועים של מסגרות המיפוי הפופולריות ביותר של Java.

2. מסגרות מיפוי

2.1. דוזר

Dozer היא מסגרת מיפוי המשתמשת ברקורסיה כדי להעתיק נתונים מאובייקט אחד לאחר. המסגרת מסוגלת לא רק להעתיק מאפיינים בין השעועית, אלא היא יכולה גם להמיר אוטומטית בין סוגים שונים.

כדי להשתמש במסגרת Dozer עלינו להוסיף תלות כזו לפרויקט שלנו:

 com.github.dozermapper core-core 6.5.0 

מידע נוסף אודות השימוש במסגרת Dozer ניתן למצוא במאמר זה.

את תיעוד המסגרת תוכלו למצוא כאן.

2.2. אוריקה

אוריקה היא מסגרת למיפוי שעועית לשעועית שמעתיקה רקורסיבית נתונים מאובייקט אחד לאחר.

עקרון העבודה הכללי של האוריקה דומה לדוזר. ההבדל העיקרי בין השניים הוא העובדה ש אוריקה משתמשת בייצור קוד קוד. זה מאפשר ליצור מיפוי מהיר יותר עם תקורה מינימלית.

להשתמש בזה,עלינו להוסיף תלות כזו לפרויקט שלנו:

 ma.glasnost.orika orika-core 1.5.4 

מידע מפורט יותר על השימוש באוריקה ניתן למצוא במאמר זה.

את תיעוד המסגרת בפועל ניתן למצוא כאן.

2.3. MapStruct

MapStruct הוא מחולל קוד שמייצר מחלקות מיפוי שעועית באופן אוטומטי.

ל- MapStruct יש גם אפשרות להמיר בין סוגי נתונים שונים. מידע נוסף על אופן השימוש בו ניתן למצוא במאמר זה.

להוספת MapStructלפרויקט שלנו עלינו לכלול את התלות הבאה:

 org.mapstruct mapstruct 1.3.1. גמר 

את תיעוד המסגרת תוכלו למצוא כאן.

2.4. ModelMapper

ModelMapper היא מסגרת שמטרתה לפשט את מיפוי האובייקטים, על ידי קביעת האופן שבו האובייקטים מתמפים זה לזה על פי מוסכמות. הוא מספק API בטוח ובטוח מחדש.

מידע נוסף על המסגרת נמצא בתיעוד.

כדי לכלול את ModelMapper בפרויקט שלנו עלינו להוסיף את התלות הבאה:

 org.modelmapper modelmapper 2.3.8 

2.5. JMapper

JMapper היא מסגרת המיפוי שמטרתה לספק מיפוי קל לשימוש וביצועים גבוהים בין Java Beans.

המסגרת נועדה ליישם את עקרון ה- DRY באמצעות הערות ומיפוי יחס.

המסגרת מאפשרת דרכי תצורה שונות: מבוסס הערות, מבוסס XML או API.

מידע נוסף על המסגרת נמצא בתיעוד שלה.

כדי לכלול את JMapper בפרויקט שלנו עלינו להוסיף את התלות שלו:

 com.googlecode.jmapper-framework jmapper-core 1.6.1.CR2 

3. בדיקותדֶגֶם

כדי להיות מסוגל לבדוק מיפוי כראוי עלינו להיות מודלים מקור ומיקוד. יצרנו שני מודלים לבדיקה.

הראשון הוא פשוט POJO פשוט עם אחד חוּט זה מאפשר לנו להשוות מסגרות במקרים פשוטים יותר ולבדוק אם משהו משתנה אם אנו משתמשים בשעועית מסובכת יותר.

מודל המקור הפשוט נראה למטה:

מחלקה ציבורית SourceCode {קוד מחרוזת; // גטר וקובע}

ויעדו די דומה:

מחלקה ציבורית DestinationCode {קוד מחרוזת; // גטר וקובע}

הדוגמה האמיתית של שעועית מקור נראית כך:

מחלקה ציבורית SourceOrder {private String orderFinishDate; תשלום פרטי סוג סוג תשלום סוג; הנחה פרטית בהנחה; פרטי משלוח מסירת נתונים נתונים; הזמנת משתמש פרטי; משתמש; רשימת פרטי שהוזמנה מוצרים; חנות פרטית המציעה חנות; order int הזמנה פרטית; מצב OrderStatus פרטי; פרטי LocalDate orderDate; // סטרים וקובעים סטנדרטיים}

וכיתת היעד נראית למטה:

מחלקה ציבורית Order {User orderingUser; רשימת פרטי שהוזמנה מוצרים; פרטי OrderStatus orderStatus; פרטי LocalDate orderDate; פרטי LocalDate orderFinishDate; תשלום פרטי סוג סוג תשלום סוג; הנחה בהנחה פרטית; חנות פרטית int; פרטי משלוח מסירת נתונים נתונים; חנות פרטית המציעה חנות; // סטרים וקובעים סטנדרטיים}

את כל מבנה המודל ניתן למצוא כאן.

4. ממירים

כדי לפשט את העיצוב של הגדרת הבדיקה, יצרנו את מֵמִיר מִמְשָׁק:

ממיר ממשק ציבורי {Order convert (SourceOrder sourceOrder); המרת DestinationCode (SourceCode sourceCode); }

וכל המפות המותאמות אישית שלנו יישמו את הממשק הזה.

4.1. OrikaConverter

אוריקה מאפשרת יישום ממשק API מלא, זה מאוד מפשט את יצירת המפות:

מחלקה ציבורית OrikaConverter מיישם ממיר {פרטי MapperFacade mapperFacade; ציבורי OrikaConverter () {MapperFactory mapperFactory = DefaultMapperFactory חדש. Builder (). build (); mapperFactory.classMap (Order.class, SourceOrder.class) .field ("orderStatus", "status"). byDefault (). register (); mapperFacade = mapperFactory.getMapperFacade (); } @Override הסדר ציבורי להמיר (SourceOrder sourceOrder) {return mapperFacade.map (sourceOrder, Order.class); } @Override המרת יעד DestinationCode ציבורית (SourceCode sourceCode) {return mapperFacade.map (sourceCode, DestinationCode.class); }}

4.2. ממיר DozerConverter

Dozer דורש קובץ מיפוי XML, עם הסעיפים הבאים:

  com.baeldung.performancetests.model.source.SourceOrder com.baeldung.performancetests.model.destination.Oder status מצב הזמנה    com.baeldung.performancetests.model.source.SourceCode com.baeldung.performancetests.model.destination.DestinationCode 

לאחר הגדרת מיפוי ה- XML, נוכל להשתמש בה מקוד:

מחלקה ציבורית DozerConverter מיישם ממיר {Mapper Mapper Mapper הסופי; DozerConverter () {this.mapper = DozerBeanMapperBuilder.create () .withMappingFiles ("dozer-mapping.xml") .build (); } @Override הסדר ציבורי להמיר (SourceOrder sourceOrder) {return mapper.map (sourceOrder, Order.class); } @Override יעד DestinationCode ציבורי (SourceCode sourceCode) {return mapper.map (sourceCode, DestinationCode.class); }}

4.3. MapStructConverter

הגדרת MapStruct היא די פשוטה מכיוון שהיא מבוססת לחלוטין על יצירת קוד:

ממשק ציבורי @Mapper MapStructConverter מרחיב ממיר {MapStructConverter MAPPER = Mappers.getMapper (MapStructConverter.class); @Mapping (source = "status", target = "orderStatus") @Override Order convert (SourceOrder sourceOrder); המרת @Override DestinationCode (SourceCode sourceCode); }

4.4. ממיר JMapper

ממיר JMapper דורש יותר עבודה. לאחר הטמעת הממשק:

מחלקה ציבורית JMapperConverter מיישם ממיר {JMapper realLifeMapper; JMapper simpleMapper; JMapperConverter ציבורי () {JMapperAPI api = JMapperAPI חדש (). להוסיף (JMapperAPI.mappedClass (Order.class)); realLifeMapper = JMapper חדש (Order.class, SourceOrder.class, api); JMapperAPI simpleApi = JMapperAPI חדש (). להוסיף (JMapperAPI.mappedClass (DestinationCode.class)); simpleMapper = JMapper חדש (DestinationCode.class, SourceCode.class, simpleApi); } @Override הסדר ציבורי להמיר (SourceOrder sourceOrder) {return (Order) realLifeMapper.getDestination (sourceOrder); } @Override המרת DestinationCode ציבורית (SourceCode sourceCode) {return (DestinationCode) simpleMapper.getDestination (sourceCode); }}

אנחנו גם צריכים להוסיף @JMap ביאורים לכל שדה במחלקת היעד. כמו כן, JMapper לא יכול להמיר בין סוגי enum בפני עצמו והוא דורש מאיתנו ליצור פונקציות מיפוי מותאמות אישית:

@JMapConversion (מ- = "paymentType", ל- = "paymentType") המרת תשלום סוג ציבורי (com.baeldung.performancetests.model.source.PaymentType סוג) {PaymentType paymentType = null; switch (type) {case CARD: paymentType = PaymentType.CARD; לשבור; case CASH: paymentType = PaymentType.CASH; לשבור; מקרה העברה: paymentType = PaymentType.TRANSFER; לשבור; } להחזיר את PaymentType; }

4.5. ModelMapperConverter

ModelMapperConverter מחייב אותנו לספק רק את השיעורים שאנו רוצים למפות:

מחלקה ציבורית ModelMapperConverter מיישמת ממיר {ModelMapper modelMapper פרטי; ModelMapperConverter () {modelMapper = ModelMapper חדש (); } @Override הסדר ציבורי להמיר (SourceOrder sourceOrder) {return modelMapper.map (sourceOrder, Order.class); } @Override DestinationCode המרה ציבורית (SourceCode sourceCode) {return modelMapper.map (sourceCode, DestinationCode.class); }}

5. בדיקת מודלים פשוטה

לצורך בדיקת הביצועים אנו יכולים להשתמש ב- Java Microbenchmark Harness, מידע נוסף על אופן השימוש בו ניתן למצוא במאמר זה.

יצרנו אמת מידה נפרדת עבור כל אחת מהן מֵמִיר עם ציון BenchmarkMode ל מצב. הכל.

5.1. זמן ממוצע

JMH החזיר את התוצאות הבאות למשך זמן ריצה ממוצע (כמה שפחות טוב יותר):

שם המסגרתזמן ריצה ממוצע (ב- ms לכל פעולה)
MapStruct10 -5
JMapper10 -5
אוריקה0.001
ModelMapper0.001
דוזר0.002

אמת מידה זו מראה בבירור כי הן MapStruct והן JMapper הם בעלי זמני העבודה הממוצעים הטובים ביותר.

5.2. תפוקה

במצב זה, המדד מחזיר את מספר הפעולות בשנייה. קיבלנו את התוצאות הבאות (יותר טוב יותר) :

שם המסגרתתפוקה (בפעולות לכל אלפיות שנייה)
MapStruct133719
JMapper106978
אוריקה1800
ModelMapper978
דוזר471

במצב תפוקה, MapStruct הייתה המהירה ביותר מבין המסגרות שנבדקו, עם JMapper שנייה קרובה.

5.3. SingleShotTime

מצב זה מאפשר מדידת זמן הפעולה היחיד מתחילתו ועד סופו. המדד נתן את התוצאה הבאה (פחות טוב יותר):

שם המסגרתזמן ירייה בודדת (ב- ms לכל פעולה)
JMapper0.015
MapStruct0.450
דוזר2.094
אוריקה2.898
ModelMapper4.837

כאן אנו רואים כי JMapper מחזיר תוצאה טובה יותר מזו של MapStruct.

5.4. SampleTime

מצב זה מאפשר דגימה של זמן כל פעולה. התוצאות לשלושה אחוזונים שונים נראות להלן:

זמן לדוגמא (באלפיות השנייה לפעולה)
שם המסגרתp0.90p0.999p1.0
JMapper10-40.0012.6
MapStruct10-40.0013
אוריקה0.0010.0104
ModelMapper0.0020.0153.2
דוזר0.0030.02125

כל המדדים הראו כי MapStruct ו- JMapper הן בחירות טובות בהתאם לתרחיש.

6. בדיקת מודלים של החיים האמיתיים

לצורך בדיקת הביצועים אנו יכולים להשתמש ב- Java Microbenchmark Harness, מידע נוסף על אופן השימוש בו ניתן למצוא במאמר זה.

יצרנו אמת מידה נפרדת עבור כל אחת מהן מֵמִיר עם ציון BenchmarkMode ל מצב. הכל.

6.1. זמן ממוצע

JMH החזיר את התוצאות הבאות למשך זמן ריצה ממוצע (פחות טוב יותר):

שם המסגרתזמן ריצה ממוצע (ב- ms לכל פעולה)
MapStruct10 -4
JMapper10 -4
אוריקה0.004
ModelMapper0.059
דוזר0.103

6.2. תפוקה

במצב זה, המדד מחזיר את מספר הפעולות בשנייה. עבור כל אחד מהמפים קיבלנו את התוצאות הבאות (יותר טוב):

שם המסגרתתפוקה (בפעולות למ"ש)
JMapper7691
MapStruct7120
אוריקה281
ModelMapper19
דוזר10

6.3. SingleShotTime

מצב זה מאפשר מדידת זמן הפעולה היחיד מתחילתו ועד סופו. המדד נתן את התוצאות הבאות (פחות טוב יותר):

שם המסגרתזמן ירייה בודדת (ב- ms לכל פעולה)
JMapper0.253
MapStruct0.532
דוזר9.495
ModelMapper16.288
אוריקה18.081

6.4. SampleTime

מצב זה מאפשר דגימה של זמן הפעולה. תוצאות הדגימה מחולקות לאחוזים, נציג תוצאות לשלושה אחוזונים שונים p0.90, p0.999, ו- p1.00:

זמן לדוגמא (באלפיות השנייה לכל פעולה)
שם המסגרתp0.90p0.999p1.0
JMapper10-30.00864
MapStruct10-30.01068
אוריקה0.0060.27832
ModelMapper0.0832.39897
דוזר0.1464.526118

אמנם התוצאות המדויקות של הדוגמה הפשוטה והדוגמה האמיתית היו שונות בבירור, אך הן עוקבות פחות או יותר באותה מגמה. בשתי הדוגמאות ראינו תחרות צמודה בין JMapper ו- MapStruct על המקום הראשון.

6.5. סיכום

בהתבסס על בדיקות המודל האמיתי שביצענו בסעיף זה, אנו יכולים לראות שהביצועים הטובים ביותר שייכים בבירור ל- JMapper, אם כי MapStruct היא שנייה קרובה. באותן בדיקות אנו רואים כי דוזר נמצא באופן עקבי בתחתית טבלת התוצאות שלנו, למעט SingleShotTime.

7. סיכום

במאמר זה ערכנו מבחני ביצועים של חמש מסגרות מיפוי שעועית פופולריות של Java: ModelMapper, MapStruct, אוריקה, דוזר ו- JMapper.

כמו תמיד, ניתן למצוא דוגמאות קוד ב- GitHub.


$config[zx-auto] not found$config[zx-overlay] not found