ORM,JPA,Hibernate,Spring data jpa 之间的缘分

1. ORM

      ORM——Object Relational Mapping,即对象关系映射,实质是表示内存中的对象与关系型数据库之间的映射关系。

2. JPA

      JPA全称Java Persistence API,可以通过注解或者XML描述对象-关系表之间的映射关系,并将实体对象持久化到数据库中。

3. JPA的功能

      1. 提供ORM映射元数据,JPA支持XML和注解两种元数据的形式,元数据描述对象与表之间的映射关系,ORM框架则根据这种映射关系将实体对象映射到数据库中。

      2. 提供持久层的API,用来操作实体对象,执行CURD操作,ORM框架替开发者完成所有的事情,开发者无需关注JDBC以及SQL代码的编写。

      3. 提供JPQL(Java Persistence Query Language),即Java持久化查询语言,一种面向对象而非面向数据库的查询语言进行数据查询,避免程序的SQL语句紧密耦合。

总结:JPA仅仅是一种规范,也就是说JPA仅仅定义了一些接口,而Hibernate是实现JPA接口的ORM框架。即JPA是ORM规范,Hibernate是实现这种规范的一种ORM框架。

JPA规范与ORM框架之间的关系

4. Spring data jpa

      Spring data jpa是spring提供的一套简化JPA开发的框架,按照约定编写好DAO层接口,就可以在不实现接口的情况下实现对数据库的访问和操作,同时提供了很多处理CURD的功能,如分页,排序,复杂的查询等。Spring data JPA可以理解为JPA规范的再次封装抽象,底层使用的是Hibernate的JPA技术实现。

Spring data jpa,JPA以及ORM框架之间的关系

3.1 按照约定命名规则

Spring data jpa接口约定命名规范
序号关键字方法名称Sql语句where字句(JPQL Snippet)
1AndfindByLastnameAndFirstnamewhere Lastname = ? and Firstname = ?
2OrfindByLastnameOrFirstnamewhere Lastname = ? or Firstname = ?
3Is,EqualsfindByFirstname,findByFirstnIs,findByFirstnameEqualswhere Firstname = ?
4BetweenfindByStartDateBetweenwhere startDate between ? and ? 
5LessThanfindByAgeLessThanwhere age < ?
6LessThanEqualsfindByAgeLessThanEqualswhere age <= ?
7GreaterThanfindByAgeGreaterwhere age > ?
8GreaterThanEqualsfindByAgeGreaterEqualswhere age >= ?
9AfterfindByStartDateAfterwhere startDate > ?
10BeforefindByStartDateBeforewhere startDate < ?
11IsNullfindByAgeIsNullwhere Age is null
12isNotNull,NotNullfindByAge(Is)NotNullwhere Age is not null
13LikefindByFirstnameLikewhere firstname like ?
14NotLikefindByFirstnameeNotLikewhere firstname not like ?
15StartingWithfindByFirstnameStartingWithwhere firstname like "?%"
16EndingWithfindByFirstnameEndingWithwhere firstname like "%?"
17ContainingfindByFirstnameContainingwhere firstname like "%?%"
18OrderByfindByAgeOrderByLastnameDescwhere name age = ? order by Lastname desc
19NotfindByAgeNotwhere age <> ?
20InfindByAgeIn(Collection<Age> ages)where age in (?)
21NotInfindByAgeNotIn(Collection<Age> ages)where age not in (?)
22TruefindByActiveTruewhere active = true
23FalsefindByActiveFalsewhere active = false
24IgnoreCasefindByFirstnameIgnoreCasewhere UPPER(firstname) = UPPER(?)

创建测试数据库

CREATE DATABASE testDB;
CREATE TABLE `test_jpa`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `first_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `last_name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `sex` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `email` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `age` int(12) NOT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

示例代码:

public interface TestJpaRepositories extends JpaRepository<TestJpa,Integer> {

    //根据firstName与LastName查找(两者必须在数据库有)
    TestJpa findByFirstNameAndLastName(String firstName, String lastName);

    //根据firstName或LastName查找(两者其一有就行)
    TestJpa findByLastNameOrFirstName(String lastTestName,String firstName);

    //根据firstName查找它是否存在数据库里<类似与以下关键字>
    //TestJpa findByFirstName(String firstName);
    TestJpa findByFirstNameIs(String firstName);

    //在Age数值age到age2之间的数据
    List<TestJpa> findByAgeBetween(Integer age, Integer age2);

    //小于指定age数值之间的数据
    List<TestJpa> findByAgeLessThan(Integer age);

    //小于等于指定age数值的数据
    List<TestJpa> findByAgeLessThanEqual(Integer age);

    //大于指定age数值之间的数据
    List<TestJpa> findByAgeGreaterThan(Integer age);

    //大于或等于指定age数值之间的数据
    List<TestJpa> findByAgeGreaterThanEqual(Integer age);

    //在指定age数值之前的数据类似关键字<LessThan>
    List<TestJpa> findByAgeAfter(Integer age);

    //在指定age数值之后的数据类似关键字<GreaterThan>
    List<TestJpa>  findByAgeBefore(Integer age);

    //返回age字段为空的数据
    List<TestJpa> findByAgeIsNull();

    //返回age字段不为空的数据
    List<TestJpa> findByAgeNotNull();

    /**
     * 该关键字我一度以为是类似数据库的模糊查询,
     * 但是我去官方文档看到它里面并没有通配符。
     * 所以我觉得它类似
     * TestJpa findByFirstName(String firstName);
     * @see https://docs.spring.io/spring-data/jpa/docs/2.1.5.RELEASE/reference/html/#jpa.repositories
     */
    TestJpa findByFirstNameLike(String firstName);

    //同上
    List<TestJpa> findByFirstNameNotLike(String firstName);

    //查找数据库中指定类似的名字(如:输入一个名字"M" Jpa会返回多个包含M开头的名字的数据源)<类似数据库模糊查询>
    List<TestJpa> findByFirstNameStartingWith(String firstName);

    //查找数据库中指定不类似的名字(同上)
    List<TestJpa> findByFirstNameEndingWith(String firstName);

    //查找包含的指定数据源(这个与以上两个字段不同的地方在与它必须输入完整的数据才可以查询)
    List<TestJpa> findByFirstNameContaining(String firstName);

    //根据age选取所有的数据源并按照LastName进行升序排序
    List<TestJpa> findByAgeOrderByLastName(Integer age);

    //返回不是指定age的所有数据
    List<TestJpa> findByAgeNot(Integer age);

    //查找包含多个指定age返回的数据
    List<TestJpa> findByAgeIn(List<Integer> age);
}

基于Junit4的单元测试(测试有效)

@SpringBootTest
@RunWith(SpringRunner.class)
@Slf4j
public class TestJpaRepositoriesTest {

    @Autowired
    private TestJpaRepositories repositories;

    @Test
    public void findByFirstNameAndLastName() {
        TestJpa testJpa = repositories.findByFirstNameAndLastName("May", "Eden");
        Assert.assertEquals(testJpa.getFirstName(),"May");
    }

    @Test
    public void findByLastNameOrFirstName() {
        TestJpa testJpa = repositories.findByLastNameOrFirstName("Geordie", "Eden");
        Assert.assertNotEquals(testJpa.getLastName(),"Eden");
    }

    @Test
    public void findByFirstNameIs() {
        TestJpa testJpa = repositories.findByFirstNameIs("amy");
        Assert.assertNull(testJpa);
    }

    @Test
    public void findByAgeBetween() {
        List<TestJpa> testJpaList = repositories.findByAgeBetween(15, 17);
        Assert.assertEquals(3,testJpaList.size());
    }

    @Test
    public void findByAgeLessThan() {
        List<TestJpa> testJpaList = repositories.findByAgeLessThan(17);
        Assert.assertEquals(2,testJpaList.size());
    }

    @Test
    public void findByAgeLessThanEqual() {
        List<TestJpa> testJpaList = repositories.findByAgeLessThanEqual(17);
        Assert.assertEquals(3,testJpaList.size());
    }

    @Test
    public void findByAgeGreaterThan() {
        List<TestJpa> testJpaList = repositories.findByAgeGreaterThan(17);
        Assert.assertEquals(2,testJpaList.size());
    }

    @Test
    public void findByAgeGreaterThanEqual() {
        List<TestJpa> testJpaList = repositories.findByAgeGreaterThanEqual(17);
        Assert.assertEquals(3,testJpaList.size());
    }

    @Test
    public void findByAgeAfter() {
        List<TestJpa> testJpaList = repositories.findByAgeAfter(17);
        Assert.assertEquals(2,testJpaList.size());
    }

    @Test
    public void findByAgeBefore() {
        List<TestJpa> testJpaList = repositories.findByAgeBefore(17);
        Assert.assertEquals(2,testJpaList.size());
    }

    @Test
    public void findByAgeIsNull() {
        List<TestJpa> testJpaList = repositories.findByAgeIsNull();
        Assert.assertEquals(0,testJpaList.size());
    }

    @Test
    public void findByAgeNotNull() {
        List<TestJpa> testJpaList = repositories.findByAgeNotNull();
        Assert.assertEquals(5,testJpaList.size());
    }

    @Test
    public void findByFirstNameLike() {
        TestJpa testJpa = repositories.findByFirstNameLike("May");
        Assert.assertNotNull(testJpa);
    }

    @Test
    public void findByFirstNameNotLike() {

    }

    @Test
    public void findByFirstNameStartingWith() {
        List<TestJpa> testJpaList = repositories.findByFirstNameStartingWith("May");
        Assert.assertEquals(2,testJpaList.size());
    }

    @Test
    public void findByFirstNameEndingWith() {
        List<TestJpa> testJpaList = repositories.findByFirstNameEndingWith("Evil");
        Assert.assertEquals(0,testJpaList.size());
    }

    @Test
    public void findByFirstNameContaining() {
        List<TestJpa> testJpaList = repositories.findByFirstNameContaining("hack");
        Assert.assertEquals(0,testJpaList.size());
    }

    @Test
    public void findByAgeOrderByLastName() {
        List<TestJpa> testJpaList = repositories.findByAgeOrderByLastName(18);
        for (TestJpa testJpaL : testJpaList){
            log.info("数据结果"+testJpaL.toString());
        }
    }

    @Test
    public void findByAgeNot() {
        List<TestJpa> testJpaList = repositories.findByAgeNot(20);
        Assert.assertEquals(5,testJpaList.size());
    }

    @Test
    public void findByAgeIn() {
        List<TestJpa> testJpaList = repositories.findByAgeIn(Arrays.asList(15, 16));
        Assert.assertEquals(2,testJpaList.size());
    }
}

总结:ORM是一种架构思想,JPA基于ORM思想定义的一个规范,Hibernate是基于ORM思想,按照JPA规范的一种(框架)实现方式,Spring data JPA可以理解为JPA规范的再次封装抽象,底层使用的是Hibernate的JPA技术实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值