【系统学习SpringBoot】SpringBoot初遇Spring-Data-JPA

【JPA】

JPA【Java Persistence API】的简称,中文名【Java持久层API】,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。

Sun引入新的JPA ORM规范出于两个原因:
【1】简化现有Java EE和Java SE应用开发工作;
【2】Sun希望整合ORM技术,实现天下归一。

目前比较成熟的 JPA 框架主要包括
【1】Oracle的Oracle AS TopLink(TopLink,是位居第一的Java对象关系可持续性体系结构,原署WebGain公司的产品,后被Oracle收购)
【2】Oracle 捐献给 Eclipse 社区的 EclipseLink
【3】Jboss 的 Hibernate EntityManager
【4】Apache 的 OpenJPA 等。



【Spring中的JPA】

Spring 框架对 JPA 提供的支持主要体现在如下几个方面:

【1】它使得 JPA 配置变得更加灵活。
JPA 规范要求,配置文件必须命名为 persistence.xml,并存在于类路径下的META-INF 目录中。该文件通常包含了初始化 JPA 引擎所需的全部信息。Spring 提供的
LocalContainerEntityManagerFactoryBean 提供了非常灵活的配置,persistence.xml
中的信息都可以在此以属性注入的方式提供。

【2】Spring 实现了部分在 EJB 容器环境下才具有的功能
比如对 @PersistenceContext、@PersistenceUnit 的容器注入支持。

【3】Spring 将 EntityManager
的创建与销毁、事务管理等代码抽取出来,并由其统一管理,开发者不需要关心这些,业务方法中只剩下操作领域对象的代码,事务管理和
EntityManager 创建、销毁的代码都不再需要开发者关心了。**



【Spring-Data-JPA】

Spring Data JPA 框架,主要针对的就是 Spring 唯一没有简化到的业务逻辑代码。
使用Spring-data-JPA开发者连仅剩的实现持久层业务逻辑的工作都省了,唯一要做的,就只是声明持久层的接口,其他都交给 Spring Data JPA 来帮你完成!



一、SpringBoot中使用spring-data-jpa

【1】导入jar(spring-data-jpa的jar,mysql数据库连接的jar)
连版本都不用写了,父pom中已经定义了,此处只需要加入引用即可。

         <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-data-jpaartifactId>
        dependency>
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
        dependency>



【2】添加配置文件,数据库操作,四大配置肯定少不了

  • 驱动
    • 【com.mysql.jdbc.Driver】老套路
  • 链接
    • 【jdbc:mysql://localhost:3306/test】(有时候会有乱码问题)给链接后面加上编码即可【jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8】
  • 用户名
    • root
  • 密码
    • 【不外传哈,(●’◡’●)】
#配置数据库,使用SpringJPA
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test
    username: root
    password: *********
    driver-class-name: com.mysql.jdbc.Driver



【3】编写实体类,spring-data-jpa会自动创建一个数据库的表与之对应,,参考配置如下

package xatu.zsl.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.io.Serializable;

/**
 * Created by zsl on 2017/9/4.
 */
@Entity(name = "user_test")//此标签即我要创建表,user_test
public class User implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id//主键
    @GeneratedValue//自增
    private long id;
    //此属性与表中的【user_name】列对应,不可以为空
    @Column(nullable = false, name = "user_name")
    private String name;
    //此属性与表中的【password】列对应,不可以为空
    @Column(nullable = false)
    private String password;

    public User() {
    }

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

    public static long getSerialVersionUID() {
        return serialVersionUID;
    }

    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 String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}



【4】写一个dao层的接口例如【UserRepositoryDao】

//JpaRepository,,第一个是
public interface UserRepositoryDao extends JpaRepository<User, Long> {

}

就这样可以玩?? 【回答】是的,就这样简单粗暴,,原因见下面细节分析【3】



到此,,SpringBoot对jpa的配置算是完成了。,下面用一下,体验非一般的感觉



二、Spring-data-jpa的增删改查

测试代码片段如下:有点问题的代码

   @GetMapping("/showuser")
    public List showUsers() {

        User user = new User("小鼠标一号", "password" + 5);
        user.setId(4);
        //增
        System.out.println("============= 增 ===========");
        userRepositoryDao.save(user);

        //改
        System.out.println("============= 改 ===========");
        User user2 = new User("小鼠标二号", "password" + 5);
        user.setId(4);
        userRepositoryDao.save(user);

        //查
        System.out.println("============= 查 ===========");
//        userRepositoryDao.delete(user);
        List users = userRepositoryDao.findAll();

        //删
        System.out.println("============= 删 ===========");
        User user1 = new User("小鼠标","mima");
        userRepositoryDao.save(user1);
        userRepositoryDao.delete(user1);
        return users;

    }

控制台打印出的sql如下
【系统学习SpringBoot】SpringBoot初遇Spring-Data-JPA_第1张图片
【1】增和删除,,事先需要通过ID,,select是为了防止重复插入,造成主键重复错误
【2】删除前的插入,是代码中专门放的为了测试使用。



测试代码片段如下: 这个才是比较正确的测试案例,,刚刚那个是本人测试是遇到的坑,专门保留下来。

package xatu.zsl.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import xatu.zsl.dao.UserRepositoryDao;
import xatu.zsl.domain.XatuZSLinfo;
import xatu.zsl.entity.Student;
import xatu.zsl.entity.User;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;


/**
 * Created by zsl on 2017/9/2.
 */
@RestController
public class HelloController {


    @RequestMapping("/springboot")
    public String hello() {
        return "Hello SpringBoot!";
    }

    @GetMapping("/student_json")
    public List getStudentJson() {
        List students = new ArrayList<>();
        students.add(new Student("刘备", "1406001", 25));
        students.add(new Student("张飞", "1406001", 20));
        students.add(new Student("关羽", "1406001", 23));
        students.add(new Student("曹操", "1405001", 24));
        return students;
    }

    @Autowired
    FilterRegistrationBean registration;

    @GetMapping("/getname")
    public Map getName() {
        Map initParameters = registration.getInitParameters();
        return initParameters;
    }

    @Autowired
    private XatuZSLinfo properties;

    @GetMapping("/getzsl")
    public XatuZSLinfo getXatuZSLinfo() {
        return properties;
    }

    @Autowired
    private UserRepositoryDao userRepositoryDao;

    @GetMapping("/showuser")
    public List showUsers() {

        User user = new User("小鼠标一号", "password" + 5);
        //增
        System.out.println("============= 增 ===========");
        userRepositoryDao.save(user);

        //改
        System.out.println("============= 改 ===========");
        user.setName("小鼠标更改");
        userRepositoryDao.save(user);

        //查
        System.out.println("============= 查 ===========");
//        userRepositoryDao.delete(user);
        List users = userRepositoryDao.findAll();

        //删
        System.out.println("============= 删 ===========");
        User user1 = new User("小鼠标","mima");
        userRepositoryDao.save(user1);
        userRepositoryDao.delete(user1);
        return users;

    }
}

【系统学习SpringBoot】SpringBoot初遇Spring-Data-JPA_第2张图片

这个增删改查看起来更规范一点。。

数据库及最后页面的显示如下:
【系统学习SpringBoot】SpringBoot初遇Spring-Data-JPA_第3张图片



三、细节分析

【1】@Entity注解,,起始主要就是一个属性,,表名。

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package javax.persistence;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Entity {
    String name() default "";
}



【2】 @Column注解内容稍微多一点。

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package javax.persistence;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
    String name() default "";
    //是唯一
    boolean unique() default false;
    //可以为空
    boolean nullable() default true;
    //可插入的
    boolean insertable() default true;
    //可更新的
    boolean updatable() default true;
    //列定义
    String columnDefinition() default "";

    String table() default "";

    int length() default 255;
    //精度
    int precision() default 0;
    //规模
    int scale() default 0;
}



【3】springBoot为什么这么方便的使用JPA的方法,只需要继承JpaRepository接口,
下面是JpaRepository接口的内容,只需要设置相应的泛型,就可以很方便的使用(Spring容器中肯定有这个接口的实现。)

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.data.jpa.repository;

import java.io.Serializable;
import java.util.List;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.QueryByExampleExecutor;

@NoRepositoryBean
public interface JpaRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
    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);

     List findAll(Example var1);

     List findAll(Example var1, Sort var2);
}



参考链接
【1】 了解 Spring Data JPA

你可能感兴趣的:(SpringBoot,SpringBoot)