Dozer 使用小結(jié)

這篇文章是本人在閱讀Dozer官方文檔(5.5.1版本斗这,官網(wǎng)已經(jīng)一年多沒更新了)的過程中,整理下來我認(rèn)為比較基礎(chǔ)的應(yīng)用場景。

本文中提到的例子應(yīng)該能覆蓋JavaBean映射的大部分場景经瓷,希望對你有所幫助翠储。

概述

Dozer是什么?

Dozer是一個JavaBean映射工具庫绘雁。

它支持簡單的屬性映射,復(fù)雜類型映射援所,雙向映射庐舟,隱式顯式的映射,以及遞歸映射住拭。

它支持三種映射方式:注解挪略、API、XML滔岳。

它是開源的杠娱,遵從Apache 2.0 協(xié)議

安裝

引入jar包

maven方式

如果你的項目使用maven,添加以下依賴到你的pom.xml即可:

<dependency>
    <groupId>net.sf.dozer</groupId>
    <artifactId>dozer</artifactId>
    <version>5.4.0</version>
</dependency>

非maven方式

如果你的項目不使用maven谱煤,那就只能發(fā)揚(yáng)不怕苦不怕累的精神了摊求。

使用Dozer需要引入Dozer的jar包以及其依賴的第三方j(luò)ar包。

Eclipse插件

Dozer有插件可以在Eclipse中使用(不知道是否好用刘离,反正我沒用過)

插件地址: http://dozer.sourceforge.net/eclipse-plugin

使用

將Dozer引入到工程中后室叉,我們就可以來小試一番了。

實踐出真知硫惕,先以一個最簡單的例子來展示Dozer映射的處理過程茧痕。

準(zhǔn)備

我們先準(zhǔn)備兩個要互相映射的類

NotSameAttributeA.java

public class NotSameAttributeA {
    private long id;
    private String name;
    private Date date;

    // 省略getter/setter
}

NotSameAttributeB.java

public class NotSameAttributeB {
    private long id;
    private String value;
    private Date date;

    // 省略getter/setter
}

這兩個類存在屬性名不完全相同的情況:name 和 value。

Dozer的配置

為什么要有映射配置?

如果要映射的兩個對象有完全相同的屬性名恼除,那么一切都很簡單踪旷。

只需要直接使用Dozer的API即可:

Mapper mapper = new DozerBeanMapper();
DestinationObject destObject =  
    mapper.map(sourceObject, DestinationObject.class);

但實際映射時,往往存在屬性名不同的情況缚柳。

所以埃脏,你需要一些配置來告訴Dozer應(yīng)該轉(zhuǎn)換什么,怎么轉(zhuǎn)換秋忙。

注:官網(wǎng)著重建議:在現(xiàn)實應(yīng)用中彩掐,最好不要每次映射對象時都創(chuàng)建一個Mapper實例來工作,這樣會產(chǎn)生不必要的開銷灰追。如果你不使用IoC容器(如:spring)來管理你的項目堵幽,那么狗超,最好將Mapper定義為單例模式。

映射配置文件

src/test/resources目錄下添加dozer/dozer-mapping.xml文件朴下。
<mapping>標(biāo)簽中允許你定義<class-a><class-b>努咐,對應(yīng)著相互映射的類。
<field>標(biāo)簽里定義要映射的特殊屬性殴胧。需要注意<a><class-a>對應(yīng)渗稍,<b><class-b>對應(yīng),聰明的你团滥,猜也猜出來了吧竿屹。

<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozer.sourceforge.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://dozer.sourceforge.net
          http://dozer.sourceforge.net/schema/beanmapping.xsd">
  <mapping date-format="yyyy-MM-dd">
    <class-a>org.zp.notes.spring.common.dozer.vo.NotSameAttributeA</class-a>
    <class-b>org.zp.notes.spring.common.dozer.vo.NotSameAttributeB</class-b>
    <field>
      <a>name</a>
      <b>value</b>
    </field>
  </mapping>
</mappings>

與Spring整合

配置 DozerBeanMapperFactoryBean

src/test/resources目錄下添加spring/spring-dozer.xml文件。

Dozer與Spring的整合很便利灸姊,你只需要聲明一個DozerBeanMapperFactoryBean拱燃,
將所有的dozer映射配置文件作為屬性注入到mappingFiles
DozerBeanMapperFactoryBean會加載這些規(guī)則力惯。

spring-dozer.xml文件范例

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
       default-autowire="byName" default-lazy-init="false">

  <bean id="mapper" class="org.dozer.spring.DozerBeanMapperFactoryBean">
    <property name="mappingFiles">
      <list>
        <value>classpath*:dozer/dozer-mapping.xml</value>
      </list>
    </property>
  </bean>
</beans>

自動裝配

至此碗誉,萬事具備,你只需要自動裝配mapper父晶。

RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring/spring-dozer.xml"})
@TransactionConfiguration(defaultRollback = false)
public class DozerTest extends TestCase {
    @Autowired
    Mapper mapper;

    @Test
    public void testNotSameAttributeMapping() {
        NotSameAttributeA src = new NotSameAttributeA();
        src.setId(007);
        src.setName("邦德");
        src.setDate(new Date());

        NotSameAttributeB desc = mapper.map(src, NotSameAttributeB.class);
        Assert.assertNotNull(desc);
    }
}

運(yùn)行一下單元測試哮缺,綠燈通過。

Dozer支持的數(shù)據(jù)類型轉(zhuǎn)換

Dozer可以自動做數(shù)據(jù)類型轉(zhuǎn)換诱建。當(dāng)前蝴蜓,Dozer支持以下數(shù)據(jù)類型轉(zhuǎn)換(都是雙向的)

  • Primitive to Primitive Wrapper

    原型(int、long等)和原型包裝類(Integer俺猿、Long)

  • Primitive to Custom Wrapper

    原型和定制的包裝

  • Primitive Wrapper to Primitive Wrapper

    原型包裝類和包裝類

  • Primitive to Primitive

    原型和原型

  • Complex Type to Complex Type

    復(fù)雜類型和復(fù)雜類型

  • String to Primitive

    字符串和原型

  • String to Primitive Wrapper

    字符串和原型包裝類

  • String to Complex Type if the Complex Type contains a String constructor

    字符串和有字符串構(gòu)造器的復(fù)雜類型(類)

  • String to Map

    字符串和Map

  • Collection to Collection

    集合和集合

  • Collection to Array

    集合和數(shù)組

  • Map to Complex Type

    Map和復(fù)雜類型

  • Map to Custom Map Type

    Map和定制Map類型

  • Enum to Enum

    枚舉和枚舉

  • Each of these can be mapped to one another: java.util.Date, java.sql.Date, java.sql.Time, java.sql.Timestamp, java.util.Calendar, java.util.GregorianCalendar

    這些時間相關(guān)的常見類可以互換:java.util.Date, java.sql.Date, java.sql.Time, java.sql.Timestamp, java.util.Calendar, java.util.GregorianCalendar

  • String to any of the supported Date/Calendar Objects.

    字符串和支持Date/Calendar的對象

  • **Objects containing a toString() method that produces a long representing time in (ms) to any supported Date/Calendar object. **

    如果一個對象的toString()方法返回的是一個代表long型的時間數(shù)值(單位:ms)茎匠,就可以和任何支持Date/Calendar的對象轉(zhuǎn)換。

Dozer的映射配置

在前面的簡單例子中押袍,我們體驗了一把Dozer的映射流程诵冒。但是兩個類進(jìn)行映射,有很多復(fù)雜的情況谊惭,相應(yīng)的汽馋,你也需要一些更復(fù)雜的配置。

Dozer有三種映射配置方式:

  • 注解方式
  • API方式
  • XML方式

用注解來配置映射

Dozer 5.3.2版本開始支持注解方式配置映射(只有一個注解:@Mapping)圈盔”荆可以應(yīng)對一些簡單的映射處理,復(fù)雜的就玩不轉(zhuǎn)了驱敲。

看一下@Mapping的聲明就可以知道铁蹈,這個注解只能用于元素和方法。

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
public @interface Mapping {
  String value() default "";
}

讓我們來試試吧:

TargetBean.java

public class SourceBean {

    private Long id;

    private String name;

    @Mapping("binaryData")
    private String data;

    @Mapping("pk")
    public Long getId() {
        return this.id;
    }

    //其余getter/setter方法略
}

TargetBean.java

public class TargetBean {

    private String pk;

    private String name;

    private String binaryData;

    //getter/setter方法略
}

定義了兩個相互映射的Java類众眨,只需要在源類中用@Mapping標(biāo)記和目標(biāo)類中對應(yīng)的屬性就可以了握牧。

@Test
public void testAnnotationMapping() {
    SourceBean src = new SourceBean();
    src.setId(7L);
    src.setName("邦德");
    src.setData("00000111");

    TargetBean desc = mapper.map(src, TargetBean.class);
    Assert.assertNotNull(desc);
}

測試一下容诬,綠燈通過。

官方文檔說沿腰,雖然當(dāng)前版本(文檔的版本對應(yīng)Dozer 5.5.1)僅支持@Mapping览徒,但是在未來的發(fā)布版本會提供其他的注解功能,那就敬請期待吧(再次吐槽一下:一年多沒更新了)颂龙。

用API來配置映射

個人覺得這種方式比較麻煩习蓬,不推薦,也不想多做介紹措嵌,就是這么任性友雳。

用XML來配置映射

需要強(qiáng)調(diào)的是:如果兩個類的所有屬性都能很好的互轉(zhuǎn),可以你中有我铅匹,我中有你,不分彼此饺藤,那么就不要畫蛇添足的在xml中去聲明映射規(guī)則了包斑。

屬性名不同時的映射(Basic Property Mapping)

Dozer會自動映射屬性名相同的屬性,所以不必添加在xml文件中涕俗。

<field>
  <a>one</a>
  <b>onePrime</b>
</field>

字符串和日期映射(String to Date Mapping)

字符串在和日期進(jìn)行映射時罗丰,允許用戶指定日期的格式。

格式的設(shè)置分為三個作用域級別:

屬性級別

對當(dāng)前屬性有效(這個屬性必須是日期字符串)

<field>
  <a date-format="MM/dd/yyyy HH:mm:ss:SS">dateString</a>
  <b>dateObject</b>
</field>

類級別

對這個類中的所有日期相關(guān)的屬性有效

<mapping date-format="MM-dd-yyyy HH:mm:ss">
  <class-a>org.dozer.vo.TestObject</class-a>
  <class-b>org.dozer.vo.TestObjectPrime</class-b>
  <field>
    <a>dateString</a>
    <b>dateObject</b>
  </field>
</mapping>

全局級別

對整個文件中的所有日期相關(guān)的屬性有效再姑。

<mappings>
  <configuration>
    <date-format>MM/dd/yyyy HH:mm</date-format>
  </configuration>

  <mapping wildcard="true">
    <class-a>org.dozer.vo.TestObject</class-a>
    <class-b>org.dozer.vo.TestObjectPrime</class-b>
    <field>
      <a>dateString</a>
      <b>dateObject</b>
    </field>
  </mapping>
</mappings>

集合和數(shù)組映射(Collection and Array Mapping)

Dozer可以自動處理以下類型的雙向轉(zhuǎn)換萌抵。

  • List to List
  • List to Array
  • Array to Array
  • Set to Set
  • Set to Array
  • Set to List

使用hint

如果使用泛型或數(shù)組,沒有必要使用hint元镀。

如果不使用泛型或數(shù)組绍填。在處理集合或數(shù)組之間的轉(zhuǎn)換時,你需要用hint指定目標(biāo)列表的數(shù)據(jù)類型栖疑。

若你不指定hint讨永,Dozer將認(rèn)為目標(biāo)集合和源集合的類型是一致的。

使用Hints的范例:

<field>
  <a>hintList</a> 
  <b>hintList</b> 
  <b-hint>org.dozer.vo.TheFirstSubClassPrime</b-hint> 
</field> 

累計映射和非累計映射(Cumulative vs. Non-Cumulative List Mapping)

如果你要轉(zhuǎn)換的目標(biāo)類已經(jīng)初始化遇革,你可以選擇讓Dozer添加或更新對象到你的集合中卿闹。

而這取決于relationship-type配置,默認(rèn)是累計萝快。

它的設(shè)置有作用域級別:

  • 全局級
<mappings>
  <configuration>
     <relationship-type>non-cumulative</relationship-type>
  </configuration>
</mappings>
  • 類級別
<mappings>
  <mapping relationship-type="non-cumulative">
    <!-- 省略 -->  
  </mapping> 
</mappings>
  • 屬性級別
<field relationship-type="cumulative">
  <a>hintList</a>
  <b>hintList</b> 
  <a-hint>org.dozer.vo.TheFirstSubClass</a-hint> 
  <b-hint>org.dozer.vo.TheFirstSubClassPrime</b-hint> 
</field>

移動孤兒(Removing Orphans)

這里的孤兒是指目標(biāo)集合中存在锻霎,但是源集合中不存在的元素。

你可以使用remove-orphans開關(guān)來選擇是否移除這樣的元素揪漩。

<field remove-orphans="true">
  <a>srcList</a> 
  <b>destList</b>  
</field>    

深度映射(Deep Mapping)

所謂深度映射旋恼,是指允許你指定屬性的屬性(比如一個類的屬性本身也是一個類)。舉例來說

Source.java

public class Source {
    private long id;
    private String info;
}

Dest.java

public class Dest {
    private long id;
    private Info info;
}
public class Info {
    private String content;
}

映射規(guī)則

<mapping>
  <class-a>org.zp.notes.spring.common.dozer.vo.Source</class-a>
  <class-b>org.zp.notes.spring.common.dozer.vo.Dest</class-b>
  <field>
    <a>info</a>
    <b>info.content</b>
  </field>
</mapping>

排除屬性(Excluding Fields)

就像任何團(tuán)體都有搗亂分子氢拥,類之間轉(zhuǎn)換時也有想要排除的因子蚌铜。

如何在做類型轉(zhuǎn)換時锨侯,自動排除一些屬性,Dozer提供了幾種方法冬殃,這里只介紹一種比較通用的方法囚痴。

更多詳情參考官網(wǎng)

field-exclude可以排除不需要映射的屬性审葬。

<field-exclude> 
  <a>fieldToExclude</a> 
  <b>fieldToExclude</b> 
</field-exclude>

單向映射(One-Way Mapping)

注:本文的映射方式深滚,無特殊說明,都是雙向映射的涣觉。

有的場景可能希望轉(zhuǎn)換過程不可逆痴荐,即單向轉(zhuǎn)換。

單向轉(zhuǎn)換可以通過使用one-way來開啟

類級別

<mapping type="one-way"> 
  <class-a>org.dozer.vo.TestObjectFoo</class-a>
  <class-b>org.dozer.vo.TestObjectFooPrime</class-b>   
    <field>
      <a>oneFoo</a>
      <b>oneFooPrime</b>
    </field>
</mapping>  

屬性級別

<mapping> 
  <class-a>org.dozer.vo.TestObjectFoo2</class-a>
  <class-b>org.dozer.vo.TestObjectFooPrime2</class-b>   
  <field type="one-way">
    <a>oneFoo2</a>
    <b>oneFooPrime2</b>
  </field>

  <field type="one-way">
    <a>oneFoo3.prime</a>
    <b>oneFooPrime3</b>
  </field>

全局配置(Global Configuration)

全局配置用來設(shè)置全局的配置信息官册。此外生兆,任何定制轉(zhuǎn)換都是在這里定義的。

全局配置都是可選的膝宁。

  • <date-format>表示日期格式
  • <stop-on-errors>錯誤處理開關(guān)
  • <wildcard>通配符
  • <trim-strings>裁剪字符串開關(guān)
<configuration >
  
  <date-format>MM/dd/yyyy HH:mm</date-format>
  <stop-on-errors>true</stop-on-errors>
  <wildcard>true</wildcard>
  <trim-strings>false</trim-strings>
     
  <custom-converters> <!-- these are always bi-directional -->
    <converter type="org.dozer.converters.TestCustomConverter" >
      <class-a>org.dozer.vo.TestCustomConverterObject</class-a>
      <class-b>another.type.to.Associate</class-b>
    </converter>
     
  </custom-converters>     
</configuration>

全局配置的作用是幫助你少配置一些參數(shù)鸦难,如果個別類的映射規(guī)則需要變更,你可以mapping中覆蓋它员淫。

覆蓋的范例如下

<mapping date-format="MM-dd-yyyy HH:mm:ss"> 
  <!-- 省略 -->
</mapping>

<mapping wildcard="false">
  <!-- 省略 -->
</mapping> 

<mapping stop-on-errors="false"> 
  <!-- 省略 -->
</mapping>

<mapping trim-strings="true"> 
  <!-- 省略 -->
</mapping>      

定制轉(zhuǎn)換(Custom Converters)

如果Dozer默認(rèn)的轉(zhuǎn)換規(guī)則不能滿足實際需要合蔽,你可以選擇定制轉(zhuǎn)換。

定制轉(zhuǎn)換通過配置XML來告訴Dozer如何去轉(zhuǎn)換兩個指定的類介返。當(dāng)Dozer轉(zhuǎn)換這兩個指定類的時候拴事,會調(diào)用你的映射規(guī)則去替換標(biāo)準(zhǔn)映射規(guī)則。

為了讓Dozer識別圣蝎,你必須實現(xiàn)org.dozer.CustomConverter接口刃宵。否則,Dozer會拋異常捅彻。

具體做法:

(1) 創(chuàng)建一個類實現(xiàn)org.dozer.CustomConverter接口组去。

public class TestCustomConverter implements CustomConverter {
  
  public Object convert(Object destination, Object source, 
      Class destClass, Class sourceClass) {
    if (source == null) {
      return null;
    }
    CustomDoubleObject dest = null;
    if (source instanceof Double) {
      // check to see if the object already exists
      if (destination == null) {
        dest = new CustomDoubleObject();
      } else {
        dest = (CustomDoubleObject) destination;
      }
      dest.setTheDouble(((Double) source).doubleValue());
      return dest;
    } else if (source instanceof CustomDoubleObject) {
      double sourceObj = 
        ((CustomDoubleObject) source).getTheDouble();
      return new Double(sourceObj);
    } else {
      throw new MappingException("Converter TestCustomConverter "
          + "used incorrectly. Arguments passed in were:"
          + destination + " and " + source);
    }
  } 

(2) 在xml中引用定制的映射規(guī)則

引用定制的映射規(guī)則也是分級的,你可以酌情使用步淹。

  • 全局級
<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozer.sourceforge.net"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://dozer.sourceforge.net
          http://dozer.sourceforge.net/schema/beanmapping.xsd">
  <configuration>
    <!-- 總是雙向轉(zhuǎn)換的 -->
    <custom-converters>
      <converter type="org.dozer.converters.TestCustomConverter" >
        <class-a>org.dozer.vo.CustomDoubleObject</class-a>
        <class-b>java.lang.Double</class-b>
      </converter>

      <!-- You are responsible for mapping everything between 
           ClassA and ClassB -->
      <converter 
        type="org.dozer.converters.TestCustomHashMapConverter" >
        <class-a>org.dozer.vo.TestCustomConverterHashMapObject</class-a>
        <class-b>org.dozer.vo.TestCustomConverterHashMapPrimeObject</class-b>
      </converter>
    </custom-converters>     
  </configuration>
</mappings>
  • 屬性級
<mapping>
  <class-a>org.dozer.vo.SimpleObj</class-a>
  <class-b>org.dozer.vo.SimpleObjPrime2</class-b>    
  <field custom-converter=
    "org.dozer.converters.TestCustomConverter">
    <a>field1</a>
    <b>field1Prime</b>
  </field>
</mapping>   

映射的繼承(Inheritance Mapping)

Dozer支持映射規(guī)則的繼承機(jī)制从隆。

屬性如果有著相同的名字則不需要在xml中配置,除非使用了hint

我們來看一個例子

<mapping>
  <class-a>org.dozer.vo.SuperClass</class-a>
  <class-b>org.dozer.vo.SuperClassPrime</class-b>
    
  <field>
    <a>superAttribute</a>
    <b>superAttr</b>
  </field>
</mapping>  

<mapping>
  <class-a>org.dozer.vo.SubClass</class-a>
  <class-b>org.dozer.vo.SubClassPrime</class-b>
    
  <field>
    <a>attribute</a>
    <b>attributePrime</b>
  </field>
</mapping>
  
<mapping>
  <class-a>org.dozer.vo.SubClass2</class-a>
  <class-b>org.dozer.vo.SubClassPrime2</class-b>
     
  <field>
    <a>attribute2</a>
    <b>attributePrime2</b>
  </field>
</mapping>

在上面的例子中SubClass缭裆、SubClass2是SuperClass的子類键闺;

SubClassPrime和SubClassPrime2是SuperClassPrime的子類。

superAttribute和superAttr的映射規(guī)則會被子類所繼承澈驼,所以不必再重復(fù)的在子類中去聲明驹愚。

參考

Dozer官方文檔 | Dozer源碼地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末炊昆,一起剝皮案震驚了整個濱河市睁枕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌徘六,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件榴都,死亡現(xiàn)場離奇詭異待锈,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)嘴高,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進(jìn)店門竿音,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人拴驮,你說我怎么就攤上這事春瞬。” “怎么了套啤?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵宽气,是天一觀的道長。 經(jīng)常有香客問我潜沦,道長抹竹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任止潮,我火速辦了婚禮,結(jié)果婚禮上钞楼,老公的妹妹穿的比我還像新娘喇闸。我一直安慰自己,他們只是感情好询件,可當(dāng)我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布燃乍。 她就那樣靜靜地躺著,像睡著了一般宛琅。 火紅的嫁衣襯著肌膚如雪刻蟹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天嘿辟,我揣著相機(jī)與錄音舆瘪,去河邊找鬼。 笑死红伦,一個胖子當(dāng)著我的面吹牛英古,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播昙读,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼召调,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起唠叛,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤只嚣,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后艺沼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體册舞,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年澳厢,在試婚紗的時候發(fā)現(xiàn)自己被綠了环础。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡剩拢,死狀恐怖线得,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情徐伐,我是刑警寧澤贯钩,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站办素,受9級特大地震影響角雷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜性穿,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一勺三、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧需曾,春花似錦吗坚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至谋减,卻和暖如春牡彻,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背出爹。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工庄吼, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人严就。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓霸褒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親盈蛮。 傳聞我的和親對象是個殘疾皇子废菱,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 1. 簡介 1.1 什么是 MyBatis 技矮? MyBatis 是支持定制化 SQL、存儲過程以及高級映射的優(yōu)秀的...
    笨鳥慢飛閱讀 5,454評論 0 4
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理殊轴,服務(wù)發(fā)現(xiàn)衰倦,斷路器,智...
    卡卡羅2017閱讀 134,629評論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,773評論 6 342
  • Spark SQL, DataFrames and Datasets Guide Overview SQL Dat...
    草里有只羊閱讀 18,303評論 0 85
  • 誤區(qū):書是不是應(yīng)該要一本一本的閱讀 不是的旁理,看目錄樊零,只要找到自己需要的內(nèi)容開始閱讀 方法一:主動閱讀 1.帶著問題...
    CNBLUEone閱讀 227評論 0 1