1、@Query注解
1.1、@Query注解源码
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
@QueryAnnotation
@Documented
public @interface Query {
//定义一个JPQL语句
String value() default "";
String countQuery() default "";
String countProjection() default "";
//是否开启本地sql语句查询,默认是false
boolean nativeQuery() default false;
String name() default "";
String countName() default "";
}
1.2、JPQL语句基本查询
后续所有操作的例子都是参考这个实体类
@Entity
@Table(name="tb_label")
public class Label implements Serializable {
@Id
private String id;//
private String labelname;//标签名称
private String state;//状态
private Long count;//使用数量
private Long fans;//关注数
private String recommend;//是否推荐
public Label() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getLabelname() {
return labelname;
}
public void setLabelname(String labelname) {
this.labelname = labelname;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Long getCount() {
return count;
}
public void setCount(Long count) {
this.count = count;
}
public Long getFans() {
return fans;
}
public void setFans(Long fans) {
this.fans = fans;
}
public String getRecommend() {
return recommend;
}
public void setRecommend(String recommend) {
this.recommend = recommend;
}
@Override
public String toString() {
return "Label{" +
"id='" + id + '\'' +
", labelname='" + labelname + '\'' +
", state='" + state + '\'' +
", count=" + count +
", fans=" + fans +
", recommend='" + recommend + '\'' +
'}';
}
}
//dao层代码
public interface LabelDao extends JpaRepository<Label,String> {
//使用@Query注解可以自定义JPQL语句以实现更灵活的查询
@Query("SELECT l from Label l where l.id=(select max(l2.id) from Label l2) ")
Label getMaxId();
}
//测试代码
@RunWith(SpringRunner.class)
@SpringBootTest(classes = BaseApplication.class)
public class JpaTest {
@Autowired
private LabelDao labelDao;
@Test
public void testQuery(){
Label label = labelDao.getMaxId();
System.out.println("-----------label-------------"+label.toString());
}
}
1.3、@Query注解传递参数查询
//**************************************dao层代码**************************************
public interface LabelDao extends JpaRepository<Label,String> {
/**
* 为@Query注解传递参数的方式1:使用占位符,且传递参数必须按照指定的顺序
* @return
*/
@Query("SELECT l from Label l where l.labelname=?1 and l.state=?2")
List<Label> testQueryAnnotationParams1(String labelname,String state);
/**
* 为@Query注解传递参数的方式2:使用命名参数的方式,配合@Param注解一起使用
*/
@Query("SELECT l from Label l where l.labelname=:labelname and l.state=:state")
List<Label> testQueryAnnotationParams2(@Param("state") String state, @Param("labelname") String name);
}
//******************************测试代码**********************************************
@RunWith(SpringRunner.class)
@SpringBootTest(classes = BaseApplication.class)
public class JpaTest {
@Autowired
private LabelDao labelDao;
/**
* @Query注解传递参数的方式1:使用占位符
*/
@Test
public void testQueryAnnotationParam1(){
List<Label> list = labelDao.testQueryAnnotationParams1("java", "1");
list.stream().forEach(label -> {
System.out.println("*****"+label.toString());
});
}
/**
* @Query注解传递参数的方式2:使用命名参数的方式,配合@Param注解一起使用
*/
@Test
public void testQueryAnnotationParams2(){
List<Label> list = labelDao.testQueryAnnotationParams2("1", "php");
list.stream().forEach(label -> {
System.err.println("*****"+label.toString());
});
}
}
1.4、@Query注解中Like模糊查询
//***********************************以下是dao代码*********************************************
public interface LabelDao extends JpaRepository<Label,String> {
/**
* @Query注解Like模糊查询1: @Query不写百分号%,但在调用方法时需要使用
*/
@Query("SELECT l from Label l where l.labelname like ?1 or l.state=?2")
List<Label> testQueryAnnotationLikeParams1(String labelname,String state);
/**
* @Query注解Like模糊查询2: @Query写百分号%,但在调用方法时不用写
*/
@Query("SELECT l from Label l where l.labelname like %?1% or l.state=?2")
List<Label> testQueryAnnotationLikeParams2(String labelname,String state);
/**
* @Query注解Like模糊查询3,使用命名方式结合@Param注解
*/
@Query("SELECT l from Label l where l.labelname like %:labelname% or l.state=:state")
List<Label> testQueryAnnotationLikeParams3(@Param("state") String state,@Param("labelname") String name);
}
//***********************************以下是测试代码*********************************************
@RunWith(SpringRunner.class)
@SpringBootTest(classes = BaseApplication.class)
public class JpaTest {
@Autowired
private LabelDao labelDao;
/**
* 使用like模糊查询 @Query中不写百分号%,但在调用方法时需要使用
*/
@Test
public void testQueryAnnotationLikeParams1(){
List<Label> list = labelDao.testQueryAnnotationLikeParams1("%java%", "1");
list.stream().forEach(label -> {
System.err.println("*****"+label.toString());
});
}
/**
* 使用like模糊查询 @Query中写百分号%,但在调用方法时不用写
*/
@Test
public void testQueryAnnotationLikeParams2(){
List<Label> list = labelDao.testQueryAnnotationLikeParams2("java", "1");
list.stream().forEach(label -> {
System.err.println("*****"+label.toString());
});
}
@Test
public void testQueryAnnotationLikeParams3(){
List<Label> list = labelDao.testQueryAnnotationLikeParams3("1", "php");
list.stream().forEach(label -> {
System.err.println("*****"+label.toString());
});
}
}
1.5、@Query注解本地SQL语句查询
//*********************************dao层代码*****************************************
public interface LabelDao extends JpaRepository<Label,String> {
/**
* 原生的sql语句查询
* nativeQuery =true表示启用本地sql语句查询
* @return
*/
@Query(value = "select count(id) from tb_label",nativeQuery =true )
long getCount();
}
//**********************************测试代码**********************************************
@RunWith(SpringRunner.class)
@SpringBootTest(classes = BaseApplication.class)
public class JpaTest {
@Autowired
private LabelDao labelDao;
@Test
public void getCount(){
long count = labelDao.getCount();
System.err.println("------------:"+count);
}
}
2、@Modifying注解
在springdatajpa中如果想使用update和delete操作必须使用@Query注解和@Modifying注解,使用@Modifying注解就表示操作一个更新或者删除操作。
可以通过定义的JPQL完成update和delete操作,注意JPQL不支持使用insert。在@Query注解中编写JPQL语句,但必须使用@Modifying注解进行修饰,用来通知SpringData,这是一个update和delete操作。
【注意】在update或delete操作需要使用事物,此时需要我们定义service层,在server层的方法上添加事物操作。默认情况下,SpringData的每个方法上都有事物,但是这个默认事物是只读事物,它不能完成修改操作.
//*********************************DAO层************************************************
public interface LabelDao extends JpaRepository<Label,String> {
/**
* 可以通过定义的JPQL完成update和delete操作,注意JPQL不支持使用insert。
* 在@Query注解中编写JPQL语句,但必须使用@Modifying注解进行修饰,用来通知SpringData,这是一个update和delete操作。
*/
@Modifying
@Query("update Label label set label.labelname=:name where label.id=:id")
void updateData(@Param("id") String id,@Param("name")String name);
}
//******************************service层***************************************************
@Service
public class LabelService {
@Autowired
private LabelDao labelDao;
//注意更新方法中使用了事物注解
@Transactional
public void updateNameById(String id,String name){
labelDao.updateData(id,name);
}
}
//************************************测试*********************************************
@RunWith(SpringRunner.class)
@SpringBootTest
public class Test2 {
@Autowired
private LabelService labelService;
@Test
public void update(){
labelService.updateNameById("","java----");
}
}