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);
网友评论