Spring-Data

一、Spring Data概述

1、SpringData:Spring的一个子项目。用于简化数据库的访问,支持NoSQL关系数据存储。其主要目标是使数据库的访问变得方便快捷。
2、SpringData项目所支持NoSQL存储
(1)MongoDB(文档数据库)
(2)Neo4j(图形数据库)
(3)Redis(键/值存储)
(4)Hbase(列族数据库)
3、SpringData项目所支持的关系数据库存储技术
(1)JDBC
(2)JPA

二、JPA Spring Data概述

1、JPA Spring Data:致力于减少数据访问层(Dao)的开发量。开发者唯一要做的就是声明持久层的接口,其他的交给SpringDataJPA来帮你完成。
2、框架怎么可能代替开发者实现业务逻辑呢?比如:当有一个UserDao.findUserById()这样一个方法声明,大致应该能判断这是根据给定条件ID查询满足条件的User对象。Spring Data JPA做的便是规范方法的名字,根据规范的名字来确定方法需要什么样的逻辑。
2、JPQL和SQL
(1)JPQL和SQL很像,查询关键字都是一样的
(2)唯一的区别是:JPQL是面向对象的
3、JPQL书写规则
JPA的查询语言,类似于sql
(1)里面不能出现表名,列名,只能出现java的类名,属性名,区分大小写
(2)出现的sql关键字是一样的意思,关键字不区分大小写
(3)不能写select * 要写select 别名

三、使用Spring Data JPA进行持久层开发

1、步骤
(1)配置Spring整合JPA
(2)在Spring配置文件中配置SpringData,让Spring为声明的接口创建代理对象。配置了jsp:repositories后,Spring初始化容器时将会扫描base-package指定的包目录及其子目录,为继承Repository或其子接口的接口创建代理对象,并将代理对象注册为SpringBean,业务层便可以通过Spring自动封装的特性来直接使用该对象。
(3)声明持久层的接口,该接口继承Repository**,Repository是一个标记型接口,它不包含任何方法,如必要,Spring Data 可实现Repsitory其他子接口,其中定义了一些常用的增删改查,以及分页相关的方法。
(4)在接口中声明需要的方法。Spring Data将根据给定的策略来为其生成实现代码。

2、Repository接口
(1)Repository是一个空接口。即是一个标记接口。
(2)若我们定义的接口继承了Repository,则此接口会被IOC容器识别为一个Repository-Bean,纳入到IOC容器中,进而可以在此接口中定义满足一定规范的方法。
(3)实际上,也可以通过@RepositoryDefinition(dmainClass=Person.class,idClass=Integer.calss)注解来替代继承Repository接口。(dmainClass指定处理持久化类的类型,idClass指定主键的类型)
(4)Repository的子接口
A、Repository:仅仅是一个标识,表明任何继承它的均为仓库接口类。
B、CrudRepository:继承Repository,实现了一组CRUD相关的方法。
C、PagingAndSortingRepository:继承CrudRepository,实现了一组分页排序相关的方法。
D、JpaRepository:继承了PagingAndSortingRepository,实现一组JPA规范相关的方法。
E、自定义的XxxRepository需要继承JpaRepository,这样XxxRepository接口就具备了通用的数据访问控制层的能力。
F、JpaSpecificationExecutor:不属于Repository体系,实现一组JPA Criteria查询相关的方法。

3、SpringData Repository查询方法定义规范
(1)在Repository子接口中声明方法
A、不是随便声明的,而要符合一定的规范
B、简单条件查询:查询某一个实体类或者集合
a、按照SpringData规范,查询方法以find | read | get开头,涉及条件查询时,条件的属性用条件关键字连接,需要注意的是:条件属性以首字母大写。
例:定义一个Entity实体类

class User{
	private String firstName;
	private String lastName; 	 	 	 	
}

使用And条件连接时,应该这样写:
findByLastNameAndFirstName(String lastName,String FirstName);
条件的属性名称与个数要与参数的位置与个数一一对应。
(2)支持的关键字
A、直接在接口中定义查询方法,如果是符合规范的,可以不用写实现,目前支持的关键字写法如下:

关键字方法命名sql where字句
AndfindByNameAndPwdwhere name= ? and pwd =?
OrfindByNameOrSexwhere name= ? or sex=?
Is,EqualsfindById,findByIdEqualswhere id= ?
BetweenfindByIdBetweenwhere id between ? and ?
LessThanfindByIdLessThanwhere id < ?
LessThanEqualsfindByIdLessThanEqualswhere id <= ?
GreaterThanfindByIdGreaterThanwhere id > ?
GreaterThanEqualsfindByIdGreaterThanEqualswhere id > = ?
AfterfindByIdAfterwhere id > ?
BeforefindByIdBeforewhere id < ?
IsNullfindByNameIsNullwhere name is null
isNotNull,NotNullfindByNameNotNullwhere name is not null
LikefindByNameLikewhere name like ?
NotLikefindByNameNotLikewhere name not like ?
StartingWithfindByNameStartingWithwhere name like ‘?%’
EndingWithfindByNameEndingWithwhere name like ‘%?’
ContainingfindByNameContainingwhere name like ‘%?%’
OrderByfindByIdOrderByXDescwhere id=? order by x desc
NotfindByNameNotwhere name <> ?
InfindByIdIn(Collection<?> c)where id in (?)
NotInfindByIdNotIn(Collection<?> c)where id not in (?)
TruefindByAaaTuewhere aaa = true
FalsefindByAaaFalsewhere aaa = false
IgnoreCasefindByNameIgnoreCasewhere UPPER(name)=UPPER(?)
CountcountByFirstNameselect count(*) from … where x.firstName = ?1
ExistsexistsByFirstNamelike the dao.exists(Example),judge by attribution of firstName:select keyindex0_.id as col_0_0_ from key_index keyindex0_ where keyindex0_.name=? limit ?

(3)支持级联查询,但是若果当前类有符合条件的属性,则优先类属性忽略级联属性。若需要使用级联属性则属性之间用‘_’进行连接。
例如

class Person{
	private Integer addressId;
	private Address address;
	//setter方法
	@Column(name="ADD_ID")
	public int getAddressId(){
		return addressId;
	}
	//其他getter方法
}
class Address{
	//..
	private Integer id;
}

当请求:

List<Person> getByAddressIdGreaterThan(Integer id);//会请求Person类中的addressId属性而不是级联属性。

如果需要使用级联属性:

List<Person> getByAddress_IdGreaterThan(Integer id);

4、SpringData @Query注解
(1)使用@Query注解可以自定义JPQL语句以实现更灵活的查询.
(2)@Query注解传递参数的方式1:使用占位符
例:

@Query("Select p FROM Person p WHERE p.lastName = ?1 AND p.email = ?2")
List<Person> testQueryAnnotationParams1(String lastName,String email);//参数需按照1.2...顺序

(3)@Query注解传递参数的方式2:命名参数
例:

@Query("Select p FROM Person p WHERE p.lastName = :lastName AND p.email = :email")
List<Person> testQueryAnnotationParams1(@Param("email")String email,@Param("lastName")String lastName);//这时参数的顺序不影响,只需参数名跟‘:’后一致就可以。

:SpringData允许占位符上添加%%
A、方式1:

@Query("Select p FROM Person p WHERE p.lastName LIKE %?1% OR p.email LIKE %?2%")
List<Person> testQueryAnnotationParams1(String lastName,String email);//参数需按照1.2...顺序

B、方式2:

@Query("Select p FROM Person p WHERE p.lastName LIKE %:lastName% OR p.email LIKE %:email%")
List<Person> testQueryAnnotationParams1(@Param("email")String email,@Param("lastName")String lastName);//这时参数的顺序不影响,只需参数名跟‘:’后一致就可以。

(4)设置nativeQuery=true即可使用原生的SQL查询
例:

@Query(value="SELECT count(id) FROM student ",nativeQuery=true)
long getTotalCount();

5、SpringData @Modifying注解
(1)可以通过自定义的JPQL完成UPDATE、和DELETE操作。注意:JPQL不支持INSERT
(2)在@Query中编写JPQL语句,但必须使用@Modifying进行修饰(通知SpringData这是一个UPDATE或DELETE操作)。
(3)UPDATE或DELETE操作需要使用事务,此时需要在Service层上面添加事务操作。
(4)默认情况下,SpringData的每个方法上都有事务,但是一个只读事务,它们不足以完成修改删除操作。
例:

@Modifying
@Query("UPDATE Person p SET p.email 	=:email WHERE  id = :id")
void updatePersonEmail(@Param("id") Integer id,@Param("email") String email);

6、JpaRepository接口

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值