1.1 Jpa命名规则
采用小驼峰命名法
关键字 | 方法命名 | sql where字句 |
---|---|---|
And | findByNameAndPwd | where name= ? and pwd =? |
Or | findByNameOrSex | where name= ? or sex=? |
Is,Equals | findById,findByIdEquals | where id= ? |
Between | findByIdBetween | where id between ? and ? |
LessThan | findByIdLessThan | where id < ? |
LessThanEquals | findByIdLessThanEquals | where id <= ? |
GreaterThan | findByIdGreaterThan | where id > ? |
GreaterThanEquals | findByIdGreaterThanEquals | where id > = ? |
After | findByIdAfter | where id > ? |
Before | findByIdBefore | where id < ? |
IsNull | findByNameIsNull | where name is null |
isNotNull,NotNull | findByNameNotNull | where name is not null |
Like | findByNameLike | where name like ? |
NotLike | findByNameNotLike | where name not like ? |
StartingWith | findByNameStartingWith | where name like ‘?%’ |
EndingWith | findByNameEndingWith | where name like ‘%?’ |
Containing | findByNameContaining | where name like ‘%?%’ |
OrderBy | findByIdOrderByXDesc | where id=? order by x desc |
Not | findByNameNot | where name <> ? |
In | findByIdIn(Collection<?> c) | where id in (?) |
NotIn | findByNameNot | where name <> ? |
True | findByAaaTue | where aaa = true |
False | findByAaaFalse | where aaa = false |
IgnoreCase | findByNameIgnoreCase | where UPPER(name)=UPPER(?) |
top | findTop100 | top |
1.2 命名示例
继承接口CrudRepository<UserEntity,Integer>, JpaSpecificationExecutor
public interface UserEntityRepository extends CrudRepository<UserEntity,Integer>, JpaSpecificationExecutor<UserEntity> {
// 根据命名规则进行查询
// find + by + 所需要查询
// findOneBy和findBy效果相同,因为此处没有使用like
// 推荐使用findOneBy的写法,以免产生歧义
public UserEntity findByEmail(String email);
public UserEntity findOneByEmail(String email);
// 根据命名规则模糊查询
// find + by + 属性名称 + Like | isnull
// 此处的email应该为 = “%xxxx%”,对于like 需要自行添加%
// 此处的findBy与findAllBy的效果相同
public List<UserEntity> findByEmailLike(String email);
// 多条件查询的命名规则
// findBy + 属性名称 + “查询方式” + “多条件的连接符(and | or)” + 属性名称 + 查询方式
public List<UserEntity> findByEmailLikeAndNameLike(String email, String name);
}
1.3 调用示例
在DemoApplicationTests 编写以下代码,此处对email字段进行模糊查询
@Test
public void testFindAllEntity() {
List<UserEntity> userEntityList = userEntityRepository.findAllByEmailLike("%@qq%");
for (UserEntity userEntity: userEntityList) {
System.out.println(userEntity);
}
}
运行结果如下所示,成功的找出了所有带@qq的数据:
UserEntity(id=3, name=SecondUser, email=hhhh@qq.com)
UserEntity(id=8, name=hello, email=qq@qq.com)
UserEntity(id=9, name=加入的名称, email=这个是email@qq.com)
2. Jpql
Jpql的语法与sql几乎一致,
不一样的是,sql需要标注表名等信息,Jpql则使用类名替代表名。
如果不写 select 而是直接使用from子句,表明获取对象的全部属性。
Jpql写在继承了 CrudRepository, JpaSpecificationExecutor的接口中
2.1 Jpql示例
public interface UserEntityRepository extends CrudRepository<UserEntity,Integer>, JpaSpecificationExecutor<UserEntity> {
// 查询操作
// 此处的?为占位符,?1表示第一个参数
@Query(value = "from UserEntity where id = ?1")
public UserEntity findUserEntityByIdJql(Integer id);
// :同为占位符,后面可跟参数名(推荐使用此方法)
@Query(value = "from UserEntity where id = :iId")
public UserEntity findUserEntityByIdJql2(Integer iId);
// 更新操作
@Modifying
@Transactional
@Query(value = "update UserEntity set email = :email where id = :id")
public Integer updateUserEntityByJpql (String email, Integer id);
// 可以使用@Param()给别面取别名,并用于jpql\原生sql中
@Query(value = "select * from user where LOWER(user.id) = :id ",nativeQuery = true)
public UserEntity UserEntityQueryFindById(@Param("id") Integer integerId);
@Query(value = "select new map(u.id as id, u.name as name) from UserInforViewEntity u where u.email like ''")
List<Map<String, Object>> getAllBaseInfo();
}
2.1.1 Jpql更新查询操作
// 查询操作
// 此处的?为占位符,?1表示第一个参数
@Query(value = "from UserEntity where id = ?1")
public UserEntity findUserEntityByIdJql(Integer id);
// :同为占位符,后面可跟参数名(推荐使用此方法)
@Query(value = "from UserEntity where id = :iId")
public UserEntity findUserEntityByIdJql2(Integer iId);
// 更新操作
@Modifying
@Transactional
@Query(value = "update UserEntity set email = :email where id = :id")
public Integer updateUserEntityByJpql (String email, Integer id);
@Query
:为语句操作@Modify
: 为更新操作@Transactional
:标志此方法为事务,更新删除操作需要此注解。
可能有人并不太理解事务是什么,事务指的是若执行到一半,操作失败,则将会回退所有操作。
如user
信息,更新了name
,在更新email
的时候失败,则会回退name
的更新。
调用方式均与1.3示例中相同,此处不赘述,若需要可看我之前SpringDataJpa相关文章,或者在评论区留言。
此处重点讲解下列代码:
@Query(value = "select new map(u.id as id, u.name as name) from UserEntity u where u.email like :email")
public List<Object> findByLikeEmailGetIdAndName(String email);
可以发现,在语句里面使用了new map,这样可以使得我们仅取部分数据,而不需要去除全部的实体类数据,这样对于数据库某张表中存有大量数据如Base64图片的情况,可以大大加快提取速度。
调用方法如下所示:
@Test
void testGetMap() {
List<Object> objectList = userEntityRepository.findByLikeEmailGetIdAndName("%qq%");
for (Object object: objectList) {
System.out.println(object);
// {name=SecondUser, id=3}
// {name=hello, id=8}
// {name=加入的名称, id=9}
}
}
2.1.2 使用sql
// 可以使用@Param()给别面取别名,并用于jpql\原生sql中
@Query(value = "select * from user where LOWER(user.id) = :id ",nativeQuery = true)
public UserEntity UserEntityQueryFindById(@Param("id") Integer integerId);
可在上述事例中查看到,第四个方法,标注nativaQuery = true,此为使用sql
即使用了原生的sql语言,可以注意到这里是写from user
,user
指的是表的名称,
而Jpql写的是from UserEntity
,UserEntity
是在Spring Data Jpa 简单教程(一)中所提到的@Entity实体类。
//UserEntity实体类
@Table(name = "user")
@Data
@Entity
public class UserEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column
private Integer id;
@Column
private String name;
@Column(name = "email")
private String email;
}
可以看出,jpql少去了对表名的描述,直接使用@Entity实体类
进行查询操作,即将@Entity
当做表操作
它的调用方法并不特别,与使用jpa、Jpql的调用方法相同,代码如下
@Test
public void testNativeSql() {
UserEntity userEntity = userEntityRepository.UserEntityQueryFindById(9);
System.out.println(userEntity);
}