如果数据库表的字段名称带有下划线,使用IDEA映射为实体后:
1 @Entity 2 @Table(name = "user_profile") 3 public class UserProfile { 4 @Id 5 @GeneratedValue(strategy = GenerationType.IDENTITY) 6 private Long User_ID; 7 private String User_Name; 8 private String Real_Name; 9 10 public UserProfile() { } 11 12 getter... 13 setter... 14 }
Spring Data JPA查询时如:
1 findByUser_ID();
会报错,时因为有下划线,Spring Data的解析规则为:
查询方法以find|read|get开头(比如 find、findBy、read、readBy、get、getBy),涉及条件查询时,条件的属性用条件关键字连接,要注意的是:条件属性首字母需大写。框架在进行方法名解析时,会先把方法名多余的前缀截取掉,然后对剩下部分进行解析。
比如 findByUserAddressZip()。框架在解析该方法时,首先剔除 findBy,然后对剩下的属性进行解析,详细规则如下(此处假设该方法针对的域对象为 AccountInfo 类型):
先判断 userAddressZip (根据 POJO 规范,首字母变为小写,下同)是否为 AccountInfo 的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,继续第二步;
从右往左截取第一个大写字母开头的字符串(此处为 Zip),然后检查剩下的字符串是否为 AccountInfo 的一个属性,如果是,则表示根据该属性进行查询;如果没有该属性,则重复第二步,继续从右往左截取;最后假设 user 为 AccountInfo 的一个属性;
接着处理剩下部分( AddressZip ),先判断 user 所对应的类型是否有 addressZip 属性,如果有,则表示该方法最终是根据 "AccountInfo.user.addressZip" 的取值进行查询;否则继续按照步骤 2 的规则从右往左截取,最终表示根据 "AccountInfo.user.address.zip" 的值进行查询。
可能会存在一种特殊情况,比如 AccountInfo 包含一个 user 的属性,也有一个 userAddress 属性,此时会存在混淆。读者可以明确在属性之间加上 "_" 以显式表达意图,比如 "findByUser_AddressZip()" 或者 "findByUserAddress_Zip()"。
但是现在的属性中没有类似上述 “AccountInfo 包含一个 user 的属性,也有一个 userAddress 属性”,所以查询会出错
可以在要用的属性前加上
@Column(name = "列名")
然后把实体改为
1 @Entity 2 @Table(name = "eb_user_profile") 3 public class UserProfile { 4 @Id 5 @GeneratedValue(strategy = GenerationType.IDENTITY) 6 @Column(name = "UserID") 7 private Long User_ID; 8 @Column(name = "UserName") 9 private String User_Name; 10 @Column(name = "RealName") 11 private String Real_Name; 12 13 public UserProfile() { } 14 15 getter... 16 setter... 17 }
这时查询语句就改为:
1 findByUserID();
这样就解决了这个错误