SpringBoot项目中ModelMapper配置以及使用

本文介绍了ModelMapper在SpringBoot项目中的配置与使用方法,包括如何引入依赖、配置转换规则及在Controller中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目中对象与对象赋值转换使用的频率非常的高,比如数据库表实体对象(Entity)与业务类对象(Model)之间的赋值传递,或者模型对象(Model)与视图对象(ViewModel)之间的赋值传递。如果我们一个一个字段的赋值,将是非常繁琐并且毫无价值的重复工作,此时虽然我们可以自己通过反射提取个公共的方法来处理,但是更高效的方式是查看是否有第三方已经提供了比较成熟稳定的工具包,避免重复造轮子的工作。

在C#中我们一般使用AutoMapper作为对象转换工具(AutoMapper配置使用参考:https://blog.youkuaiyun.com/fly_duck/article/details/102605046),Java中也有类似的转换工具,比如:Dozer,Orika,MapStruct,JMapper,ModelMapper以及BeanUtils等,都可以实现对象之间的转换。 本问主要介绍SpringBoot项目中ModelMapper的配置以及使用,使用ModelMapper我们可以快速的解决对象与对象之间的映射转换。官方的介绍如下:

The goal of ModelMapper is to make object mapping easy, by automatically determining how one object model maps to another, based on conventions, in the same way that a human would - while providing a simple, refactoring-safe API for handling specific use cases.

 ModelMapper的Github地址: https://github.com/modelmapper/modelmapper,官方地址:http://modelmapper.org/,官方使用文档:http://modelmapper.org/user-manual/

pom.xml配置

首先在pom.xml引入ModelMapper依赖:

        <!-- https://mvnrepository.com/artifact/org.modelmapper/modelmapper -->
        <dependency>
            <groupId>org.modelmapper</groupId>
            <artifactId>modelmapper</artifactId>
            <version>2.3.9</version>
        </dependency>

 ModelMapper配置

在SpringBoot项目中将ModelMapper配置好后注册为JavaBean交给Spring来管理,使用的时候直接通过注解获取ModelMapper实例来对对象进行转换。项目中强烈建议将setFullTypeMatchingRequired设置为true使用完全匹配模式,将setMatchingStrategy设置为MatchingStrategies.STRICT使用严格匹配模式,避免字段名缺失被相似字段转换错误的情况。

package com.flyduck.mybatis.config;

import com.flyduck.mybatis.entity.User;
import com.flyduck.mybatis.model.UserModel;
import org.modelmapper.AbstractConverter;
import org.modelmapper.Converter;
import org.modelmapper.ModelMapper;
import org.modelmapper.convention.MatchingStrategies;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.text.SimpleDateFormat;
import java.util.Date;


@Configuration
public class ModelMapperConfig {

    private Converter<Date, String> dateToStringConverter = new AbstractConverter<Date, String>() {
        @Override
        protected String convert(Date date) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

            return date == null ? null : simpleDateFormat.format(date);
        }
    };

    /**
     * 将ModelMapper注册到Spring中
     * 可以添加一些定制化的配置,官方文档:http://modelmapper.org/user-manual/property-mapping/
     *
     * @author flyduck
     * @date 2020/11/25 21:35
     * @param []
     * @return org.modelmapper.ModelMapper
    */
    @Bean
    public ModelMapper modelMapper() {
        ModelMapper modelMapper = new ModelMapper();

        // 官方配置说明: http://modelmapper.org/user-manual/configuration/
        // 完全匹配
        modelMapper.getConfiguration().setFullTypeMatchingRequired(true);

        // 匹配策略使用严格模式
        modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);

        modelMapper.addConverter(dateToStringConverter);

        configureUser(modelMapper);

        return modelMapper;
    }

    private void configureUser(ModelMapper modelMapper) {
        modelMapper.typeMap(UserModel.class, User.class)
                .addMappings(mapper -> mapper.skip(User::setPassword))
                .addMappings(mapper -> mapper.skip(User::setCreateTime))
                .addMappings(mapper -> mapper.skip(User::setUpdateTime))
                .addMappings(mapper -> mapper.map(UserModel::getName, User::setRealName));

        modelMapper.typeMap(User.class, UserModel.class)
                .addMappings(mapper -> mapper.skip(UserModel::setPassword))
                .addMappings(mapper -> mapper.map(User::getRealName, UserModel::setName));
//                .addMappings(mapper -> mapper.using(dateToStringConverter).map(User::getCreateTime, UserModel::setCreateTime))
//                .addMappings(mapper -> mapper.using(dateToStringConverter).map(User::getUpdateTime, UserModel::setUpdateTime));
    }
}

默认情况下,ModelMapper会通过反射按照字段名自动进行对象转换。但是一些特殊情况,需要我们自定义配置,示例配置中我们单独为User和UserModel类之间的转换做了一些常用的配置。 当某个字段不需要转换可以通过skip来设置,当字段名不一致可以通过map来设置,当字段值需要处理后再转换可以通过Converter结合map来设置。User类的定义:

public class User implements Serializable {
    private Long id;
    private String code;
    private Date createTime;
    private Date updateTime;
    private Boolean isDelete;
    private String userName;
    private String email;
    private String phoneNumber;
    private String password;
    private String realName;
    private String nickName;
    private String avatar;

    // 省略getter, setter方法
}

UserModel的定义:

public class UserModel {
    private Long id;
    private String createTime;
    private String updateTime;
    private String userName;
    private String password;
    private String email;
    private String phoneNumber;
    private String name;
    private String nickName;
    private String avatar;

    // 省略 getter,setter方法
}

对象转换

在Controller控制器中,通过@Autowired注解得到ModelMapper实例,然后直接通过modelMapper.map(user, UserModel.class)转换得到VO层的UserModel对象,然后直接传给前端接口。

@RestController
@RequestMapping("user")
public class UserController {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ModelMapper modelMapper;

    @GetMapping("{id}")
    public UserModel get(@PathVariable Long id) {
        User user  = userMapper.selectByPrimaryKey(id);

        if (user == null || user.getIsDelete()) {
            return null;
        }

        UserModel userModel = modelMapper.map(user, UserModel.class);

        return userModel;
    }
}

总结

以上就是SpringBoot项目中ModelMapper的常规使用,示例源码:https://gitee.com/flyduck128/springboot-demo/tree/master/flyduck-mybatis。使用ModelMapper可以大大提高开发人员对于对象转换的开发效率,特别适用于微服务中对象之间的转换。对于ModelMapper的详细配置以及高级使用可以参考官方文档。就如开篇所说的Java中对象转换的工具很多,ModelMapper常规使用配置简单,上手容易,同时也提供一些高级用法,同时由于使用的反射进行转换所以效率不是很高,对于效率要求不高的项目推荐使用ModelMapper。

拓展

国外朋友专门对Dozer,Orika,MapStruct,JMapper和ModelMapper进行了性能测试,测试地址:https://www.baeldung.com/java-performance-mapping-frameworks。测试结果为JMapper和MapStruct性能表现最好。如下是测试结果的部分截图:

 

 

好的,下面是一个简单的Spring Boot项目实战: 1. 创建一个Spring Boot项目 首先,你需要在你的IDE中创建一个Spring Boot项目。可以使用Spring Initializr进行创建,或者手动创建一个Maven或Gradle项目并添加必要的依赖。 2. 添加依赖 在pom.xml中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--添加JDBC依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!--添加Thymeleaf模板依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!--添加MySQL数据库驱动依赖--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--添加MyBatis依赖--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.4</version> </dependency> ``` 3. 配置数据库 在application.properties中配置数据库连接信息: ```properties spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false spring.datasource.username=root spring.datasource.password=root ``` 4. 创建实体类 在项目中创建一个实体类,并使用JPA注解进行字段映射,例如: ```java @Entity @Table(name = "user") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private Integer age; // getter和setter方法 } ``` 5. 创建Mapper接口 在项目中创建一个Mapper接口,并使用MyBatis注解进行SQL语句映射,例如: ```java @Mapper public interface UserMapper { @Select("SELECT * FROM user WHERE id = #{id}") User findById(Long id); @Insert("INSERT INTO user(name, age) VALUES(#{name}, #{age})") void insert(User user); @Update("UPDATE user SET name=#{name}, age=#{age} WHERE id=#{id}") void update(User user); @Delete("DELETE FROM user WHERE id=#{id}") void delete(Long id); } ``` 6. 创建Service层 在项目中创建一个Service层,调用Mapper层完成业务逻辑,例如: ```java @Service public class UserService { @Autowired private UserMapper userMapper; public User findById(Long id) { return userMapper.findById(id); } public void insert(User user) { userMapper.insert(user); } public void update(User user) { userMapper.update(user); } public void delete(Long id) { userMapper.delete(id); } } ``` 7. 创建Controller层 在项目中创建一个Controller层,处理HTTP请求和响应,例如: ```java @Controller public class UserController { @Autowired private UserService userService; @GetMapping("/user/{id}") public String findById(@PathVariable Long id, Model model) { User user = userService.findById(id); model.addAttribute("user", user); return "user"; } @GetMapping("/user/add") public String add() { return "add"; } @PostMapping("/user/save") public String save(User user) { userService.insert(user); return "redirect:/"; } @GetMapping("/user/edit/{id}") public String edit(@PathVariable Long id, Model model) { User user = userService.findById(id); model.addAttribute("user", user); return "edit"; } @PostMapping("/user/update") public String update(User user) { userService.update(user); return "redirect:/"; } @GetMapping("/user/delete/{id}") public String delete(@PathVariable Long id) { userService.delete(id); return "redirect:/"; } } ``` 8. 创建视图 在项目中创建视图文件,例如: user.html: ```html <!DOCTYPE html> <html> <head> <title>User</title> </head> <body> <h1>User</h1> <table> <tr> <th>ID</th> <th>Name</th> <th>Age</th> </tr> <tr> <td th:text="${user.id}"></td> <td th:text="${user.name}"></td> <td th:text="${user.age}"></td> </tr> </table> <a href="/">Back</a> </body> </html> ``` add.html: ```html <!DOCTYPE html> <html> <head> <title>Add User</title> </head> <body> <h1>Add User</h1> <form action="/user/save" method="post"> <label for="name">Name:</label> <input type="text" id="name" name="name"><br><br> <label for="age">Age:</label> <input type="text" id="age" name="age"><br><br> <input type="submit" value="Save"> </form> <a href="/">Back</a> </body> </html> ``` edit.html: ```html <!DOCTYPE html> <html> <head> <title>Edit User</title> </head> <body> <h1>Edit User</h1> <form action="/user/update" method="post"> <input type="hidden" id="id" name="id" th:value="${user.id}"> <label for="name">Name:</label> <input type="text" id="name" name="name" th:value="${user.name}"><br><br> <label for="age">Age:</label> <input type="text" id="age" name="age" th:value="${user.age}"><br><br> <input type="submit" value="Save"> </form> <a href="/">Back</a> </body> </html> ``` 9. 启动应用 最后,你可以启动应用并测试它是否正常工作。在浏览器中访问http://localhost:8080/,你应该能够看到一个用户列表。你还可以添加、编辑和删除用户。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值