源码:https://gitee.com/cao_wen_bin/test
最近在公司遇到了这样一个为题,前端传过来的是一个List<Manager>,往数据库中保存到时候是String,这个String使用谷歌的json转化器。
当查询的时候在将这个数据库中String的数据以List<Manager>的形式返回给前端。
使用mapstruct中在怎样将String转化为List。在此记录一下。
1.引入依赖
xml
<!--mapstruct-->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.5.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.5.Final</version>
</dependency>
2.PO->DTO
java
package com.cao.pojo;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true)
@ToString
public class Manager {
private String name;
private String code;
}
需求是将PO转化为DTO,但是PO中的类型是String,而DTO中的类型是List
ManagerPO中的acctManagerList属性是String
java
package com.cao.po;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true)
@ToString
public class ManagerPO {
private Long id;
private String acctManagerListString;
}
ManagerDTO中的acctManagerList属性是List<Manager>
java
package com.cao.dto;
import com.cao.pojo.Manager;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.util.List;
@Data
@Accessors(chain = true)
@ToString
public class ManagerDTO {
private Long id;
private List<Manager> acctManagerList;
}
3.编写转换代码
因为我是使用的Gson把List<Manager>转换为String,所以从String转换为List<Manager>也要用相同的json转换,不然会出现异常
java
import com.cao.dto.ManagerDTO;
import com.cao.po.ManagerPO;
import com.cao.pojo.Manager;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.apache.commons.lang3.StringUtils;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface ManagerBeanConvert {
ManagerBeanConvert INSTANCE = Mappers.getMapper(ManagerBeanConvert.class);
@Mapping(target = "id", source = "id")
@Mapping(target = "acctManagerList", expression = "java(MapStruct.strToList(managerPO.getAcctManagerListString()))")
ManagerDTO po2Dto(ManagerPO managerPO);
@Mapping(target = "id", source = "id")
@Mapping(target = "acctManagerListString", expression = "java(MapStruct.listToStr(managerDTO.getAcctManagerList()))")
ManagerPO dto2Po(ManagerDTO managerDTO);
class MapStruct {
/**
* po中的String转为dto中的list
*/
public static List<Manager> strToList(String acctManagerListString) {
if (StringUtils.isNotEmpty(acctManagerListString)) {
// 将po中的acctManagerListString用Gson转换成为list(必须和list转String使用相同的转换器)
List<Manager> managerList = new Gson().fromJson(acctManagerListString, new TypeToken<List<Manager>>() {}.getType());
return managerList;
}
return null;
}
/**
* dto中的list转为po中的String
*/
public static String listToStr(List<Manager> managerList) {
if (!CollectionUtils.isEmpty(managerList)) {
// 将dto中的acctManagerList用Gson转换成为String(必须和String转list使用相同的转换器)
String managerListString = new Gson().toJson(managerList);
return managerListString;
}
return null;
}
}
}
4.测试代码和测试
java
import com.cao.beanconvert.ManagerBeanConvert;
import com.cao.dto.ManagerDTO;
import com.cao.po.ManagerPO;
import com.cao.pojo.Manager;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import java.util.*;
@Slf4j
public class BeanConvertTest {
public static void main(String[] args) {
// po中的String转为dto中的list
poString2DtoList();
System.out.println("=====================");
// dto中的list转为po中的String
dtoList2PoString();
}
private static void dtoList2PoString() {
List<Manager> managerList = new ArrayList<>();
managerList.add(new Manager().setCode("0001").setName("管理员1号"));
managerList.add(new Manager().setCode("0002").setName("管理员2号"));
ManagerDTO managerDTO = new ManagerDTO().setId(3L).setAcctManagerList(managerList);
log.info("managerDTO是: {}",managerDTO);
ManagerPO managerPO = ManagerBeanConvert.INSTANCE.dto2Po(managerDTO);
log.info("managerDTO转换为managerPO结果是: {}",managerPO);
}
private static void poString2DtoList() {
//设置List<Manager>
List<Manager> managerList = new ArrayList<>();
managerList.add(new Manager().setCode("0001").setName("管理员1号"));
managerList.add(new Manager().setCode("0002").setName("管理员2号"));
//使用Gson将list转换成String
String managerListString = new Gson().toJson(managerList);
ManagerPO managerPO = new ManagerPO();
managerPO.setId(1L).setAcctManagerListString(managerListString);
log.info("managerPO是:{}",managerPO);
ManagerDTO managerDTO = ManagerBeanConvert.INSTANCE.po2Dto(managerPO);
log.info("managerPO转换为managerDTO结果是: {}",managerDTO);
}
}
5.改造
虽然上面的写法已经可以满足需求了,但是在ManagerBeanConvert接口中写内部类的话不规范,所以要修改。
新建一个专门的用于类型属性的转换的类AttributeConvertUtil,将接口中的内部类挪到这个新建的类中,并在方法上面加上@Named("别名")
java
import com.cao.pojo.Manager;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.apache.commons.lang3.StringUtils;
import org.mapstruct.Named;
import org.springframework.util.CollectionUtils;
import java.util.List;
public class AttributeConvertUtil {
/**
* po中的String转为dto中的list
*/
@Named("strToList")
public List<Manager> strToList(String acctManagerListString) {
if (StringUtils.isNotEmpty(acctManagerListString)) {
// 将po中的acctManagerListString用Gson转换成为list(必须和list转String使用相同的转换器)
List<Manager> managerList = new Gson().fromJson(acctManagerListString, new TypeToken<List<Manager>>() {
}.getType());
return managerList;
}
return null;
}
/**
* dto中的list转为po中的String
*/
@Named("listToStr")
public String listToStr(List<Manager> managerList) {
if (!CollectionUtils.isEmpty(managerList)) {
// 将dto中的acctManagerList用Gson转换成为String(必须和String转list使用相同的转换器)
String managerListString = new Gson().toJson(managerList);
return managerListString;
}
return null;
}
}
修改接口,
1.在@Mapper上引用我们的自定义转换代码类AttributeConvertUtil
2.使用qualifiedByName指定我们使用的自定义转换方法
java
import com.cao.dto.ManagerDTO;
import com.cao.po.ManagerPO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
@Mapper(uses = AttributeConvertUtil.class) //将自定义类引入进来
public interface ManagerBeanConvert {
ManagerBeanConvert INSTANCE = Mappers.getMapper(ManagerBeanConvert.class);
@Mapping(target = "id", source = "id")
@Mapping(target = "acctManagerList", source = "acctManagerListString", qualifiedByName = "strToList")// qualifiedByName的值和别名一样
ManagerDTO po2Dto(ManagerPO managerPO);
@Mapping(target = "id", source = "id")
@Mapping(target = "acctManagerListString", source = "acctManagerList", qualifiedByName = "listToStr") // qualifiedByName的值和别名一样
ManagerPO dto2Po(ManagerDTO managerDTO);
}