springdata教程

github:https://github.com/leelun/springdata-example

Spring Data

Spring 的一个子项目。用于简化数据库访问,支持NoSQL 和 关系数据存储。其主要目标是使数据库的访问变得方便快捷。

SpringData 项目所支持 NoSQL 存储:

MongoDB (文档数据库)

Neo4j(图形数据库)

Redis(键/值存储)

Hbase(列族数据库)

SpringData 项目所支持的关系数据存储技术

JDBC、JPA

 

JPA Spring Data

致力于减少数据访问层 (DAO) 的开发量.开发者唯一要做的,就只是声明持久层的接口,其他都交给 Spring Data JPA 。

Spring Data JPA 做的便是规范方法的名字,根据符合规范的名字来确定方法需要实现什么样的逻辑。

例如:UserDao.findUserById()  这样一个方法声明,大致应该能判断出这是根据给定条件的 ID 查询出满足条件的User对象。

Repository 接口

Repository是 Spring Data 的一个核心接口,它不提供任何方法,开发者需要在自己定义的接口中声明需要的方法 。

Spring Data可以让我们只定义接口,只要遵循 Spring Data的规范,就无需写实现类。 

与继承 Repository 等价的一种方式,就是在持久层接口上使用 @RepositoryDefinition 注解,并为其指定 domainClass 和 idClass 属性。

Repository 的子接口

Repository: 仅仅是一个标识,表明任何继承它的均为仓库接口类

CrudRepository: 继承 Repository,实现了一组 CRUD 相关的方法 

PagingAndSortingRepository: 继承 CrudRepository,实现了一组分页排序相关的方法 

JpaRepository: 继承 PagingAndSortingRepository,实现一组 JPA 规范相关的方法 

自定义的 XxxxRepository 需要继承 JpaRepository,这样的 XxxxRepository 接口就具备了通用的数据访问控制层的能力。

JpaSpecificationExecutor: 不属于Repository体系,实现一组 JPA Criteria 查询相关的方法 

 

SpringData 方法定义规范

按照 Spring Data 的规范,查询方法以 find | read | get 开头。

涉及条件查询时,条件的属性用条件关键字连接,要注意的是:条件属性以首字母大写。 

例如:定义一个 Entity 实体类 
class User{ 
private String firstName; 
private String lastName; 
} 
使用And条件连接时,应这样写: 
findByLastNameAndFirstName(String lastName,String firstName); 
条件的属性名称与个数要与参数的位置与个数一一对应 

支持的关键字

查询方法解析流程

对于精准属性查询可以明确在属性之间加上 "_" 以显式表达意图

例如:"findByUser_DepUuid()" 或者 "findByUserDep_uuid()"

“_”是对属性进行拆分。

 

特殊的参数: 还可以直接在方法的参数上加入分页或排序的参数,比如:

Page<UserModel> findByName(String name, Pageable pageable);

List<UserModel> findByName(String name, Sort sort);

@Query

可以在接口上面自定义查询语句。

@Query("SELECT p FROM Person p WHERE p.lastName = ?1 AND p.email = ?2")

List<Person> testQueryAnnotationParams1(String lastName, String email);

查询中 ?n” 个数需要与方法定义的参数个数相一致,并且顺序也要一致 

也可以在查询中用@Param直接指定接受参数的name

@Query("SELECT p FROM Person p WHERE p.lastName = :lastName AND p.email = :email")

List<Person> testQueryAnnotationParams2(@Param("email") String email, @Param("lastName") String lastName);

通过显示指定nativeQuery为true实现本地查询

@Query(value="SELECT count(id) FROM jpa_persons", nativeQuery=true)

long getTotalCount();

@Modifying

@Modifying与@Query一起声明,用来指定@Query中的语句修改或删除操作。

注意: JPQL 不支持使用 INSERT。(保存操作调用JpaRepository save

默认情况下, SpringData 的每个方法上有事务, 但都是一个只读事务. 他们不能完成修改操作!

事务

Spring Data 提供了默认的事务处理方式,即所有的查询均声明为只读事务。

如需改变 Spring Data 提供的事务默认方式,可以在方法上注解 @Transactional 声明

 

CrudRepository

该接口提供了最基本的对实体类的添删改查操作 。

T save(T entity);//保存单个实体 

Iterable<T> save(Iterable<? extends T> entities);//保存集合       

T findOne(ID id);//根据id查找实体        

boolean exists(ID id);//根据id判断实体是否存在        

Iterable<T> findAll();//查询所有实体,不用或慎用!        

long count();//查询实体数量        

void delete(ID id);//根据Id删除实体        

void delete(T entity);//删除一个实体 

void delete(Iterable<? extends T> entities);//删除一个实体集合        

void deleteAll();//删除所有实体。

PagingAndSortingRepository

该接口提供了分页与排序功能 。

Iterable<T> findAll(Sort sort); //排序

Page<T> findAll(Pageable pageable); //分页查询(含排序功能)

JpaRepository

该接口提供了JPA的相关功能 。

List<T> findAll(); //查找所有实体

List<T> findAll(Sort sort); //排序、查找所有实体

List<T> save(Iterable<? extends T> entities);//保存集合

void flush();//执行缓存与数据库同步

T saveAndFlush(T entity);//强制执行持久化

void deleteInBatch(Iterable<T> entities);//删除一个实体集合

JpaSpecificationExecutor

该接口实现了一组 JPA Criteria 查询相关的方法 。

T findOne(Specification<T>  t) :查询单结果。

 

Specification:封装JPA Criteria查询条件。

 

自定义 Repository 方法

1 为指定Repository 添加自定义方法

步骤示例:

(1) 定义自定义接口

public interface PersonDao {

//通过定义自定义方法

void test();

}

(2) 让当前xxxRepository接口继承PersonDao

public interface PersonRepository

extends JpaRepository<Person, Integer>, JpaSpecificationExecutor<Person>, PersonDao {

//直接在当前xxxRepository中自定义方法

void test1();

}

(3) 实现自定义方法

在当前xxxRepository接口package下创建xxxRepositoryImpl,并且实现自定义方法

public class PersonRepositoryImpl implements PersonDao{



@PersistenceContext

private EntityManager entityManager;



@Override

public void test() {

Person person = entityManager.find(Person.class, 11);

System.out.println("-->" + person);

}



public void test2() {

System.out.println(entityManager.createQuery("FROM Person o").getResultList().size());

}

}

 默认情况下, Spring Data 会在 base-package 中查找 "接口名Impl" 作为实现类. 也可以通过 repository-impl-postfix 声明后缀.

<jpa:repositories base-package="com.springdata"

entity-manager-factory-ref="entityManagerFactory" repository-impl-postfix="Impl"></jpa:repositories>

2 为所有的 Repository 都添加自实现的方法

(1) 声明继承 Spring Data 的 Repository的接口, 在该接口中声明自定义方法。

@NoRepositoryBean

public interface CommonMethodTest<T, ID extends Serializable>

extends JpaRepository<T, ID>{



void method();



}

(2) 实现声明接口,并且继承SimpleJpaRepository

@NoRepositoryBean

public class CommonMethodTestImpl<T, ID extends Serializable>

extends SimpleJpaRepository<T, ID> implements CommonMethodTest<T, ID> {



public CommonMethodTestImpl(Class<T> domainClass, EntityManager em) {

super(domainClass, em);

}



@Override

public void method() {

System.out.println("...METHOD TEST...");

}



}

(3) 创建继承JpaRepositoryFactoryBean 的类,指定自定义方法的接口。

public class CommonJpaRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable>

extends JpaRepositoryFactoryBean<T, S, ID> {



protected RepositoryFactorySupport createRepositoryFactory(

EntityManager entityManager) {

return new CommonRepositoryFactory(entityManager);

}



private static class CommonRepositoryFactory<T, I extends Serializable>

extends JpaRepositoryFactory {



private EntityManager entityManager;



public CommonRepositoryFactory(EntityManager entityManager) {

super(entityManager);

this.entityManager = entityManager;

}



protected Object getTargetRepository(RepositoryMetadata metadata) {

return new CommonMethodTestImpl<T, I>(

(Class<T>) metadata.getDomainType(), entityManager);

}



protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {

return CommonMethodTest.class;

}

}



}

(4) 配置 <jpa:repositories /> 节点的 factory-class 属性指向(3)创建的类

<jpa:repositories base-package="com.springdata.commonrepositorymethod"

entity-manager-factory-ref="entityManagerFactory"

factory-class="com.springdata.commonrepositorymethod.CommonJpaRepositoryFactoryBean"></jpa:repositories>

 

 

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Spring Data JPA 是一个用于简化数据库访问的框架,它基于 JPA (Java Persistence API) 规范,提供了一种更简单、更高效的方式来访问和操作数据库。 下面是使用 Spring Data JPA 的一般步骤: 1. 添加依赖:在你的项目中,添加 Spring Data JPA 的依赖。你可以在 Maven 或 Gradle 配置文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> ``` 2. 配置数据库连接:在 `application.properties` 或 `application.yml` 文件中配置数据库连接信息,包括数据库 URL、用户名、密码等。 3. 创建实体类:创建与数据库表对应的实体类,并使用 JPA 注解来映射实体类与数据库表之间的关系。 ```java @Entity @Table(name = "users") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private Integer age; // getters and setters } ``` 4. 创建 Repository 接口:创建一个继承自 `JpaRepository` 的接口,并通过方法命名规则或自定义查询方法来定义数据库操作。 ```java public interface UserRepository extends JpaRepository<User, Long> { List<User> findByAgeGreaterThan(Integer age); } ``` 5. 使用 Repository:在需要访问数据库的地方,注入 Repository 接口,并调用其中的方法进行数据库操作。 ```java @Service public class UserService { @Autowired private UserRepository userRepository; public List<User> getUsersByAgeGreaterThan(Integer age) { return userRepository.findByAgeGreaterThan(age); } } ``` 这只是 Spring Data JPA 的基本用法,你还可以使用更高级的特性,如分页、排序、复杂查询等。希望这些信息对你有帮助!如果你有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值