mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
Adding readme file
This commit is contained in:
parent
e07add7d43
commit
6c9e3159b8
132
readme.md
Normal file
132
readme.md
Normal file
@ -0,0 +1,132 @@
|
||||
# What's Maple?
|
||||
|
||||
Maple is a Java [annotation processor](http://docs.oracle.com/javase/6/docs/technotes/guides/apt/index.html) for the generation of type-safe bean mapping classes.
|
||||
|
||||
All you have to do is to define one more more mapper interfaces, annotate them with the `@Mapper` annotation and add the required mapping methods. During compilation, Maple will generate an implementation for each mapper interface, based on your preferred mapping framework (currently [Dozer](http://dozer.sourceforge.net/) is supported, more to come).
|
||||
|
||||
The following shows an example. First, an object (e.g. a JPA entity) and an accompanying data transfer object (DTO):
|
||||
|
||||
public class Car {
|
||||
|
||||
private String make;
|
||||
private int numberOfSeats;
|
||||
private int yearOfManufacture;
|
||||
|
||||
//constructor, getters, setters etc.
|
||||
}
|
||||
|
||||
public class CarDto {
|
||||
|
||||
private String make;
|
||||
private int seatCount;
|
||||
private int yearOfManufacture;
|
||||
|
||||
//constructor, getters, setters etc.
|
||||
}
|
||||
|
||||
Both types are rather similar, only the seat count attributes have different names. The mapper interface thus looks like this:
|
||||
|
||||
@Mapper
|
||||
public interface CarMapper {
|
||||
|
||||
CarMapper INSTANCE = Mappers.getMapper( CarMapper.class );
|
||||
|
||||
@Mapping(source = "numberOfSeats", target = "seatCount"),
|
||||
CarDto carToCarDto(Car car);
|
||||
|
||||
Car carDtoToCar(CarDto carDto);
|
||||
}
|
||||
|
||||
The interface is straight-forward:
|
||||
|
||||
* Annotating it with `@Mapper` let's the Maple processor kick in during compilation
|
||||
* The `INSTANCE` member provides access to the mapper implementation for clients (a service loader based alternative coming soon)
|
||||
* For each mapping direction (entity to DTO and vice versa) there is a conversion method. For those attributes which have differing names and thus can't be mapped automatically, a mapping is configured using the `@Mapping` annotation on one of the methods.
|
||||
|
||||
Based on the mapper interface, clients can perform object mappings in a very easy and type-safe manner:
|
||||
|
||||
@Test
|
||||
public void shouldMapCarToDto() {
|
||||
|
||||
//given
|
||||
Car car = new Car( "Morris", 2, 1980 );
|
||||
|
||||
//when
|
||||
CarDto carDto = CarMapper.INSTANCE.carToCarDto( car );
|
||||
|
||||
//then
|
||||
assertThat( carDto ).isNotNull();
|
||||
assertThat( carDto.getMake() ).isEqualTo( car.getMake() );
|
||||
assertThat( carDto.getSeatCount() ).isEqualTo( car.getNumberOfSeats() );
|
||||
assertThat( carDto.getyearOfManufacture() ).isEqualTo( car.getyearOfManufacture() );
|
||||
}
|
||||
|
||||
Sometimes not only the names of two corresponding attributes differ, but also their types. This can be addressed by defining a custom type converter:
|
||||
|
||||
public class IntToStringConverter implements Converter<Integer, String> {
|
||||
|
||||
@Override
|
||||
public String from(Integer source) {
|
||||
return source != null ? source.toString() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer to(String target) {
|
||||
return target != null ? Integer.valueOf( target ) : null;
|
||||
}
|
||||
}
|
||||
|
||||
To make use of a converter, specify its type within the `@Mapping` annotation:
|
||||
|
||||
@Mapper
|
||||
public interface CarMapper {
|
||||
|
||||
CarMapper INSTANCE = Mappers.getMapper( CarMapper.class );
|
||||
|
||||
@Mappings({
|
||||
@Mapping(source = "numberOfSeats", target = "seatCount"),
|
||||
@Mapping(source = "yearOfManufacture", target = "manufacturingYear", converter = IntToStringConverter.class)
|
||||
})
|
||||
CarDto carToCarDto(Car car);
|
||||
|
||||
Car carDtoToCar(CarDto carDto);
|
||||
}
|
||||
|
||||
# Using Maple
|
||||
|
||||
Maple is a Java annotation processor based on [JSR 269](jcp.org/en/jsr/detail?id=269) and as such can be used within command line builds (javac, Ant, Maven etc.) as well as from within your IDE.
|
||||
|
||||
Detailed instructions on the usage will be added soon, in between the [set up](http://docs.jboss.org/hibernate/stable/jpamodelgen/reference/en-US/html/chapter-usage.html) of the Hibernate JPA meta model generator can be used as general guideline for setting up an annotation processor.
|
||||
|
||||
In order to use Maple, you have to check out its sources as it is currently not available in any public Maven repository.
|
||||
|
||||
# What's next
|
||||
|
||||
Maple is just in its very beginnings. There are several ideas for further features, including but not limited to:
|
||||
|
||||
* Allow to generate mappers for several existing mapping frameworks (currently only Dozer is supported).
|
||||
* Generate "native" mappers, that is without any reflection, but by direcly invoking getters and setters within the generated mapper. This should deliver very efficient mapper implementations
|
||||
* Provide a way to access the underlying mapper in order to make use of advanced features not provided by the Maple API (similar to the `unwrap()` method of JPA etc.)
|
||||
* Provide a way to add custom mapping code in a very simple way:
|
||||
|
||||
@Mapper(extension=CarMapperCustomization.class)
|
||||
public interface CarMapper {
|
||||
|
||||
CarMapper INSTANCE = Mappers.getMapper( CarMapper.class );
|
||||
|
||||
//automatically generated mapping methods
|
||||
CarDto carToCarDto(Car car);
|
||||
|
||||
Car carDtoToCar(CarDto carDto);
|
||||
|
||||
//very complex mapping which requires some hand-coding
|
||||
Vehicle carToVehicle(Car car);
|
||||
}
|
||||
|
||||
public abstract class CarMapperCustomization implements CarMapper {
|
||||
|
||||
@Override
|
||||
public Vehicle carToVehicle(Car car) {
|
||||
//implement custom mapping logic
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user