spring-data-jpa初识

一、jpa、spring-data-jpa、mybatis、hibernate认识?

jpa:Java Persistence API、java持久层api(简言之:全是接口规范)

spring-data-jpa:spring家族实现jpa规范的框架称为:spring-data-jpa,易处理类似于单表CRUD,较为依赖实体

mybatis:半自动ORM框架,灵活度较高,易处理复杂sql

hibernate:全自动ORM框架、上手较mybatis难,易处理类似于单表CRUD,较为依赖实体

mybatis-plus:类似于spring-data-jpa提供了一系列CRUD接口,较为依赖实体

二、spring-data-jpa主要接口

CrudRepository接口(CRUD操作):

//CrudRepository接口使用
public interface UserRepository extends CrudRepository<User, Integer> {}
//CrudRepository接口源码
@NoRepositoryBean
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> {
	<S extends T> S save(S entity);//保存
	<S extends T> Iterable<S> save(Iterable<S> entities);//批量保存
	T findOne(ID id);//根据id查询一个对象
	boolean exists(ID id);//判断对象是否存在
	Iterable<T> findAll();//查询所有的对象
	Iterable<T> findAll(Iterable<ID> ids);//根据id列表查询所有的对象
	long count();//计算对象的总个数
	void delete(ID id);//根据id删除
	void delete(T entity);//删除对象
	void delete(Iterable<? extends T> entities);//批量删除
	void deleteAll();//删除所有
}

PagingAndSortingRepository接口(分类、排序)继承了CrudRepository接口

//PagingAndSortingRepository接口使用
public interface UserRepositoryWithOrder extends PagingAndSortingRepository<User,Integer> {}
//PagingAndSortingRepository接口源码
@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
	Iterable<T> findAll(Sort sort);// 不带分页的排序
	Page<T> findAll(Pageable pageable);// 带分页的排序
}

JpaRepository接口

如果业务需要即提供CRUD操作,又需要提供分页以及排序功能,那么就可以直接继承这个接口。

该接口继承了PagingAndSortingRepository接口

//JpaRepository接口源码
public interface JpaRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID> {
	List<T> findAll();//查询所有对象,不排序
	List<T> findAll(Sort sort);//查询所有对象,并排序
	<S extends T> List<S> save(Iterable<S> entities);//批量保存
	void flush();//强制缓存与数据库同步
	T saveAndFlush(T entity);//保存并强制同步
	void deleteInBatch(Iterable<T> entities);//批量删除
	void deleteAllInBatch();//删除所有
}

JpaSpecificationExecutor接口相对特殊,一般用于相对复杂查询

三、上面的满足一些基本CRUD需求、自定义查询方式?

1.@Query 创建查询(类似于mybatis的@Mapper注解功能,个人倾向于使用@Mapper注解)

/**
 * 描述:自定义查询,当Spring Data JPA无法提供时,需要自定义接口,此时可以使用这种方式
 */
public interface UserDefineBySelf extends JpaRepository<User, Integer> {
	/**
	 * 命名参数
	 * 描述:推荐使用这种方法,可以不用管参数的位置
	 */
	@Query("select u from User u where u.name = :name")
	User findUserByName(@Param("name") String name);
	
	/**
	 * 索引参数
	 * 描述:使用?占位符
	 */
	@Query("select u from User u where u.email = ?1")// 1表示第一个参数
	User findUserByEmail(String email);
	
	/**
	 * 描述:可以通过@Modifying和@Query来实现更新
	 * 注意:Modifying queries的返回值只能为void或者是int/Integer
	 */
	@Modifying
	@Query("update User u set u.name = :name where u.id = :id")
	int updateUserById(@Param("name") String name, @Param("id") int id);
}

2.使用@NamedQueries创建查询

3.通过解析方法名创建查询

public interface SimpleConditionQueryRepository extends JpaRepository<User, Integer> {
	/**
	 * 说明:按照Spring data 定义的规则,查询方法以find|read|get开头
     * 涉及条件查询时,条件的属性用条件关键字连接,要注意的是:条件属性首字母需大写
	 */
	
	
	
	/**
	 * 注:此处这个接口相当于发送了一条SQL:select u from User u where u.name = :name and u.email = :email
	 * 参数名大写,条件名首字母大写,并且接口名中参数出现的顺序必须和参数列表中的参数顺序一致
	 */
	User findByNameAndEmail(String name, String email);
	
	/**
	 * 注:此处这个接口相当于发送了一条SQL:select u from User u where u.name = ?1 or u.password = ?2
	 */
	List<User> findByNameOrPassword(String name, String password);
	
	/**
	 * 注:此处这个接口相当于发送了一条SQL:select u from User u where u.id between ?1 and ?2
	 */
	List<User> findByIdBetween(Integer start, Integer end);
	
	/**
	 * 注:此处这个接口相当于发送了一条SQL:select u from User u where u.id < ?1
	 */
	List<User> findByIdLessThan(Integer end);
	
	/**
	 * 注:此处这个接口相当于发送了一条SQL:select u from User u where u.id > ?1
	 */
	List<User> findByIdGreaterThan(Integer start);
	
	/**
	 * 注:此处这个接口相当于发送了一条SQL:select u from User u where u.name is null
	 */
	List<User> findByNameIsNull();
	
	/**
	 * 注:此处这个接口相当于发送了一条SQL:select u from User u where u.name is not null
	 */
	List<User> findByNameIsNotNull();
	
	/**
	 * 注:此处这个接口相当于发送了一条SQL:select u from User u where u.name like ?1
	 */
	List<User> findByNameLike(String name);
	
	/**
	 * 注:此处这个接口相当于发送了一条SQL:select u from User u where u.name not like ?1
	 */
	List<User> findByNameNotLike(String name);
	
	/**
	 * 注:此处这个接口相当于发送了一条SQL:select u from User u where u.password = ?1 order by u.id desc
	 */
	List<User> findByPasswordOrderByIdDesc(String password);
	
	/**
	 * 注:此处这个接口相当于发送了一条SQL:select u from User u where u.name <> ?1
	 */
	List<User> findByNameNot(String name);
	
	/**
	 * 注:此处这个接口相当于发送了一条SQL:select u from User u where u.id in ?1
	 */
	List<User> findByIdIn(List<Integer> ids);
	
	/**
	 * 注:此处这个接口相当于发送了一条SQL:select u from User u where u.id not in ?1
	 */
	List<User> findByIdNotIn(List<Integer> ids);
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:applicationContext-config.xml" })
@TransactionConfiguration(defaultRollback = false)
@Transactional
public class SimpleConditionQueryRepositoryTest {
	@Autowired
	private SimpleConditionQueryRepository dao;
	
	/**
	 * select
        user0_.id as id0_,
        user0_.account as account0_,
        user0_.email as email0_,
        user0_.name as name0_,
        user0_.password as password0_ 
    from
        USER user0_ 
    where
        user0_.name=? 
        and user0_.email=? limit ?
	 */
	@Test
	public void testFindUserByNameAndEmail(){
		User user = dao.findByNameAndEmail("chhliu", "chhliu@.com");
		System.out.println(JSON.toJSONString(user));
	}
	
	/**
	 * select
        user0_.id as id1_,
        user0_.account as account1_,
        user0_.email as email1_,
        user0_.name as name1_,
        user0_.password as password1_ 
    from
        USER user0_ 
    where
        user0_.name=? 
        or user0_.password=?
	 */
	@Test
	public void testFindUserByNameOrPassword(){
		List<User> users = dao.findByNameOrPassword("chhliu", "123456");
		System.out.println(JSON.toJSONString(users));
	}
	
	/**
	 * select
        user0_.id as id1_,
        user0_.account as account1_,
        user0_.email as email1_,
        user0_.name as name1_,
        user0_.password as password1_ 
    from
        USER user0_ 
    where
        user0_.id between ? and ?
	 */
	@Test
	public void testFindByIdBetween(){
		List<User> users = dao.findByIdBetween(5, 8);
		System.out.println(JSON.toJSONString(users));
	}
	
	/**
	 * select
        user0_.id as id1_,
        user0_.account as account1_,
        user0_.email as email1_,
        user0_.name as name1_,
        user0_.password as password1_ 
    from
        USER user0_ 
    where
        user0_.id<?
	 */
	@Test
	public void testFindByIdLessThan(){
		List<User> users = dao.findByIdLessThan(4);
		System.out.println(JSON.toJSONString(users));
	}
	
	/**
	 * select
        user0_.id as id0_,
        user0_.account as account0_,
        user0_.email as email0_,
        user0_.name as name0_,
        user0_.password as password0_ 
    from
        USER user0_ 
    where
        user0_.id>?
	 */
	@Test
	public void testFindByIdGreaterThan(){
		List<User> users = dao.findByIdGreaterThan(6);
		System.out.println(JSON.toJSONString(users));
	}
	
	/**
	 * select
        user0_.id as id0_,
        user0_.account as account0_,
        user0_.email as email0_,
        user0_.name as name0_,
        user0_.password as password0_ 
    from
        USER user0_ 
    where
        user0_.name is null
	 */
	@Test
	public void testFindByNameIsNull(){
		List<User> users = dao.findByNameIsNull();
		System.out.println(JSON.toJSONString(users));
	}
	
	/**
	 * select
        user0_.id as id1_,
        user0_.account as account1_,
        user0_.email as email1_,
        user0_.name as name1_,
        user0_.password as password1_ 
    from
        USER user0_ 
    where
        user0_.name is not null
	 */
	@Test
	public void testFindByNameIsNotNull(){
		List<User> users = dao.findByNameIsNotNull();
		System.out.println(JSON.toJSONString(users));
	}
	
	/**
	 * select
        user0_.id as id1_,
        user0_.account as account1_,
        user0_.email as email1_,
        user0_.name as name1_,
        user0_.password as password1_ 
    from
        USER user0_ 
    where
        user0_.name like ?
	 */
	@Test
	public void testFindByNameLike(){
		List<User> users = dao.findByNameLike("chhliu");
		System.out.println(JSON.toJSONString(users));
	}
	
	/**
	 * select
        user0_.id as id0_,
        user0_.account as account0_,
        user0_.email as email0_,
        user0_.name as name0_,
        user0_.password as password0_ 
    from
        USER user0_ 
    where
        user0_.name not like ?
	 */
	@Test
	public void testFindByNameNotLike(){
		List<User> users = dao.findByNameNotLike("chhliu");
		System.out.println(JSON.toJSONString(users));
	}
	
	/**
	 * select
        user0_.id as id0_,
        user0_.account as account0_,
        user0_.email as email0_,
        user0_.name as name0_,
        user0_.password as password0_ 
    from
        USER user0_ 
    where
        user0_.password=? 
    order by
        user0_.id desc
	 */
	@Test
	public void testFindByPasswordOrderByIdDesc(){
		List<User> users = dao.findByPasswordOrderByIdDesc("123456");
		System.out.println(JSON.toJSONString(users));
	}
	
	/**
	 * select
        user0_.id as id1_,
        user0_.account as account1_,
        user0_.email as email1_,
        user0_.name as name1_,
        user0_.password as password1_ 
    from
        USER user0_ 
    where
        user0_.name<>?
	 */
	@Test
	public void testFindByNameNot(){
		List<User> users = dao.findByNameNot("chhliu");
		System.out.println(JSON.toJSONString(users));
	}
	
	/**
	 * select
        user0_.id as id1_,
        user0_.account as account1_,
        user0_.email as email1_,
        user0_.name as name1_,
        user0_.password as password1_ 
    from
        USER user0_ 
    where
        user0_.id in (
            ? , ? , ? , ?
        )
	 */
	@Test
	public void testFindByIdIn(){
		List<User> users = dao.findByIdIn(new ArrayList<Integer>(Arrays.asList(3,4,6,8)));
		System.out.println(JSON.toJSONString(users));
	}
	
	/**
	 * select
        user0_.id as id0_,
        user0_.account as account0_,
        user0_.email as email0_,
        user0_.name as name0_,
        user0_.password as password0_ 
    from
        USER user0_ 
    where
        user0_.id not in  (
            ? , ? , ? , ?
        )
	 */
	@Test
	public void testFindByIdNotIn(){
		List<User> users = dao.findByIdNotIn(new ArrayList<Integer>(Arrays.asList(3,4,6,8)));
		System.out.println(JSON.toJSONString(users));
	}
}

解析规则:

And --- 等价于 SQL 中的 and 关键字,比如 findByUsernameAndPassword(String user, Striang pwd)

Or --- 等价于 SQL 中的 or 关键字,比如 findByUsernameOrAddress(String user, String addr)

Between --- 等价于 SQL 中的 between 关键字,比如 findBySalaryBetween(int max, int min)

LessThan --- 等价于 SQL 中的 "<",比如 findBySalaryLessThan(int max)

GreaterThan --- 等价于 SQL 中的">",比如 findBySalaryGreaterThan(int min)

IsNull --- 等价于 SQL 中的 "is null",比如 findByUsernameIsNull()

IsNotNull --- 等价于 SQL 中的 "is not null",比如 findByUsernameIsNotNull()

NotNull --- 与 IsNotNull 等价

Like --- 等价于 SQL 中的 "like",比如 findByUsernameLike(String user)

NotLike --- 等价于 SQL 中的 "not like",比如 findByUsernameNotLike(String user)

OrderBy ---等价于 SQL 中的 "order by",比如 findByUsernameOrderBySalaryAsc(String user)

Not --- 等价于 SQL 中的 "! =",比如 findByUsernameNot(String user)

In --- 等价于 SQL 中的 "in",比如 findByUsernameIn(Collection<String> userList) ,方法的参数可以是 Collection 类型,也可以是数组或者不定长参数

NotIn --- 等价于 SQL 中的 "not in",比如 findByUsernameNotIn(Collection<String> userList) ,方法的参数可以是 Collection 类型,也可以是数组或者不定长参数

四、创建查询的顺序

上述三种查询顺序的优先级是啥呢?(布吉岛有默认没,默认是啥咱也不清楚,咱也不敢问)

Spring Data JPA 在为接口创建代理对象时,如果发现同时存在多种上述情况可用,它该优先采用哪种策略呢?为此, 提供了 query-lookup-strategy 属性,用以指定查找的顺序。它有如下三个取值:
create — 通过解析方法名字来创建查询。即使有符合的命名查询,或者方法通过 @Query 指定的查询语句,都将会被忽略。
create-if-not-found — 如果方法通过 @Query 指定了查询语句,则使用该语句实现查询;如果没有,则查找是否定义了符合条件的命名查询,如果找到,则使用该命名查询;如果两者都没有找到,则通过解析方法名字来创建查询。这是 query-lookup-strategy 属性的默认值。
use-declared-query — 如果方法通过 @Query 指定了查询语句,则使用该语句实现查询;如果没有,则查找是否定义了符合条件的命名查询,如果找到,则使用该命名查询;如果两者都没有找到,则抛出异常。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值