目录
4.1、List
迭代的每一项遵循以上规则。
@Mapper
public interface TestMapper {
TestBO testToBO(TestPO testPO);
List<TestBO> testToBOS(List<TestPO> testPOS);
}
@Component
public class TestMapperImpl implements TestMapper {
@Override
public TestBO testToBO(TestPO testPO) {
if ( testPO == null ) {
return null;
}
TestBO testBO = new TestBO();
testBO.setId( testPO.getId() );
testBO.setName( testPO.getName() );
testBO.setPrice( testPO.getPrice() );
testBO.setCreteTime( testPO.getCreteTime() );
return testBO;
}
@Override
public List<TestBO> testToBOS(List<TestPO> testPOS) {
if ( testPOS == null ) {
return null;
}
List<TestBO> list = new ArrayList<TestBO>( testPOS.size() );
for ( TestPO testPO : testPOS ) {
list.add( testToBO( testPO ) );
}
return list;
}
}
@Test
public void baseTest() {
List<TestPO> list = new ArrayList<>();
for (int i = 0; i < 2; i++) {
TestPO testPO = new TestPO();
testPO.setId(1L);
testPO.setName("haru");
testPO.setPrice(new BigDecimal("12.02"));
testPO.setCreteTime(new Date(System.currentTimeMillis()));
list.add(testPO);
}
System.out.println(testMapper.testToBOS(list));
}
结果
4.2、Map
map的key、value分别遵循以上规则。
@Mapper
public interface TestMapper {
TestBO testToBO(TestPO testPO);
Map<TestBO, TestBO> testToBOS(Map<TestPO, TestPO> testPOS);
}
@Component
public class TestMapperImpl implements TestMapper {
@Override
public TestBO testToBO(TestPO testPO) {
if ( testPO == null ) {
return null;
}
TestBO testBO = new TestBO();
testBO.setId( testPO.getId() );
testBO.setName( testPO.getName() );
if ( testPO.getPrice() != null ) {
testBO.setPrice( testPO.getPrice().toString() );
}
if ( testPO.getCreteTime() != null ) {
testBO.setCreteTime( new SimpleDateFormat().format( testPO.getCreteTime() ) );
}
return testBO;
}
@Override
public Map<TestBO, TestBO> testToBOS(Map<TestPO, TestPO> testPOS) {
if ( testPOS == null ) {
return null;
}
Map<TestBO, TestBO> map = new HashMap<TestBO, TestBO>( Math.max( (int) ( testPOS.size() / .75f ) + 1, 16 ) );
for ( java.util.Map.Entry<TestPO, TestPO> entry : testPOS.entrySet() ) {
TestBO key = testToBO( entry.getKey() );
TestBO value = testToBO( entry.getValue() );
map.put( key, value );
}
return map;
}
}
Map<TestPO, TestPO> testPOS = new HashMap<>(8);
TestPO testPO = new TestPO();
testPO.setId(1L);
testPO.setName("haru");
testPO.setPrice(new BigDecimal("12.02"));
testPO.setCreteTime(new Date(System.currentTimeMillis()));
testPOS.put(testPO, testPO);
System.out.println(testMapper.testToBOS(testPOS));
结果
4.3、更新集合
@MappingTarget注释集合上时,会先清除要更新的集合,再添加。
@Mapper
public interface TestMapper {
void updateBO(List<TestPO> testPOS, @MappingTarget List<TestBO> testBOS);
}
@Component
public class TestMapperImpl implements TestMapper {
@Override
public void updateBO(List<TestPO> testPOS, List<TestBO> testBOS) {
if ( testPOS == null ) {
return;
}
testBOS.clear();
for ( TestPO testPO : testPOS ) {
testBOS.add( testPOToTestBO( testPO ) );
}
}
protected TestBO testPOToTestBO(TestPO testPO) {
if ( testPO == null ) {
return null;
}
TestBO testBO = new TestBO();
testBO.setId( testPO.getId() );
testBO.setName( testPO.getName() );
if ( testPO.getPrice() != null ) {
testBO.setPrice( testPO.getPrice().toString() );
}
if ( testPO.getCreteTime() != null ) {
testBO.setCreteTime( new SimpleDateFormat().format( testPO.getCreteTime() ) );
}
return testBO;
}
}
4.4、集合策略
通过@Mapping#collectionMappingStrategy设置集合的映射策略:CollectionMappingStrategy.ACCESSOR_ONLY:默认、CollectionMappingStrategy.SETTER_PREFERRED、CollectionMappingStrategy.ADDER_PREFERRED、CollectionMappingStrategy.TARGET_IMMUTABLE。
只有set方法修改集合 | 只有add方法修改集合 | set、add方法都有修改集合 | set、add方法都没有 | 已经存在的集合对象 | |
---|---|---|---|---|---|
ACCESSOR_ONLY | 直接set集合 | 先get获取集合再addAll | 直接set集合 | 先get获取集合再addAll | 先get获取集合再addAll |
SETTER_PREFERRED | 直接set集合 | add集合一项 | 直接set集合 | 先get获取集合再addAll | 先get获取集合再addAll |
ADDER_PREFERRED | 直接set集合 | add集合一项 | add集合一项 | 先get获取集合再addAll | 先get获取集合再addAll |
TARGET_IMMUTABLE | 直接set集合 | 异常 | 直接set集合 | 异常 | 直接set集合 |
只有add方法,使用CollectionMappingStrategy.ADDER_PREFERRED策略。
public class TestPOS {
private List<TestPO> list;
public List<TestPO> getList() {
return list;
}
public void addList(TestPO testPO) {
this.list.add(testPO);
}
}
public class TestBOS {
private List<TestBO> list;
public List<TestBO> getList() {
return list;
}
public void addList(TestBO testBO) {
this.list.add(testBO);
}
}
@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED)
public interface TestMapper {
TestBO toBO(TestPO testPO);
TestBOS toBOS(TestPOS testPOS);
}
@Component
public class TestMapperImpl implements TestMapper {
@Override
public TestBO toBO(TestPO testPO) {
if ( testPO == null ) {
return null;
}
TestBO testBO = new TestBO();
testBO.setId( testPO.getId() );
testBO.setName( testPO.getName() );
if ( testPO.getPrice() != null ) {
testBO.setPrice( testPO.getPrice().toString() );
}
if ( testPO.getCreteTime() != null ) {
testBO.setCreteTime( new SimpleDateFormat().format( testPO.getCreteTime() ) );
}
return testBO;
}
@Override
public TestBOS toBOS(TestPOS testPOS) {
if ( testPOS == null ) {
return null;
}
TestBOS testBOS = new TestBOS();
if ( testPOS.getList() != null ) {
for ( TestPO list : testPOS.getList() ) {
testBOS.addList( toBO( list ) );
}
}
return testBOS;
}
}
可以看到testBOS.addList( toBO( list ) )使用了add方法。
再看把add方法去掉,使用CollectionMappingStrategy.ACCESSOR_ONLY策略。
public class TestPOS {
private List<TestPO> list;
public List<TestPO> getList() {
return list;
}
}
public class TestBOS {
private List<TestBO> list;
public List<TestBO> getList() {
return list;
}
}
@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ACCESSOR_ONLY)
public interface TestMapper {
TestBO toBO(TestPO testPO);
TestBOS toBOS(TestPOS testPOS);
}
@Component
public class TestMapperImpl implements TestMapper {
@Override
public TestBO toBO(TestPO testPO) {
if ( testPO == null ) {
return null;
}
TestBO testBO = new TestBO();
testBO.setId( testPO.getId() );
testBO.setName( testPO.getName() );
if ( testPO.getPrice() != null ) {
testBO.setPrice( testPO.getPrice().toString() );
}
if ( testPO.getCreteTime() != null ) {
testBO.setCreteTime( new SimpleDateFormat().format( testPO.getCreteTime() ) );
}
return testBO;
}
@Override
public TestBOS toBOS(TestPOS testPOS) {
if ( testPOS == null ) {
return null;
}
TestBOS testBOS = new TestBOS();
if ( testBOS.getList() != null ) {
List<TestBO> list = testPOListToTestBOList( testPOS.getList() );
if ( list != null ) {
testBOS.getList().addAll( list );
}
}
return testBOS;
}
protected List<TestBO> testPOListToTestBOList(List<TestPO> list) {
if ( list == null ) {
return null;
}
List<TestBO> list1 = new ArrayList<TestBO>( list.size() );
for ( TestPO testPO : list ) {
list1.add( toBO( testPO ) );
}
return list1;
}
}
testBOS.getList().addAll( list )先getList在addAll。
最后看一下集合对象存在的情况。使用CollectionMappingStrategy.TARGET_IMMUTABLE策略。
@Data
public class TestPOS {
private List<TestPO> list;
}
@Data
public class TestBOS {
private List<TestBO> list;
}
@Mapper(collectionMappingStrategy = CollectionMappingStrategy.TARGET_IMMUTABLE)
public interface TestMapper {
TestBO toBO(TestPO testPO);
void toBOS(TestPOS testPOS, @MappingTarget TestBOS testBOS);
}
@Component
public class TestMapperImpl implements TestMapper {
@Override
public TestBO toBO(TestPO testPO) {
if ( testPO == null ) {
return null;
}
TestBO testBO = new TestBO();
testBO.setId( testPO.getId() );
testBO.setName( testPO.getName() );
if ( testPO.getPrice() != null ) {
testBO.setPrice( testPO.getPrice().toString() );
}
if ( testPO.getCreteTime() != null ) {
testBO.setCreteTime( new SimpleDateFormat().format( testPO.getCreteTime() ) );
}
return testBO;
}
@Override
public void toBOS(TestPOS testPOS, TestBOS testBOS) {
if ( testPOS == null ) {
return;
}
testBOS.setList( testPOListToTestBOList( testPOS.getList() ) );
}
protected List<TestBO> testPOListToTestBOList(List<TestPO> list) {
if ( list == null ) {
return null;
}
List<TestBO> list1 = new ArrayList<TestBO>( list.size() );
for ( TestPO testPO : list ) {
list1.add( toBO( testPO ) );
}
return list1;
}
}
直接使用testBOS.setList( testPOListToTestBOList( testPOS.getList() ) )。
使用默认集合策略
@Mapper
public interface TestMapper {
TestBO toBO(TestPO testPO);
void toBOS(TestPOS testPOS, @MappingTarget TestBOS testBOS);
}
@Component
public class TestMapperImpl implements TestMapper {
@Override
public TestBO toBO(TestPO testPO) {
if ( testPO == null ) {
return null;
}
TestBO testBO = new TestBO();
testBO.setId( testPO.getId() );
testBO.setName( testPO.getName() );
if ( testPO.getPrice() != null ) {
testBO.setPrice( testPO.getPrice().toString() );
}
if ( testPO.getCreteTime() != null ) {
testBO.setCreteTime( new SimpleDateFormat().format( testPO.getCreteTime() ) );
}
return testBO;
}
@Override
public void toBOS(TestPOS testPOS, TestBOS testBOS) {
if ( testPOS == null ) {
return;
}
if ( testBOS.getList() != null ) {
List<TestBO> list = testPOListToTestBOList( testPOS.getList() );
if ( list != null ) {
testBOS.getList().clear();
testBOS.getList().addAll( list );
}
else {
testBOS.setList( null );
}
}
else {
List<TestBO> list = testPOListToTestBOList( testPOS.getList() );
if ( list != null ) {
testBOS.setList( list );
}
}
}
protected List<TestBO> testPOListToTestBOList(List<TestPO> list) {
if ( list == null ) {
return null;
}
List<TestBO> list1 = new ArrayList<TestBO>( list.size() );
for ( TestPO testPO : list ) {
list1.add( toBO( testPO ) );
}
return list1;
}
}
先清除了目标集合testBOS.getList().clear(),再testBOS.getList().addAll( list )。
4.5、*集合属性映射
4.5.1、手动创建add方法
在1.7中介绍过对象属性值和getter/setter方法的匹配规则,这里在介绍下List属性字段名的映射规则。
public class TestBOS {
private List<TestBO> oneTest_;
public List<TestBO> getOneTestList() {
return oneTest_;
}
public void addOneTest(TestBO testBO) {
oneTest_.add(testBO);
}
}
这里不使用lombok,手动编写get、add方法。
@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED)
public interface TestMapper {
@Mapping(target = "oneTest_", source = "tests")
TestBOS toBean(TestPOS testPO);
}
@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED)
public interface TestMapper {
@Mapping(target = "oneTest", source = "tests")
TestBOS toBean(TestPOS testPO);
}
以上编译后的实现类会是什么样呢?答案是编译报错。
这里都提示了“oneTestList”的属性名。
@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED)
public interface TestMapper {
@Mapping(target = "oneTestList", source = "tests")
TestBOS toBean(TestPOS testPO);
}
@Component
public class TestMapperImpl implements TestMapper {
@Override
public TestBOS toBean(TestPOS testPO) {
if ( testPO == null ) {
return null;
}
TestBOS testBOS = new TestBOS();
if ( testPO.getTests() != null ) {
for ( TestPO test : testPO.getTests() ) {
testBOS.addOneTest( testPOToTestBO( test ) );
}
}
return testBOS;
}
protected TestBO testPOToTestBO(TestPO testPO) {
if ( testPO == null ) {
return null;
}
TestBO testBO = new TestBO();
testBO.setId( testPO.getId() );
testBO.setName( testPO.getName() );
if ( testPO.getPrice() != null ) {
testBO.setPrice( testPO.getPrice().toString() );
}
if ( testPO.getCreateTime() != null ) {
testBO.setCreateTime( new SimpleDateFormat().format( testPO.getCreateTime() ) );
}
return testBO;
}
}
修改属性为“oneTestList”,可以正确编译,testBOS.addOneTest( testPOToTestBO( test ) ),集合的映射策略是ADDER_PREFERRED,所以调用了add方法。
4.5.2、getter和adder类型不同
public class TestBOS {
private List<Integer> oneTest_;
public List<TestBO> getOneTestList() {
return new ArrayList<>();
}
public void addOneTest(Integer integer) {
oneTest_.add(integer);
}
}
这个例子将oneTest_的类型改成List<Integer>,getOneTestList()方法还是返回List<TestBO>,addOneTest方法的参数改为Integer。结果如下。
@Component
public class TestMapperImpl implements TestMapper {
@Override
public TestBOS toBean(TestPOS testPO) {
if ( testPO == null ) {
return null;
}
TestBOS testBOS = new TestBOS();
if ( testBOS.getOneTestList() != null ) {
List<TestBO> list = testPOListToTestBOList( testPO.getTests() );
if ( list != null ) {
testBOS.getOneTestList().addAll( list );
}
}
return testBOS;
}
protected TestBO testPOToTestBO(TestPO testPO) {
if ( testPO == null ) {
return null;
}
TestBO testBO = new TestBO();
testBO.setId( testPO.getId() );
testBO.setName( testPO.getName() );
if ( testPO.getPrice() != null ) {
testBO.setPrice( testPO.getPrice().toString() );
}
if ( testPO.getCreateTime() != null ) {
testBO.setCreateTime( new SimpleDateFormat().format( testPO.getCreateTime() ) );
}
return testBO;
}
protected List<TestBO> testPOListToTestBOList(List<TestPO> list) {
if ( list == null ) {
return null;
}
List<TestBO> list1 = new ArrayList<TestBO>( list.size() );
for ( TestPO testPO : list ) {
list1.add( testPOToTestBO( testPO ) );
}
return list1;
}
}
集合的映射调用的是testBOS.getOneTestList().addAll( list )。推测要先能匹配add方法,add方法的参数类型要和get方法返回List中泛型类型一致。
再修改下。
public class TestBOS {
private List<Integer> oneTest_;
public List<TestBO> getOneTestList() {
return new ArrayList<>();
}
public void addOneTest(TestBO testBO) {
oneTest_.add(testBO.getId().intValue());
}
}
@Component
public class TestMapperImpl implements TestMapper {
@Override
public TestBOS toBean(TestPOS testPO) {
if ( testPO == null ) {
return null;
}
TestBOS testBOS = new TestBOS();
if ( testPO.getTests() != null ) {
for ( TestPO test : testPO.getTests() ) {
testBOS.addOneTest( testPOToTestBO( test ) );
}
}
return testBOS;
}
protected TestBO testPOToTestBO(TestPO testPO) {
if ( testPO == null ) {
return null;
}
TestBO testBO = new TestBO();
testBO.setId( testPO.getId() );
testBO.setName( testPO.getName() );
if ( testPO.getPrice() != null ) {
testBO.setPrice( testPO.getPrice().toString() );
}
if ( testPO.getCreateTime() != null ) {
testBO.setCreateTime( new SimpleDateFormat().format( testPO.getCreateTime() ) );
}
return testBO;
}
}
这样就是调用了add方法testBOS.addOneTest( testPOToTestBO( test ) )。
4.5.3、多个相同参数列表的add方法
public class TestBOS {
private List<TestBO> oneTest;
public List<TestBO> getOneTestList() {
return oneTest;
}
public void addOneTest(TestBO testBO) {
oneTest.add(testBO);
}
public void addTwoTest(TestBO testBO) {
oneTest.add(testBO);
}
}
@Component
public class TestMapperImpl implements TestMapper {
@Override
public TestBOS toBean(TestPOS testPO) {
if ( testPO == null ) {
return null;
}
TestBOS testBOS = new TestBOS();
if ( testBOS.getOneTestList() != null ) {
List<TestBO> list = testPOListToTestBOList( testPO.getTests() );
if ( list != null ) {
testBOS.getOneTestList().addAll( list );
}
}
return testBOS;
}
protected TestBO testPOToTestBO(TestPO testPO) {
if ( testPO == null ) {
return null;
}
TestBO testBO = new TestBO();
testBO.setId( testPO.getId() );
testBO.setName( testPO.getName() );
if ( testPO.getPrice() != null ) {
testBO.setPrice( testPO.getPrice().toString() );
}
if ( testPO.getCreateTime() != null ) {
testBO.setCreateTime( new SimpleDateFormat().format( testPO.getCreateTime() ) );
}
return testBO;
}
protected List<TestBO> testPOListToTestBOList(List<TestPO> list) {
if ( list == null ) {
return null;
}
List<TestBO> list1 = new ArrayList<TestBO>( list.size() );
for ( TestPO testPO : list ) {
list1.add( testPOToTestBO( testPO ) );
}
return list1;
}
}
如果找到多个相同参数列表的add方法,则会因为无法确认匹配哪一个就会调用get方法了testBOS.getOneTestList().addAll( list )。
介绍这个主要是为了给第11章铺垫。