环境准备:
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;
}
}