zoukankan      html  css  js  c++  java
  • Spring Boot教程(三十一)使用Spring-data-jpa(2)

    创建实体

    创建一个User实体,包含id(主键)、name(姓名)、age(年龄)属性,通过ORM框架其会被映射到数据库表中,由于配置了hibernate.hbm2ddl.auto,在应用启动的时候框架会自动去数据库中创建对应的表。

    @Entity
    public class User {
    
        @Id
        @GeneratedValue
        private Long id;
    
        @Column(nullable = false)
        private String name;
    
        @Column(nullable = false)
        private Integer age;
    
        // 省略构造函数
    
        // 省略getter和setter
    
    }

    创建数据访问接口

    下面针对User实体创建对应的Repository接口实现对该实体的数据访问,如下代码:

    public interface UserRepository extends JpaRepository<User, Long> {
    
        User findByName(String name);
    
        User findByNameAndAge(String name, Integer age);
    
        @Query("from User u where u.name=:name")
        User findUser(@Param("name") String name);
    
    }

    在Spring-data-jpa中,只需要编写类似上面这样的接口就可实现数据访问。不再像我们以往编写了接口时候还需要自己编写接口实现类,直接减少了我们的文件清单。

    下面对上面的UserRepository做一些解释,该接口继承自JpaRepository,通过查看JpaRepository接口的API文档,可以看到该接口本身已经实现了创建(save)、更新(save)、删除(delete)、查询(findAll、findOne)等基本操作的函数,因此对于这些基础操作的数据访问就不需要开发者再自己定义。

    在我们实际开发中,JpaRepository接口定义的接口往往还不够或者性能不够优化,我们需要进一步实现更复杂一些的查询或操作。由于本文重点在spring boot中整合spring-data-jpa,在这里先抛砖引玉简单介绍一下spring-data-jpa中让我们兴奋的功能,后续再单独开篇讲一下spring-data-jpa中的常见使用。

    在上例中,我们可以看到下面两个函数:

    • User findByName(String name)
    • User findByNameAndAge(String name, Integer age)

    它们分别实现了按name查询User实体和按name和age查询User实体,可以看到我们这里没有任何类SQL语句就完成了两个条件查询方法。这就是Spring-data-jpa的一大特性:通过解析方法名创建查询

    除了通过解析方法名来创建查询外,它也提供通过使用@Query 注解来创建查询,您只需要编写JPQL语句,并通过类似“:name”来映射@Param指定的参数,就像例子中的第三个findUser函数一样。

    Spring-data-jpa的能力远不止本文提到的这些,由于本文主要以整合介绍为主,对于Spring-data-jpa的使用只是介绍了常见的使用方式。诸如@Modifying操作、分页排序、原生SQL支持以及与Spring MVC的结合使用等等内容就不在本文中详细展开,这里先挖个坑,后续再补文章填坑,如您对这些感兴趣可以关注我博客或简书,同样欢迎大家留言交流想法。

    单元测试

    在完成了上面的数据访问接口之后,按照惯例就是编写对应的单元测试来验证编写的内容是否正确。这里就不多做介绍,主要通过数据操作和查询来反复验证操作的正确性。

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringApplicationConfiguration(Application.class)
    public class ApplicationTests {
    
    	@Autowired
    	private UserRepository userRepository;
    
    	@Test
    	public void test() throws Exception {
    
    		// 创建10条记录
    		userRepository.save(new User("AAA", 10));
    		userRepository.save(new User("BBB", 20));
    		userRepository.save(new User("CCC", 30));
    		userRepository.save(new User("DDD", 40));
    		userRepository.save(new User("EEE", 50));
    		userRepository.save(new User("FFF", 60));
    		userRepository.save(new User("GGG", 70));
    		userRepository.save(new User("HHH", 80));
    		userRepository.save(new User("III", 90));
    		userRepository.save(new User("JJJ", 100));
    
    		// 测试findAll, 查询所有记录
    		Assert.assertEquals(10, userRepository.findAll().size());
    
    		// 测试findByName, 查询姓名为FFF的User
    		Assert.assertEquals(60, userRepository.findByName("FFF").getAge().longValue());
    
    		// 测试findUser, 查询姓名为FFF的User
    		Assert.assertEquals(60, userRepository.findUser("FFF").getAge().longValue());
    
    		// 测试findByNameAndAge, 查询姓名为FFF并且年龄为60的User
    		Assert.assertEquals("FFF", userRepository.findByNameAndAge("FFF", 60).getName());
    
    		// 测试删除姓名为AAA的User
    		userRepository.delete(userRepository.findByName("AAA"));
    
    		// 测试findAll, 查询所有记录, 验证上面的删除是否成功
    		Assert.assertEquals(9, userRepository.findAll().size());
    
    	}
    
    
    }

    源码来源

  • 相关阅读:
    例题6-8 Tree Uva548
    例题6-7 Trees on the level ,Uva122
    caffe Mac 安装
    Codeforces Round #467 (Div. 1) B. Sleepy Game
    Educational Codeforces Round37 E
    Educational Codeforces Round 36 (Rated for Div. 2) E. Physical Education Lessons
    Good Bye 2017 E. New Year and Entity Enumeration
    Good Bye 2017 D. New Year and Arbitrary Arrangement
    Codeforces Round #454 D. Seating of Students
    浙大紫金港两日游
  • 原文地址:https://www.cnblogs.com/allalongx/p/8521166.html
Copyright © 2011-2022 走看看