Java中什么是DTO,什么场景下使用DTO,怎么使用DTO。

文章展示了在JavaSpring环境下,如何使用DTO(DataTransferObject)来处理涉及多个表的业务操作。DTO用于封装不同表的数据,如菜品和口味信息。在新增、查询和更新菜品时,通过DTO对象进行数据库交互,包括保存、查询和更新菜品及关联的口味信息。

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

DTO是数据传输对象(DTO)(Data Transfer Object)。

比如同时操作一个业务但是这个业务涉及到两个表,这时可以再新建一个DTO表,继承与需要使用的表再额外加上这个表里面不含的数据。

比如菜品表,菜品不但需要菜品的信息还需要口味的信息,一个菜品表不够用,可以做个菜品表DTO,继承于菜品表但是里面也有口味表的数据。

import com.zhengdidi.reggie.entity.Dish;
import com.zhengdidi.reggie.entity.DishFlavor;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;

@Data
public class DishDto extends Dish {

    //菜品对应的口味数据
    private List<DishFlavor> flavors = new ArrayList<>();

    private String categoryName;

    private Integer copies;
}

在增删改查时调用这个DTO对象。

package com.zhengdidi.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhengdidi.reggie.dto.DishDto;
import com.zhengdidi.reggie.entity.Dish;
import com.zhengdidi.reggie.entity.DishFlavor;
import com.zhengdidi.reggie.mapper.DishMapper;
import com.zhengdidi.reggie.service.DishFlavorService;
import com.zhengdidi.reggie.service.DishService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class DishServiceImpl extends ServiceImpl<DishMapper,Dish> implements DishService {

    @Autowired
    private DishFlavorService dishFlavorService;

    /**
     * 新增菜品,同时保存对应的口味数据
     * @param dishDto
     */
    @Transactional
    public void saveWithFlavor(DishDto dishDto) {
        //保存菜品的基本信息到菜品表dish
        this.save(dishDto);

        Long dishId = dishDto.getId();//菜品id

        //菜品口味
        List<DishFlavor> flavors = dishDto.getFlavors();
        flavors = flavors.stream().map((item) -> {
            item.setDishId(dishId);
            return item;
        }).collect(Collectors.toList());

        //保存菜品口味数据到菜品口味表dish_flavor
        dishFlavorService.saveBatch(flavors);

    }

    /**
     * 根据id查询菜品信息和对应的口味信息
     * @param id
     * @return
     */
    public DishDto getByIdWithFlavor(Long id) {
        //查询菜品基本信息,从dish表查询
        Dish dish = this.getById(id);

        DishDto dishDto = new DishDto();
        BeanUtils.copyProperties(dish,dishDto);

        //查询当前菜品对应的口味信息,从dish_flavor表查询
        LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DishFlavor::getDishId,dish.getId());
        List<DishFlavor> flavors = dishFlavorService.list(queryWrapper);
        dishDto.setFlavors(flavors);

        return dishDto;
    }

    @Override
    @Transactional
    public void updateWithFlavor(DishDto dishDto) {
        //更新dish表基本信息
        this.updateById(dishDto);

        //清理当前菜品对应口味数据---dish_flavor表的delete操作
        LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(DishFlavor::getDishId,dishDto.getId());

        dishFlavorService.remove(queryWrapper);

        //添加当前提交过来的口味数据---dish_flavor表的insert操作
        List<DishFlavor> flavors = dishDto.getFlavors();

        flavors = flavors.stream().map((item) -> {
            item.setDishId(dishDto.getId());
            return item;
        }).collect(Collectors.toList());

        dishFlavorService.saveBatch(flavors);
    }
}

<think>好的,用户想了解JavaDTO的用法和示例。首先,我需要回忆一下DTO的基本概念。DTO是Data Transfer Object的缩写,主要用于不同层之间传输数据,比如从DAO层到Service层,或者从Service层到Controller层。DTO通常包含私有属性和对应的getter、setter方法,遵循JavaBean规范。 接下来,用户可能需要具体的示例来说明如何创建DTO。比如定义一个UserDTO类,包含用户名、邮箱等属性,并提供getter和setter方法。这样用户可以看到基本的DTO结构。 然后,用户可能关心DTO在不同层之间的转换。比如如何将实体类转换为DTO,或者反过来。这里需要提到工具类,如ModelMapper或MapStruct,它们可以简化转换过程。例如,使用ModelMapper的map方法将PostDTO转换为Post实体类,或者使用Spring的BeanUtils.copyProperties进行属性拷贝。 另外,用户可能想知道DTO的实际应用场景,比如在Spring Boot中接收请求参数,或者返回响应数据。这时候可以举例说明在Controller层使用DTO作为参数,避免直接暴露实体类的结构,增强安全性。 还需要注意DTO的验证,比如结合JSR-380注解进行数据校验,如@NotBlank、@Email等,确保传入的数据符合要求。同时,DTO还可以用于定制返回给前端的数据结构,过滤掉不必要的字段。 用户可能还会遇到集合转换的问题,比如将实体列表转换为DTO列表,这时候可以展示使用Stream API和map方法进行批量转换的例子。 最后,要确保回答结构清晰,分点说明,每个部分都有代码示例,并引用提供的参考资料来支持内容。同时,生成相关问题,帮助用户进一步学习相关内容。</think>### Java DTO使用方法及示例 #### 1. **DTO基础定义** DTO(Data Transfer Object)是用于在不同层之间传输数据的对象,通常包含私有属性和对应的`get/set`方法,遵循JavaBean规范[^1]。 **示例代码**: ```java public class UserDTO { private String username; private String email; // Getter/Setter方法 public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } } ``` #### 2. **DTO与实体类的转换** DTO与数据库实体(Entity)需通过工具类或框架转换,避免直接暴露实体结构[^3][^4]。 **示例**:使用`ModelMapper`转换: ```java // 实体类到DTO User userEntity = userRepository.findById(1L); UserDTO userDTO = modelMapper.map(userEntity, UserDTO.class); // DTO到实体类 User newUser = modelMapper.map(userDTO, User.class); userRepository.save(newUser); ``` #### 3. **DTO在Spring Boot中的应用** 在Controller层接收请求参数或返回响应时使用DTO: **示例**:接收HTTP请求参数并验证: ```java @PostMapping("/users") public ResponseEntity<?> createUser(@Valid @RequestBody UserDTO userDTO) { User user = modelMapper.map(userDTO, User.class); userService.save(user); return ResponseEntity.ok("用户创建成功"); } ``` #### 4. **DTO的字段过滤与定制** DTO可定制返回字段,隐藏敏感信息(如密码): **示例**:仅返回用户名和注册时间: ```java public class UserResponseDTO { private String username; private LocalDateTime createTime; // 省略其他字段 } ``` #### 5. **集合类型的DTO转换** 使用Stream API批量转换实体列表到DTO列表: **示例**: ```java List<UserDTO> userDTOList = userList.stream() .map(user -> modelMapper.map(user, UserDTO.class)) .collect(Collectors.toList()); ``` #### 6. **DTO的验证与注解** 通过JSR-380注解实现数据校验[^3]: **示例**: ```java public class LoginDTO { @NotBlank(message = "邮箱不能为空") @Email private String email; @Size(min = 6, max = 20, message = "密码长度需6-20位") private String password; } ``` #### 7. **工具类手动转换** 若无需框架,可手动编写转换逻辑[^2]: **示例**: ```java public class UserConverter { public static UserDTO toDTO(User user) { UserDTO dto = new UserDTO(); dto.setUsername(user.getName()); dto.setEmail(user.getEmail()); return dto; } } ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值