版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_27886997/article/details/84969207
package com.demo.jpa_query_test.respository;
import com.demo.jpa_query_test.model.Stu;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.jdbc.core.JdbcTemplate;
import java.awt.print.Pageable;
import java.util.List;
/**
* 一个学生和班级多对一
* 一个学生和汽车多对多
*/
public interface StuRespository extends JpaRepository<Stu,Integer> {
//这是接口不能注入jdbcTemplate 要想用自己新建个studao类 可以把jdbcTemplate和StuRespository都注入进入
@Override
<S extends Stu> S save(S s);
@Override
List<Stu> findAll();
//多对一查询,想要查询学生 根据其所在的班级id
//inner join为内连接查询,左右都必须有值,右边的IClass必须返回实体,不然查询的结果为bull
//不用写外键关系 s.iclass c 包含了外键关系,右表还必须这样写
@Query(value = "select s from Stu s inner join s.iclass c where c.id = :size ")
List<Stu> findByCarSize(@Param(value = "size") Integer size);
//多对一查询,想要查询学生 根据其所在的班级id
//left join为内连接查询,以左边为基础,右边的IClass可以返回null
//不用写外键关系 s.iclass c 包含了外键关系,右表还必须这样写
@Query(value = "select s from Stu s left join s.iclass c where c.id = :size ")
List<Stu> findByCarSize2(@Param(value = "size") Integer size);
/**转换后的hibernate语句
* Hibernate: select stu0_.id as id1_2_, stu0_.c_id as c_id3_2_, stu0_.name as name2_2_ from stu stu0_ where (select count(carlist1_.stu_id) from sut_car_relation carlist1_ where stu0_.id=carlist1_.stu_id)>=?
* //多对多查询,原始的sql要查询左表+中间表 或者右表+中间表
* //jpql 有size() concate()等函数可用
* //查询拥有汽车数大于2的学生
*/
@Query(value = "select s from Stu s where size(s.carList)>= :size ")
List<Stu> findByCarSize3(@Param(value = "size") Integer size);
/**
* 使用原生的sql 查询学生 按照拥有的汽车数排序,学生和汽车多对多
* 先使用子查询 得到stu_id 和 统计数这个中间表 c 拿这个中间表(带汽车统计个数和学生id)和学生表内连接 得到交叉集合
*
* @return
*/
@Query(value = " select s.* from stu s ,(select sc.stu_id ,count(sc.stu_id) as coun_t from sut_car_relation sc group by sc.stu_id) as c where s.id = c.stu_id order by c.coun_t asc" ,nativeQuery = true)
List<Stu> findByCarSize4();
/**
* 使用jpql查询没有 车的学生 is null 判断null is empty只能判断实体的集合属性是否为空
* @return
*/
@Query(value = "select s from Stu s where s.carList is empty ")
List<Stu> findByCarSize6();
/**
* 使用jpql就简单的多了 直接如下
* @return
*/
@Query(value = "select s from Stu s order by size(s.carList) desc")
List<Stu> findByCarSize5();
/**
* spring boot分页
* 前边传入分页参数
* Pageable pageable = new PageRequest(currentPage, pagesize, Sort.Direction.DESC, "keywords");
* currentPage从0页开始
*/
@Query(value = "from Stu s where 1=1")
List<Stu> findByIPage_w();
/**
* 使用自带的分页page 该对象里面总条数。。这些都有了
* //这是spring boot 2.0 pageable必写全路径,不然就
* @Param on all parameters except Pageable and Sort typed once, or none at all_。。
* @param name
* @param pageable
* @return
*/
@Query(value = "select s from Stu s where s.name = :name")
Page<Stu> findAllTest1(@Param(value = "name") String name,org.springframework.data.domain.Pageable pageable);
/**
* jpql 支持动态传参数,?1 或者:name 这种,同时只能使用一种
*
*/
@Query(value = "from Stu s where s.name = ?1 and s.id = ?2")
Stu findByNameAndId(String name,String id);
/***
* 动态sql
* 原始的sql
* IF( expr1 , expr2 , expr3 ) expr1 的值为 TRUE,则返回值为 expr2 ,expr1 的值为FALSE,则返回值为 expr3
* 例如 if(/"/"=:name,1=1, s.name like concat('%',:name,'%'))
* if(:stae is null,1=1, s.state = :state)
*
* @Query(value = "select * from tag_info T where (1=1 and if(:tagState is null ,1=1,T.tag_state=:tagState) and T.tag_type in :tagType and if(\"\"=:content,1=1,T.name like CONCAT('%',:content,'%'))) or (1=1 and T.id in :ids) order by :orderFiled :px limit :start , :ed", nativeQuery = true)
*
* IFNULL( expr1 , expr2 ) 在 expr1 的值不为 NULL的情况下都返回 expr1,否则返回 expr2
*/
//在拼接sql的过程中,传来的参数有字符串,Integer Boolean等 都可以判断为"" 或者为null
//但 in 集合或者数组,没法判断 他们也可能为空,in () 报错 ,前台可以给个默认值,默全部,如果前台传来的为空 就用全部,不为空就用前台的,或者故意往集合添加一个无关紧要的
/**
* jpql无法动态拼接sql只能用原始的
*/
//删除更新操作 要加@Modifying
@Query("delete from Stu s where s.name = ?1")
@Modifying
void delByName(String name);
}