美文网首页
Java JPA使用注意事项

Java JPA使用注意事项

作者: 丿星纟彖彳亍 | 来源:发表于2021-11-10 10:59 被阅读0次

    JAVA JPA使用注意事项

    共同需要遵守的

    在进行数据删改时

    使用@Modifying注解(标注只需要绑定参数的自定义的更新类语句(更新、插入、删除)),

    @Transactional 事务

    默认情况下,repository 接口中的CRUD方法都是被@Transactional注解修饰了的,对于读的操作方法,@Transactional注解的readOnly属性是被设置为true的,即只读;
    CRUD中的其他方法被@Transactional修饰,即非只读。如果你需要修改repository 接口中的某些方法的事务属性,可以在该方法上重新加上@Transactional注解,并设置需要的属性。

    in 语句写法

    @Query(value = "select * from ee where identifynumber=?1 and yearmonth=?2 and syssource in (?3)  and (freetype='0' or freetype='' or  freetype is null) ", nativeQuery = true)
        public List<ee> findNoFreeByIdentifynumber( String identifynumber,String yearmonth, List<String> syssource);
    

    @Query 自定义SQL时

    需要加上nativeQuery=true来声明这是一个本地查询哦。

    取值方式::#{#obj.field} :value ?1

    :#{#obj.field} 方式取值和:value方式取值不能一起用;

    模糊查询

    使用对象传参时

    如果使用到模糊查询,需要将入参转成字符串(to_char)或者使用concat()函数转换,Oracle的只能拼接两个参数,但可以多次套接,MySQL可以无限参数拼接,比如:
    CONCAT(CONCAT('%', :#{#pojo.query}), '%'))

    使用参数传参时

    可以直接使用||拼接字符串查询:比如:
    LIKE '%'||:query||'%'

    可配置查询(参数为空之类):

    使用if语句(目前还没成功,转换成SQL的时候,会把if带过去,而SQL是没有if语句的,不清楚原因)

    if(?1='' OR ?1 is null, 1=1, ?1=xx)

    使用判空+OR

    (:query is null OR a.fymc LIKE '%'||:query||'%')
    注意: 如果需要判断的参数是数字型的,最好请在查询之前处理好,jpa目前不支持数字型参数为空(null),这里提供一个笨办法:入参前判断,如果参数为空,给它赋予一个特定值,语句里面使用这个特定值判断:(:query = -1 OR a.fymc LIKE '%'||:query||'%')

        /**
         * 查询诊疗价格(使用对象传参)
         * @param pojo
         * @return
         */
        @Query(value = " SELECT d.fymc entryName, d.fydj unitPrice, d.FYDW unit\n" +
                "    FROM (SELECT ROW_NUMBER() OVER (ORDER BY a.fyxh) rowNumber, a.fymc, b.fydj, a.fydw\n" +
                "    FROM gy_ylml a, gy_ylmx b\n" +
                "    WHERE a.fyxh = b.fyxh AND a.zfpb = 0 AND b.zfpb = 0 AND b.jgid = :#{#pojo.organizationId} " +
    //            "        AND (:#{#pojo.query} is null OR a.fymc LIKE CONCAT(CONCAT('%', :#{#pojo.query}), '%')) )  d\n" +
                "        AND (:#{#pojo.query} is null OR a.fymc LIKE '%'||to_char(:#{#pojo.query})||'%') )  d\n" +
                " WHERE d.rowNumber BETWEEN ((:#{#pojo.pageNo} - 1) * :#{#pojo.pageSize} + 1) AND :#{#pojo.pageNo} * :#{#pojo.pageSize}", nativeQuery = true)
        List<Map<String, Object>> getListFy(@Param("pojo") PricePojo pojo);
        
        /**
         * 查询诊疗价格(使用参数传参)
         * @param jgid
         * @param query
         * @param pageSize
         * @param pageNo
         * @return
         */
        @Query(value = " SELECT d.fymc entryName, d.fydj unitPrice, d.FYDW unit\n" +
                "    FROM (SELECT ROW_NUMBER() OVER (ORDER BY a.fyxh) rowNumber, a.fymc, b.fydj, a.fydw\n" +
                "    FROM gy_ylml a, gy_ylmx b\n" +
                "    WHERE a.fyxh = b.fyxh AND a.zfpb = 0 AND b.zfpb = 0 AND b.jgid = :jgid " +
                "     AND (:query is null OR a.fymc LIKE '%'||:query||'%'))  d\n" +
                " WHERE d.rowNumber BETWEEN ((:pageNo - 1) * :pageSize + 1) AND :pageNo * :pageSize", nativeQuery = true)
        List<Map<String, Object>> getListFy (@Param("jgid") String jgid, @Param("query") String query, @Param("pageNo") Integer pageNo, @Param("pageSize") Integer pageSize);
    

    @Query 自定义JPQL时

    想要使用jpql的前提是你已经使用注解配置好了实体类以及参数

    /**
     * @Entity 作用:指定当前类是实体类。
     * @Table 作用:指定实体类和表之间的对应关系。
     *  属性:
     *   name:指定数据库表的名称
     * @Id 作用:指定当前字段是主键。
     * @GeneratedValue  作用:指定主键的生成方式。。
     *  属性:
     *   strategy :指定主键生成策略。
     *   GenerationType.IDENTITY:自增,底层数据库必须支持自增(mysql)
     *   GenerationType.SEQUENCE:序列,底层数据库必须支持序列(oracle)
     *   GenerationType.TABLE:jpa提供的一种策略,通过生成一张表的方式完成主键自增,这张表存储了下一次添加的主键的值
     *   GenerationType.AUTO:由程序自动选择一种策略
     *
     * @Column
     *  作用:指定实体类属性和数据库表之间的对应关系
     *  属性:
     *   name:指定数据库表的列名称。
     *   unique:是否唯一
     *   nullable:是否可以为空
     *   inserttable:是否可以插入
     *   updateable:是否可以更新
     *   columnDefinition: 定义建表时创建此列的DDL
     *   secondaryTable: 从表名。如果此列不建在主表上(默认建在主表),该属性定义该列所在从表的名字搭建开发环境[重点]
     */
    //示例:
    @Entity //标注这是一个实体类
    @Table(name = "tbl_user") //建立实体类与表的映射关系
    public class User {
      @Id //声明此属性为主键
      @GeneratedValue(strategy = GenerationType.IDENTITY) //主键生成策略,自增
      @Column(name = "user_id")//指定属性对应数据库表的列名
      private Integer userId;
    
      @Column(name = "user_name")
      private String userName;
    
      @Column(name = "user_address")
      private String userAddress;
    
      @Column(name = "user_salary")
      private Double userSalary;
      
      //...getter setter toString方法
    }
    

    指定类接收查询结果时,如果参数和返回结果不对应

    需要在实体类写一个初始化方法,查询语句中最好写上全路径,不然jpa可能找不到

        /**
         * 获取处方预付费列表
         *
         * @param brid
         * @param cfsbArr
         * @return
         */
        @Query(value = "SELECT new com.bsoft.gzjkpt.model.domain.GetPrecalculatedFeeCheckData(A.cfsb, A.fphm, A.mzxh, A.tybz, A.zfpb) " +
                "    FROM Ms_cf01 A " +
                "    WHERE A.jgid = ?1 AND 1 = 0 OR A.cfsb IN ?2 ")
        List<GetPrecalculatedFeeCheckData> getPrecalculatedFeeCheckData(@Param("jgid") String jgid, @Param("cfsb") List<String> cfsbList, @Param("yjxh") List<String> yjxhList);
    

    相关文章

      网友评论

          本文标题:Java JPA使用注意事项

          本文链接:https://www.haomeiwen.com/subject/ozmbzltx.html