前言
今天用JPA又把之前的防疫物资项目重构了一遍,遇到很多问题,不过最终都解决了,JPA的学习之路还是很长...
遇到难题
1.联表查询(返回自定义实体类)
JPA确实很强大,简单的CRUD用的简直舒服~,但是今天在使用联表查询的时候,遇到了很棘手的问题。直接上代码。
@Entity
@Table(name = "material_record_info",)
public class MaterialRecordDO implements Serializable {
private static final long serialVersionUID = 1642587292218800992L;
    private int recordId;
    private Integer receiveNumber;
    private String receiveReason;
    private Date receiveDateTime;
    private int mId;
    private int uId;
get/set方法我就省略了,这是外键表物资记录表,其中的mId和uId是另外两张表的主键。但是最终想显示给用户的这样的:
public class MaterialRecordVO {
    private int recordId; //记录编号
    private int receiveNumber; // 领取数量
    private String receiveReason; //领取原因
    private Date receiveDateTime; //领取时间
    private String materialName; //防疫物资名称
    private String userRealName; //用户真实姓名
最终使用JPQL解决了问题,注意自定义实体类要有对应的有参构造函数,顺序也必须一样。
@Repository
public interface IMaterialRecordDAO extends JpaRepository<MaterialRecordDO, Integer>  {
    @Query("SELECT new co'm.apesource.epmrs_3.entity.MaterialRecordVO(a.recordId,a.receiveNumber,a.receiveReason,a.receiveDateTime,b.materialName,c.userRealName)" +
           "FROM MaterialRecordDO a " +
           "INNER JOIN MaterialInfo b ON a.mId = b.materialId" +
           "INNER JOIN UserInfo c ON a.uId = c.userId")
    List<MaterialRecordVO> listMaterialRecord();
2.联表动态查询(返回自定义实体类)
我看了看JpaspecificationExecutor实现动态查询的,看不太懂,而且好像不能返回自定义实体类,搞了几个小时,最终还是用MyBatis解决了(太香了...),一个项目既用MyBatis又用JPA是不是不好呢。。。
    // 按条件查询物资领用记录
    @Select("<script> " +
            "SELECT  record_id AS recordId,\n" +
            "               material_name AS materialName,\n" +
            "               user_real_name AS userRealName,\n" +
            "               receive_number AS receiveNumber,\n" +
            "               receive_reason AS receiveReason,\n" +
            "               receive_date_time AS receiveDateTime\n" +
            "        FROM material_record_info AS a\n" +
            "        INNER JOIN material_info AS b ON a.m_id = b.material_id\n" +
            "        INNER JOIN user_info AS c ON a.u_id = c.user_id\n" +
            "        <where>\n" +
            "           <if test='materialId != -1'>AND material_id = #{materialId}</if>\n" +
            "           <if test='userId != -1'>AND  user_id = #{userId}</if>\n" +
            "           <if test='receiveDateBegin != null and receiveDateEnd != null'>\n" +
            "               AND DATE_FORMAT(receive_date_time,'%Y-%m-%d') BETWEEN #{receiveDateBegin} AND #{receiveDateEnd}\n" +
            "           </if>\n" +
            "        </where>\n" +
            "        ORDER BY receive_date_time" +
            "</script> ")
    List<MaterialRecordVO> listMaterialRecordByCondition(MaterialRecordCondition recordCondition);
用这个记得加个<script>标签,不然不能解析,很怪。
总结
刚刚上手使用SpringBoot重构项目之后,会有一些面试相关的问题吧
1.使用Spring框架的好处
2.注解怎么使用或者原理
3.Spring怎么实现Bean的管理的
4.Spring容器初始化过程
5.IOC思想
这些东西明天再做一个整理。