SpringDataJpa基础篇5:@Query与@Modifying注解使用

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----");
    }
}



 

猜你喜欢

转载自blog.csdn.net/u013089490/article/details/84975228