jpa初探

jpa

jpa是Java Persistence API简称

主键生成策略GenerationType

  • TABLE 使用一个特定的数据库表格来保存主键,这个策略可以由表模拟序列产生主键, 不依赖于数据库的具体实现,有利于数据库的移植。序列表有一个序列名和对应值两个字段,只需要一张序列就可以用于多张表的主键生成
  • SEQUENCE 根据底层数据库的序列来生成主键,条件是数据库支持序列,通过序列产生主键,Oracle不支持ID子增长列,而是使用序列的机制生成主键ID,所以SEQUENCE适用于Oracle,Mysql不支持这种策略
  • IDENTITY 主键由数据库自动生成(主要是自动增长型)
  • AUTO 主键由程序控制 使用 AUTO 策略就是将主键生成的策略交给持久化引擎 (persistence engine) 来决定,由它自己选择从 Table 策略,Sequence 策略和 Identity 策略三种策略中选择合适的主键生成策略。

JpaRepository

实际上JpaRepository实现了PagingAndSortingRepository接口,PagingAndSortingRepository接口实现了CrudRepository接口,CrudRepository接口实现了Repository接口(下文会细说)

使用方法

public interface DemoBasicDao extends JpaRepository<Demo, Integer> {
    /**
     * where name=${name} and age=${age}
     *
     * @param name
     * @param age
     * @return
     */
    Demo findByNameAndAge(String name, int age);

    /**
     * where id in(${ids})
     *
     * @param ids
     * @return
     */
    List queryByIdIn(List ids);

    /**
     * where id between ${var1} and ${var2}
     *
     * @param var1
     * @param var2
     * @return
     */
    List getByIdBetween(int var1, int var2);

    /**
     * where id<${id}
     *
     * @param id
     * @return
     */
    List queryByIdLessThan(int id);

    /**
     * where id>${id}
     *
     * @param id
     * @return
     */
    List queryByIdGreaterThan(int id);

    /**
     * where id<=${id}
     *
     * @param id
     * @return
     */
    List queryByIdLessThanEqual(int id);

    /**
     * where id>=${id}
     *
     * @param id
     * @return
     */
    List queryByIdGreaterThanEqual(int id);

    /**
     * where name like ${name}
     *
     * @param name
     * @return
     */
    List queryByNameLike(String name);

    /**
     * where name like %name
     *
     * @param name
     * @return
     */
    List queryByNameStartingWith(String name);

    /**
     * where name like name%
     *
     * @param name
     * @return
     */
    List queryByNameEndingWith(String name);

    /**
     * order by id desc
     *
     * @param ids
     * @return
     */
    List queryByIdInOrderByIdDesc(List ids);

}
public interface DemoHighDao extends JpaRepository<Demo,Integer> {
    @Query("select demo from Demo demo where demo.id=:id")
    Demo aaaaa(@Param("id") int id);

    List queryByIdIn(List id, Sort sort);

    List queryByIdIn(List id, Pageable pageable);

    DemoMap queryById(int id);
}

关键注解

spring.datasource.platform=h2
spring.datasource.url=jdbc:h2:mem:demo;MODE=MYSQL
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=root
spring.datasource.password=

spring.h2.console.enabled=true
spring.h2.console.path=/db
spring.datasource.schema=classpath:db/schema.sql
spring.datasource.data=classpath:db/data.sql
spring.jpa.hibernate.ddl-auto=none

注意:spring.jpa.hibernate.ddl-auto

  • validate:加载hibernate时,验证创建数据库表结构
  • create:每次加载hibernate,重新创建数据库表结构,这就是导致数据库表数据丢失的原因。
  • create-drop:加载hibernate时创建,退出是删除表结构
  • update:加载hibernate自动更新数据库结构

代码github地址:

[email protected]:Mr-ChangK/jpademo.git

原理详解

  • RepositoryFactoryBeanSupport:为spring的FactoryBean接口开发的适配器,可以很便捷的通过spring配置设置repository工厂

  • RepositoryFactorySupport:创建一个给定repository接口实例的工厂bean。创建一个实现配置的repository接口的代理,并应用一个advice将控制交给QueryExecuterMethodInterceptor

  • RepositoryQuery

    • SimpleJpaQuery:方法头上@Query注解的nativeQuery属性缺省值为false,也就是使用JPQL,此时会创建SimpleJpaQuery实例,并通过两个StringQuery类实例分别持有query jpql语句和根据query jpql计算拼接出来的countQuery jpql语句;
    • NativeJpaQuery:方法头上@Query注解的nativeQuery属性如果显式的设置为nativeQuery=true,也就是使用原生SQL,此时就会创建NativeJpaQuery实例;
    • PartTreeJpaQuery:方法头上未进行@Query注解,将使用spring-data-jpa独创的方法名识别的方式进行sql语句拼接,此时在spring-data-jpa内部就会创建一个PartTreeJpaQuery实例;
    • NamedQuery :使用javax.persistence.NamedQuery注解访问数据库的形式,此时在spring-data-jpa内部就会根据此注解选择创建一个NamedQuery实例;
    • StoredProcedureJpaQuery :顾名思义,在Repository接口的方法头上使用org.springframework.data.jpa.repository.query.Procedure注解,也就是调用存储过程的方式访问数据库,此时在spring-data-jpa内部就会根据@Procedure注解而选择创建一个StoredProcedureJpaQuery实例。
  • QueryMethod

  • JpaQueryExecution

每一个方法都创建了一个

private final Map

sql解析原理详解

  • 主要的类
    • RepositoryFactoryBeanSupport:为spring的FactoryBean接口开发的适配器,可以很便捷的通过spring配置设置repository工厂

    • RepositoryFactorySupport:创建一个给定repository接口实例的工厂bean。创建一个实现配置的repository接口的代理,并应用一个advice将控制交给QueryExecuterMethodInterceptor

    • QueryLookupStrategy:是一个枚举类,有三种枚举,返回QueryLookupStrategy的实例,主要用来返回一个RepositoryQuery类

    • RepositoryQuery:

      • SimpleJpaQuery:方法头上@Query注解的nativeQuery属性缺省值为false,也就是使用JPQL,此时会创建SimpleJpaQuery实例,并通过两个StringQuery类实例分别持有query jpql语句和根据query jpql计算拼接出来的countQuery jpql语句;
      • NativeJpaQuery:方法头上@Query注解的nativeQuery属性如果显式的设置为nativeQuery=true,也就是使用原生SQL,此时就会创建NativeJpaQuery实例;
      • PartTreeJpaQuery:方法头上未进行@Query注解,将使用spring-data-jpa独创的方法名识别的方式进行sql语句拼接,此时在spring-data-jpa内部就会创建一个PartTreeJpaQuery实例;
      • NamedQuery :使用javax.persistence.NamedQuery注解访问数据库的形式,此时在spring-data-jpa内部就会根据此注解选择创建一个NamedQuery实例;
      • StoredProcedureJpaQuery :顾名思义,在Repository接口的方法头上使用org.springframework.data.jpa.repository.query.Procedure注解,也就是调用存储过程的方式访问数据库,此时在spring-data-jpa内部就会根据@Procedure注解而选择创建一个StoredProcedureJpaQuery实例。
    • PartTree:用于从方法中解析出sql语法

  • 过程

    RepositoryFactoryBeanSupport实现了InitializingBean接口,所以在bean初始化中直接执行afterPropertiesSet方法,这个方法会初始化RepositoryFactorySupport的实例,这个实例的getRepository方法会生成一个代理工厂,这个代理工厂会加入一个拦截器QueryExecutorMethodInterceptor,这个拦截器中对于每个方法都会有一个private final Map

你可能感兴趣的:(spring)