前面的章節講述了 Spring Data Jpa 經過聲明式對數據庫進行操做,上手速度快簡單易操做。但同時 JPA 還提供經過註解的方式實現,經過將 @Query
註解在繼承 repository 的接口類方法上 。java
Query 源碼講解git
public @interface Query { /** * 指定 JPQL 的查詢語句。(nativeQuery = true)是原生的 SQL 語句. */ String value() default ""; /** * 指定 count 的 JPQL 語句,若是不指定將根據 query 自動生成。 * (nativeQuery = true 的時候,是原生查詢的 SQL 語句) */ String countQuery() default ""; /** *根據那個字段來 count,通常默認便可。 */ String countProjection() default ""; /** * 默認是 false,表示 value 裏面是否是原生的 SQL 語句 */ boolean nativeQuery() default false; /** * 能夠指定一個 query 的名字,必須是惟一的。 * 若是不指定,默認的生成規則是 * {$domainClass}.${queryMethodName} */ String name() default ""; /** * 能夠指定一個 count 的query 名字,必須是惟一的。 * 若是不指定,默認的生成規則是: * {$domainClass}.${queryMethodName}.count */ String countName() default ""; }
項目中的pom.xml
、application.properties
與 Chapter1 相同github
實體類映射數據庫表spring
user 實體類sql
@Entity @Table(name = "t_user") public class User implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "u_name") private String name; @Column(name ="u_age") private Integer age; @Column(name ="u_email") private String email; // 省略構造器 set/get }
@Entity
:定義對象將會成爲被JPA管理的實體,將映射到指定的數據庫表。數據庫
@Table
:指定數據庫的表名。app
@Column
:定義該屬性對應數據庫中的列名。dom
@Id
定義屬性爲數據庫的主鍵,一個實體裏面必須有一個。學習
@GeneratedValue(strategy = GenerationType.IDENTITY)
自增加 ID 策略測試
生成以下:
繼承 UserQueryRepository
public interface UserQueryRepository extends JpaRepository<User, Long> { /** * 語句中 User 查詢數據表的類名,?1 括號表明第一個參數 */ @Query(name = "select * from User where name = ?1") List<User> findByName(String name); /** * Sort 排序 * 根據姓名模糊查詢排序 */ @Query("select u from User u where u.name like ?1%") List<User> findByAndSort(String name, Sort sort); /** * @Transactional 事務的支持 ,@Modifying 用於修改查詢 * @param name 對應 ?1 * @param id 對應 ?2 * @return */ @Transactional @Modifying @Query("update User u set u.name = ?1 where u.id = ?2") int updateById(String name, Long id); }
/** * param 對象 * @param name * @param age * @return */ @Query(value = "select u from User u where u.name = :name and u.age = :age") List<User> queryParamByNameAndAge(@Param("name") String name,@Param("age") Integer age); /** * 傳一個對象 * @param user * @return */ @Query(value = "select u from User u where u.name = :#{#user.name} and u.age = :#{#user.age}") List<User> queryObjectParamByNameAndAge(@Param("user") User user);
:name
對應 @Param
中的 name。:age
對應 @Param
中的 age。
:#{#user.name}
: 對象中的參數使用方法
@Query("select u from #{#entityName} u where u.lastname = ?1") List<User> findByLastname(String lastname);
entityName
: 根據指定的 Repository 自動插入相關的 entityName。有兩種方式能被解析出來:
@Entity
註解,直接用其屬性名。@Query(value = "select * from t_user where u_name = :name",nativeQuery = true) List<User> queryNativeByName(@Param("name") String name);
nativeQuery
: 爲 true 開啓。開啓以後字段則須要對應的數據庫中的表名和字段。CURD 測試類
路徑:src/test/java/com/mtcarpenter/repository/UserQueryRepositoryTest.java
@RunWith(SpringRunner.class) @SpringBootTest public class UserQueryRepositoryTest { /** * ⽇志對象 */ private Logger logger = LoggerFactory.getLogger(UserQueryRepositoryTest.class); @Autowired private UserQueryRepository userQueryRepository; @Before public void save() { logger.info("新增數據 result = {}", userQueryRepository.save(new User("小米", 9, "a@qq.com"))); logger.info("新增數據 result = {}", userQueryRepository.save(new User("張三", 16, "b@qq.com"))); logger.info("新增數據 result = {}", userQueryRepository.save(new User("三哥", 12, "c@qq.com"))); logger.info("新增數據 result = {}", userQueryRepository.save(new User("米二", 13, "e@qq.com"))); logger.info("新增數據 result = {}", userQueryRepository.save(new User("阿三", 12, "f@qq.com"))); logger.info("新增數據 result = {}", userQueryRepository.save(new User("張三", 12, "g@qq.com"))); logger.info("新增數據 result = {}", userQueryRepository.save(new User("米二", 8, "h@qq.com"))); } /** * 基本使用 */ @Test public void test() { logger.info("@query 查詢張三 result = {}", userQueryRepository.findByName("張三")); logger.info("根據姓名模糊查詢排序 result = {}", userQueryRepository.findByNameAndSort("米", new Sort(Sort.Direction.ASC,"age"))); logger.info("修改 id = 1 的name ,result ={ }", userQueryRepository.updateById("紅米", 1L)); } /** * param 參數使用 */ @Test public void paramTest(){ logger.info("@param 使用方法 result = {}",userQueryRepository.queryParamByNameAndAge("張三", 12)); User user = new User(); user.setName("張三"); user.setAge(12); logger.info("@Param 對象 result = {}", userQueryRepository.queryObjectParamByNameAndAge(user)); } /** * SpEl 使用 */ @Test public void spELTest(){ logger.info("SpEL 使用方法 result = {}",userQueryRepository.queryELByName("張三")); } /** * 原生查詢 */ @Test public void nativeTest(){ logger.info("原生查詢 使用方法 result = {}",userQueryRepository.queryNativeByName("張三")); } }