JPA使用包装类DTO完成属性的映射封装

环境准备:

SpringBoot、JPA相关依赖,lombok插件及依赖、easy-poi依赖

数据库实体类:
1.User类:

  • 注解@Excel 用于easy-poi声明表格中的列
  • User和Order是一对多的关系,级联类型设置为所有,@orphanRemoval = true 表示删除某条User数据时会删除Order中对应user_id的数据
@Entity
@Data
@Table(name = "user", schema = "mydb", catalog = "")
public class User implements Serializable {
    @Id
    @Column(name = "id", nullable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Excel(name = "用户id", orderNum = "0", width = 15)
    private Integer id;

    @Basic
    @Column(name = "username", nullable = true, length = 255)
    @Excel(name = "用户名", orderNum = "0", width = 15)
    private String username;

    @Basic
    @Column(name = "password", nullable = true, length = 255)
    @Excel(name = "密码", orderNum = "0", width = 15)
    private String password;

    @OneToMany(cascade={CascadeType.ALL},orphanRemoval = true)
    @JoinColumn(name="user_id")
    @Transient
    private List<Order> orderList;
}

2:Order类:

@Entity
@Data
@Table(name = "order", schema = "mydb", catalog = "")
public class Order implements Serializable {

    @Id
    @Column(name = "id", nullable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Basic
    @Column(name = "user_id", nullable = true, length = 255)
    private Integer userId;

    @Basic
    @Column(name = "order_time", nullable = true, length = 255)
    private Date orderTime;
}

包装类Vo / DTO:
Date必须是java.util.Date,使用java.sql.Date报错:找不到对应构造方法(未找到原因,数据库字段类型为datetime)

  • @NoArgsConstructor:无参构造器
  • @AllArgsConstructor:所有属性的构造器(注意顺序)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserVo implements Serializable {
    private Integer id;
    private String username;
    private String password;
    // 添加的属性
    private Date orderTime;
}

方法一:使用HQL直接返回Page< UserVo>

Dao接口:

  • 注意构造器的参数顺序要一致,使用HQL查询时均使用实体类和其对应属性名
  • 此处分页使用Pageable,直接作为入参即可。不需要分页时可直接返回List< UserVo >
@Repository
public interface UserDao extends JpaRepository<User, Integer> {
    
    @Query(value = "select new com.stee.customermanagement.vo.UserVo(a.id,a.username,a.password,b.orderTime) " +
            "from User a join Order b on a.id = b.userId and b.orderTime like concat('%',?1,'%')"
            ,countQuery = "select count(1) from from User a join Order b on a.id = b.userId and b.orderTime like concat('%',?1,'%')")
    Page<UserVo> findAllByHQL(Date orderTime, Pageable pageable);
}

Service:

省略Serive接口、ListResp返回类

@Service
@Slf4j
public class UserServiceImpl {
    @Autowired
    UserDao userDao;

    @Override
    public ListResp findAllByHQL(Date orderTime , Pageable pageable) {
        ListResp listResp = new ListResp();
        try {
            Page<UserVo> userVoPage = userDao.findAllByHQL(orderTime,pageable);
            listResp.setData(userVoPage.getContent());
            listResp.setCount(userVoPage.getTotalElements());
            listResp.setCode(ResCode.R10003001.getCode());
        } catch (Exception e){
            log.error("the error of findAllByHQL() : ", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            listResp.setCode(ResCode.R30103001.getCode());
        }
        return listResp;
    }
}

方法二:使用原生SQL返回List<Object[]>

Date必须是java.util.Date,使用java.sql.Date报错:找不到对应构造方法(数据库字段类型为datetime)

  • nativeQuery = true 表示开启原生SQL查询
  • 查询字段别名需要与实体类中字段一一对应
  • 此处分页使用limit操作,未测试使用 ORDER BY ?#{#pageable} 是否能配合Pageable完成分页。若可以则使用Page< Object[ ]>接收返回数据

Dao接口:

@Repository
public interface UserDao extends JpaRepository<User, Integer> {

    @Query(value = "select a.id as id, a.username as username , a.password as password , b.order_time as b.orderTime " +
            " from user a, order b where a.id = b.user_id and b.order_time like concat('%',?1,'%') limit ?2,?3"
            ,nativeQuery = true)
    List<Object[]> findAll(Date orderTime, Integer startIndex , Integer perSize);
}

Service:

省略Serive接口

  • 转换成dto的方法一:将objects中的所有参数强转为对应类型,传递到dto的构造器中;dto对象定义好对应的构造器
  • 方法二:通过反射的方法简化dto的转化步骤
@Service
@Slf4j
public class UserServiceImpl {
    @Autowired
    UserDao userDao;

    @Override
    public ListResp findAll(Date orderTime,Pageable pageable) {
        ListResp listResp = new ListResp();
        try {
            Integer startIndex = pageable.getPageNumber()*pageable.getPageSize();
            List<Object[]> objects = userDao.findAll(orderTime,startIndex,pageable.getPageSize());
            // 省略用于分页的count数据总条数
            List<UserVo> voList = new ArrayList<>();
            for(Object[] obj : objects){
                UserVo vo = new UserVo((Integer) obj[0],(String)obj[1],(String)obj[2],(Date)obj[3]);
                voList.add(vo);
            }
            listResp.setData(voList);
        } catch (Exception e){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return listResp;
    }
}
发布了4 篇原创文章 · 获赞 0 · 访问量 80

猜你喜欢

转载自blog.csdn.net/weixin_43958996/article/details/103693995