SpringBoot-SpringData-JPA集成

数据库访问这一层 常用的方式有:JdbcTemplate ,SpringData-JPA, MyBatis
今天我们说一下SpringData-JPA, 使用上一篇SpringBoot-JUnit作为基础代码

注:本文使用的例子来自DD程序员,旨在学习,为了防止争议,本文改为转载

SpringBoot-JUnit 介绍

Spring-data-jpa的优势

开发中对数据库的操作大多为增删改查,开发者重复大量且枯燥的代码来实现这部分逻辑
Spring-data-jpa使数据访问层变成只是一层接口的编写方式

Spring-data-jpa 只需要一个继承了JpaRepository的接口就能实现数据的访问

public interface UserRepository extends JpaRepository<User, Long> {

    User findByName(String name);

    @Query("from User u where u.name=:name")
    User findUser(@Param("name") String name);

}

项目结构

SpringBoot-SpringData-JPA集成_第1张图片


SpringBoot集成SpringData-JPA依赖

在pom.xml中添加依赖(以MySql数据库为例):


<dependency
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-data-jpaartifactId>
dependency>


<dependency>
   <groupId>mysqlgroupId>
   <artifactId>mysql-connector-javaartifactId>
   <version>5.1.29version>
dependency>

数据库连接配置

application.xml中配置数据库连接信息,自动创建表结构设置

spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=123
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop

Spring-data-jpa依赖于Hibernate
spring.jpa.properties.hibernate.hbm2ddl.auto是hibernate的配置属性
主要作用是:自动创建、更新、验证数据库表结构

参数配置介绍:

create:
    每次加载hibernate时都会删除上一次的生成的表,
    然后根据model类重新生成表,哪怕没有改变,
    这是导致数据库表数据丢失的一个重要原因。

create-drop:
    每次加载hibernate时根据model类生成表,但sessionFactory关闭时,表自动删除。

update:最常用
    首次加载hibernate时根据model类自动建立起表结构(要先建立数据库)
    以后加载hibernate时根据model类自动更新表结构,即使表结构变了,老数据不删除。
    注意:当部署到服务器后,表结构不会立即建立起来,应用首次运行后才会建立表结构。

validate:
    每次加载hibernate时,验证创建数据库表结构,和数据库表比较,不创建新表,会插入新值。

创建domain

创建User实体,会被映射到数据库
根据配置项 hibernate.hbm2ddl.auto,应用启动时自动创建表

import javax.persistence.*;
@Entity
public class User {

    // 没有默认构造会报错
    public User(){

    }

    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    @Id
    @GeneratedValue
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private Integer age;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

}

创建数据访问接口(原DAO层)

一般的,对于数据访问层,需要创建一个接口来规定对数据操作的一系列方法,再创建DAO来实现此接口,从而实现对数据库的访问

而Spring-data-jpa,对数据访问,只需继承Spring-data-jpa提供的接口(这里以JpaRepository为例)即可完成对数据的访问

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);

}

以上即可实现数据库的访问,无需再写实现类

先发一个截图说明一下SpringData-JPA接口(后续会详细说明)

SpringBoot-SpringData-JPA集成_第2张图片

这里的JpaRepository接口实现的数据库操作方法

@NoRepositoryBean
public interface JpaRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID> {
    List findAll();

    List findAll(Sort var1);

    List findAll(Iterable var1);

     List save(Iterable var1);

    void flush();

     S saveAndFlush(S var1);

    void deleteInBatch(Iterable var1);

    void deleteAllInBatch();

    T getOne(ID var1);
}

SpringData特性-通过解析方法名创建查询

public interface UserRepository extends JpaRepository<User, Long> {

    User findByName(String name);

    User findByNameAndAge(String name, Integer age);

}

以上查询用户的两个方法,没有写任何Sql,仅在接口层就完成了数据库查询动作
这是SpringData-JPA的一个特性-通过解析方法名创建查询

除了解析方法名创建查询,还提供注解创建查询(@Query)
只需写JPQL语句,通过类似“:name”映射@Param指定的参数即可

public interface UserRepository extends JpaRepository<User, Long> {

    User findByName(String name);

    @Query("from User u where u.name=:name")
    User findUser(@Param("name") String name);// 参数name 映射到数据库字段name

}

当然,SpringData-JPA给开发者带来的便利远不止以上这写,这里暂时只介绍SpringData-JPA的集成


单元测试

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(Application.class)
public class ApplicationTests {

    @Autowired
    private UserRepository userRepository;

    @Test
    public void test() throws Exception {

        // 创建测试数据
        userRepository.save(new User(“Test1", 10));
        userRepository.save(new User("Test2", 20));
        userRepository.save(new User("Test3", 30));
        userRepository.save(new User("Test4", 40));
        userRepository.save(new User("Test5", 50));

        // 测试findAll, 查询所有记录
        Assert.assertEquals(5, userRepository.findAll().size());

        // 测试findByName, 查询姓名为Test2的User.Age=20
        Assert.assertEquals(20, userRepository.findByName("Test2").getAge().longValue());

        // 测试findUser, 查询姓名为Test3的User.Age=30
        Assert.assertEquals(30, userRepository.findUser("Test3").getAge().longValue());

        // 测试findByNameAndAge, 查询姓名为Test4并且年龄为40的User
        Assert.assertEquals("Test4", userRepository.findByNameAndAge("Test4", 40).getName());

        // 测试删除姓名为Test5的User
        userRepository.delete(userRepository.findByName("Test5"));

        // 测试findAll, 删除后为4条记录
        Assert.assertEquals(4, userRepository.findAll().size());

    }

}

测试结果:

SpringBoot-SpringData-JPA集成_第3张图片

SpringBoot后续连载展望

至此SpringData的集成已经完成,后续计划陆续更新SpringData相关文章,如:

创建表,一对多和多对一映射以及懒加载等问题
SpringData接口继承关系和作用
各种注解的作用,如:更新操作,事务等
操作数据库方法的规范,自己写SQL的方式
SpringData多数据源的实现

目前只想到这些相关的,也是项目中必知必会的
后面先继续更新SpringBoot,上面的相关知识随着用到进行连载


代码下载

  CSDN下载

  GitHub下载

维护记录:
20170427:
修改描述错误: 遍历->便利
修改@Query注解创建查询-代码段错误

你可能感兴趣的:(SpringBoot,SpringBoot从0开始,SpringBoot,SpringData,数据库)