Spring Data Commons

Purpose

Spring Data’s mission is to provide a familiar and consistent, Spring-based programming model for data access while still retaining the special traits of the underlying data store. 其实就是理解Repository的概念

spring-data的主要目的就是实现object–>序列化 --> 存储 --> 反序列化 --> object这样一个流程。说实话这个作用不是很大,当我们使用sql db或者redis的时候绝对不会只是想把他们当作一个简单的object storage来使用。Spring Data Repository可以提供一些简单的操作,但是高级使用我们还是免不了要直接使用RedisTemplate和JdbcTemplate

Dependencies

spring-data的众多子项目版本比较混乱,为了保证多个子项目可以协调工作,可以使用Spring Data Release Train BOM

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-bom</artifactId>
      <version>2021.1.10</version>
      <scope>import</scope>
      <type>pom</type>
    </dependency>
  </dependencies>
</dependencyManagement>

然后就可以指定具体的子项目的时候不用指定版本号了

<dependencies>
  <dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-jpa</artifactId>
  </dependency>
<dependencies>

对于spring-boot有点特殊, spring-boot-starter-parent本来就是干这个是的,打开parent 2.7.3看看
,它依赖了spring-boot-dependencies 2.7.3, 后者有如下定义

<spring-data-bom.version>2021.2.2</spring-data-bom.version>
      <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-bom</artifactId>
        <version>${spring-data-bom.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>

这个说明在spring-boot里面不再需要自己指定spring-data-bom了。并且在spring-boot里面,引用各种starter更好

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jdbc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
		</dependency>

Object Mapping Fundamentals

主要作用就是序列化和反序列化,尤其是反序列化

1,Instance creation by using one of the constructors exposed.

2,Instance population to materialize all exposed properties.

  • If there is a single constructor, it is used.

  • If there are multiple constructors and exactly one is annotated with @PersistenceConstructor, it is used.

  • If there’s a no-argument constructor, it is used. Other constructors will be ignored.

所以简单的pojo就是比较好的 data class

Spring Data Repositories

The goal of the Spring Data repository abstraction is to significantly reduce the amount of boilerplate code required to implement data access layers for various persistence stores.

spring提供了通用的repositore

public interface CrudRepository<T, ID> extends Repository<T, ID> {

  <S extends T> S save(S entity);      

  Optional<T> findById(ID primaryKey); 

  Iterable<T> findAll();               

  long count();                        

  void delete(T entity);               

  boolean existsById(ID primaryKey);   

  // … more functionality omitted.
}

当你使用更加具体的存储方式的时候,可以使用CrudRepository的子类
We also provide persistence technology-specific abstractions, such as JpaRepository or MongoRepository. Those interfaces extend CrudRepository and expose the capabilities of the underlying persistence technology in addition to the rather generic persistence technology-agnostic interfaces such as CrudRepository.

配置

当你把Entity和Repository都定义好了以后,就需要配置来激活这些Repository,使他们和底层的存储实现联系起来。

@EnableJpaRepositories
class Config {}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(JpaRepositoriesRegistrar.class)
public @interface EnableJpaRepositories {

	/**
	 * Alias for the {@link #basePackages()} attribute. Allows for more concise annotation declarations e.g.:
	 * {@code @EnableJpaRepositories("org.my.pkg")} instead of {@code @EnableJpaRepositories(basePackages="org.my.pkg")}.
	 */
	String[] value() default {};

	/**
	 * Base packages to scan for annotated components. {@link #value()} is an alias for (and mutually exclusive with) this
	 * attribute. Use {@link #basePackageClasses()} for a type-safe alternative to String-based package names.
	 */
	String[] basePackages() default {};

	/**
	 * Type-safe alternative to {@link #basePackages()} for specifying the packages to scan for annotated components. The
	 * package of each class specified will be scanned. Consider creating a special no-op marker class or interface in
	 * each package that serves no purpose other than being referenced by this attribute.
	 */
	Class<?>[] basePackageClasses() default {};

	/**
	 * Specifies which types are eligible for component scanning. Further narrows the set of candidate components from
	 * everything in {@link #basePackages()} to everything in the base packages that matches the given filter or filters.
	 */
	Filter[] includeFilters() default {};

	/**
	 * Specifies which types are not eligible for component scanning.
	 */
	Filter[] excludeFilters() default {};

	/**
	 * Returns the postfix to be used when looking up custom repository implementations. Defaults to {@literal Impl}. So
	 * for a repository named {@code PersonRepository} the corresponding implementation class will be looked up scanning
	 * for {@code PersonRepositoryImpl}.
	 *
	 * @return
	 */
	String repositoryImplementationPostfix() default "Impl";

	/**
	 * Configures the location of where to find the Spring Data named queries properties file. Will default to
	 * {@code META-INF/jpa-named-queries.properties}.
	 *
	 * @return
	 */
	String namedQueriesLocation() default "";

	/**
	 * Returns the key of the {@link QueryLookupStrategy} to be used for lookup queries for query methods. Defaults to
	 * {@link Key#CREATE_IF_NOT_FOUND}.
	 *
	 * @return
	 */
	Key queryLookupStrategy() default Key.CREATE_IF_NOT_FOUND;

	/**
	 * Returns the {@link FactoryBean} class to be used for each repository instance. Defaults to
	 * {@link JpaRepositoryFactoryBean}.
	 *
	 * @return
	 */
	Class<?> repositoryFactoryBeanClass() default JpaRepositoryFactoryBean.class;

	/**
	 * Configure the repository base class to be used to create repository proxies for this particular configuration.
	 *
	 * @return
	 * @since 1.9
	 */
	Class<?> repositoryBaseClass() default DefaultRepositoryBaseClass.class;

	// JPA specific configuration

	/**
	 * Configures the name of the {@link EntityManagerFactory} bean definition to be used to create repositories
	 * discovered through this annotation. Defaults to {@code entityManagerFactory}.
	 *
	 * @return
	 */
	String entityManagerFactoryRef() default "entityManagerFactory";

	/**
	 * Configures the name of the {@link PlatformTransactionManager} bean definition to be used to create repositories
	 * discovered through this annotation. Defaults to {@code transactionManager}.
	 *
	 * @return
	 */
	String transactionManagerRef() default "transactionManager";

	/**
	 * Configures whether nested repository-interfaces (e.g. defined as inner classes) should be discovered by the
	 * repositories infrastructure.
	 */
	boolean considerNestedRepositories() default false;

	/**
	 * Configures whether to enable default transactions for Spring Data JPA repositories. Defaults to {@literal true}. If
	 * disabled, repositories must be used behind a facade that's configuring transactions (e.g. using Spring's annotation
	 * driven transaction facilities) or repository methods have to be used to demarcate transactions.
	 *
	 * @return whether to enable default transactions, defaults to {@literal true}.
	 */
	boolean enableDefaultTransactions() default true;

	/**
	 * Configures when the repositories are initialized in the bootstrap lifecycle. {@link BootstrapMode#DEFAULT}
	 * (default) means eager initialization except all repository interfaces annotated with {@link Lazy},
	 * {@link BootstrapMode#LAZY} means lazy by default including injection of lazy-initialization proxies into client
	 * beans so that those can be instantiated but will only trigger the initialization upon first repository usage (i.e a
	 * method invocation on it). This means repositories can still be uninitialized when the application context has
	 * completed its bootstrap. {@link BootstrapMode#DEFERRED} is fundamentally the same as {@link BootstrapMode#LAZY},
	 * but triggers repository initialization when the application context finishes its bootstrap.
	 *
	 * @return
	 * @since 2.1
	 */
	BootstrapMode bootstrapMode() default BootstrapMode.DEFAULT;

	/**
	 * Configures what character is used to escape the wildcards {@literal _} and {@literal %} in derived queries with
	 * {@literal contains}, {@literal startsWith} or {@literal endsWith} clauses.
	 *
	 * @return a single character used for escaping.
	 */
	char escapeCharacter() default '\\';
}

生成对底层store的操作

repository只定义了我要做什么,没有说明怎么做,这是由具体的实现框架来决定的,框架主要使用如下方法来生成操作:

  • By deriving the query from the method name directly.

  • By using a manually defined query.

我感觉根据名字生成实现非常不靠谱,只能用于简单的查询。

Customizing Individual Repositories

自定义底层实现
1, 定义一个interface

interface CustomizedUserRepository {
  void someCustomMethod(User user);
}

2, 定义这个interface的实现

class CustomizedUserRepositoryImpl implements CustomizedUserRepository {
	@Autowired
	private JdbcTemplate template;

  public void someCustomMethod(User user) {
    // Your custom implementation
  }
}

JdbcTemplate 是注入的CustomizedUserRepositoryImpl 可以当作一个普通的bean

2, 使用自定义的interface

interface UserRepository extends CrudRepository<User, Long>, CustomizedUserRepository {

  // Declare query methods here
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值