A105_springdata jpa_day1

2023年2月19日12:28:34

目录

1.内容介绍

1. springboot Spring Data Jpa概述;(了解)
2. springboot Spring Data Jpa入门;(掌握)
3. springboot Spring Data Jpa crud;(掌握)
4. spring data jpa单表映射细节 主键 clomn;(掌握)
5. 单向多对一;(掌握)
6. 单向一对多;(掌握)

2.Springboot Data Jpa概述

2.1.Jpa概述

2.1.1.介绍

1.JPA是Java Persistence API的简称。

2.JPA作为 Java EE 5.0 平台标准的 对象关系映射(ORM) 规范
将得到所有 Java EE 服务器的支持。 Sun 这次吸取了之前 EJB 规范惨痛失败的经历,在充分吸收现有 ORM 框架(如Hibernate)的基础上,得到了一个易于使用、伸缩性强的 ORM 规范。

3.从目前的开发社区的反应上看
JPA 受到了极大的支持和赞扬, JPA 作为 ORM 领域标准化整合者的目标已经实现。

2.1.2.为什么需要Jpa

1.这个需要从Hibernate的起源说起。 Hibernate作者Gavin King发现以前写JDBC的开发效率太低,特别在Java这种面向对象的语言在与关系型数据库之间的数据转换太麻烦了。

2.于是开发出了Hibernate,他当时的目标是,只要是Java程序员,就算不懂SQL语句,也可以来操作数据库

2.1.3.Hibernate和JPA的关系

Hibernate是一个开放源代码的对象关系映射(ORM)框架,它对JDBC进行了非常轻量级(相对于EJB这一套)的对象封装,它将POJO(就是咱们的domain)与数据库表建立映射关系,是一个全自动的orm框架,Hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。

JPA是Sun官方提出的Java持久化规范。它为Java开发人员提供了一种对象/关系映射工具来管理Java应用中的关系数据。他的出现主要是为了简化现有的持久化开发工作和整合ORM技术,结束现在Hibernate、TopLink(现在叫EclipseLink)等ORM框架各自为营的局面。

值得注意的是,JPA是在充分吸收了现有Hibernate、TopLink等ORM框架的基础上发展而来的,具有易于使用、伸缩性强等优点。

目标:
简化现有Java EE和Java SE应用的对象持久化的开发工作;
Sun希望整合ORM技术,实现一统江湖。
简单一句话:JPA是持久化规范,而Hibernate是其实现。

2.1.4.JPA的优缺点

本质:处理Java对象和关系型数据库表之间的转换,只是对JDBC再次做了一层封装

优点:

  1. 程序员操作很简单,代码简单 entityManager.persist(employee);
  2. 直接面向持久对象操作
  3. 提供世界级数据缓存(现在几乎所有的ORM框架的缓存都是学的Hibernate)
    一级缓存,二级缓存,查询缓存(空间换速度)
  4. 数据库移植性很强,很少的修改(通过配置方言搞定)
    把各种数据库抽取了一个方言接口
    不同数据库实现一个方言接口,如果换了数据库,必须修改方言实现,驱动jar文件,连接数据库信息。

缺点:

  1. 不能干预sql语句的生成
    entityManager.find(User.class, 1L);
    find方法默认查询t_user表的所有字段
    自动生成select user0_.id,user0_.name,user0_.age from t_user user0_ where user0_.id=?
  2. 一个项目中,如果对sql语句的优化要求比较高,不适合用JPA(不过可以使用JPA对原生sql的支持来解决)
  3. 如果一张表中有上亿级别的数据量,也不适合用JPA,其实也不适合用jdbc(可以使用数据库读写分离,分库分表方案解决)。
2.1.5.小结

2.2.Spring data jpa概述

2.2.1.是什么

是spring data对rdms的支持。 致力于减少数据访问层 (DAO) 的开发量. 开发者唯一要做的,就只是声明持久层的接口,其他都交给 Spring Data JPA 来帮你完成!

2.2.2.Spring data

Spring 的一个子项目。用于简化数据访问,支持NoSQL 和 关系数据存储。其主要目标是使数据的访问变得方便快捷。

  • SpringData 项目所支持 NoSQL 存储:
    MongoDB (文档数据库)
    Neo4j(图形数据库)
    Redis(键/值存储)
    Hbase(列族数据库)
    ElasticSearch
  • SpringData 项目所支持的关系数据存储技术:
    JDBC
    JPA

2.3.Springboot spring data jpa

就是使用springboot的自动配置,再一次减缓spring data jpa应用的开发,我们基本不用写配置了。

2.4.小结

3.Springboot spring Data Jpa入门

3.1.步骤分析

1)搭建一个springboot项目
   ①pom
   ②配置文件
   ③入口类
   ④启动测试
2)Springboot集成Spring data jpa
  ①pom
  ②配置
3)写代码测试
  ①domain
  ②Repository
	Spring Data 的一个核心接口为我们提供了常用的接口
	Repository 接口是 Spring Data 的一个核心接口,它不提供任何方法,开发者需要在自己定义的接口中声明需要的方法 :

	public interface Repository<T, ID extends Serializable> { } 
	1. Repository是一个空接口,即是一个标记接口;
	2. 若我们定义的接口继承了Repository,则该接口会被IOC容器识别为一个Repository Bean纳入到IOC容器中,进而可以在该接口中定义满足一定规范的方法。
	3. 实际上也可以通过@RepositoryDefinition,注解来替代继承Repository接口。
	4. 查询方法以find | read | get开头;
	5. 涉及查询条件时,条件的属性用条件关键字连接,要注意的是条件属性以首字母大写。
	6.使用@Query注解可以自定义JPQL语句实现更灵活的查询。

	CrudRepository 接口提供了最基本的对实体类的添删改查操作
	 --T save(T entity);//保存单个实体   
	  --Iterable<T> save(Iterable<? extends T> entities);//保存集合         
	  --T findOne(ID id);//根据id查找实体          
	  --boolean exists(ID id);//根据id判断实体是否存在          
	  --Iterable<T> findAll();//查询所有实体,不用或慎用!          
	  --long count();//查询实体数量          
	  --void delete(ID id);//根据Id删除实体          
	  --void delete(T entity);//删除一个实体   
	  --void delete(Iterable<? extends T> entities);//删除一个实体的集合          
	  --void deleteAll();//删除所有实体,不用或慎用!   

	PagingAndSortingRepository接口
	该接口提供了分页与排序功能   
	 --Iterable<T> findAll(Sort sort); //排序    
	--Page<T> findAll(Pageable pageable); //分页查询(含排序功能)

	JpaRepository:查找所有实体,排序、查找所有实体,执行缓存与数据库同步

  ③Service
  ④测试

3.2.搭建spirngboot

①pom

<!--    springboot让我们parent继承springboot的parent-->
<!--公共的一些配置-->
<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>

<!--    继承SpringBoot-->
<!--1.管理 SpringBoot的jar包-->
<parent>
    <groupId> org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.5.RELEASE</version>
</parent>

<!-- 依赖配置 -->
		<!-- web支持: 1、web mvc; 2、restful; 3、jackjson支持; 4、aop ........ -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- springboot test支持 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
		</dependency>

②配置文件

application.yml
server:
  port: 8888
spring:
  application:
    name: springbootdatajpatest

③入口类

@SpringBootApplication
public class App{
    public static void main(String[] args) {
        SpringApplication.run(App.class,args);
    }
}

④启动测试
启动App.java里面main

3.3.集成spring data jpa

①pom

<dependency>
		<groupId>mysql</groupId>
		<artifactId>mysql-connector-java</artifactId>
</dependency>

<dependency>
		    <groupId>org.springframework.boot</groupId>
		    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

②配置

server:
  port: 8888
spring:
  application:
    name: springbootdatajpatest
  datasource:
    url: jdbc:mysql://localhost:3306/test
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: 123456
  jpa:
    database: mysql #jpa操作mysql
    show-sql: true  #把执行sql显示出来
    hibernate:
      naming:
        physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy #不用管
      ddl-auto: update
    open-in-view: true
    database-platform: org.hibernate.dialect.MySQL55Dialect #使用的mysql5.5方言

3.4.写代码测试

①domain

package cn.itsource.entity;

import javax.persistence.*;

@Entity
@Table(name="t_employee")
public class Employee {

   @Id
   @GeneratedValue
   private Long id;

   @Column
   private String name;

   public Employee(String name) {
      this.name = name;
   }

   public Employee() {
   }
}

②Repository

package cn.itsource.repository;

import cn.itsource.entity.Employee;
import org.springframework.data.jpa.repository.JpaRepository;

public interface EmployeeRepository extends JpaRepository<Employee, Long> {
}

③Service

package cn.itsource.service;
import cn.itsource.entity.Employee;
import java.util.List;

public interface IEmployeeService {
    void add(Employee employee);
    void del(Long id);
    void update(Employee employee);
    Employee getById(Long id);
    List<Employee> getAll();
}
package cn.itsource.service.impl;

import cn.itsource.entity.Employee;
import cn.itsource.repository.EmployeeRepository;
import cn.itsource.service.IEmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;

@Service
public class EmployeeServiceImpl implements IEmployeeService {
    @Autowired
    private EmployeeRepository repository;
    @Override
    public void add(Employee employee) {
        repository.save(employee);
    }

    @Override
    public void del(Long id) {

    }

    @Override
    public void update(Employee employee) {

    }

    @Override
    public Employee getById(Long id) {
        return null;
    }

    @Override
    public List<Employee> getAll() {
        return null;
    }
}

④测试

package cn.itsource.service;
import cn.itsource.App;
import cn.itsource.entity.Employee;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import static org.junit.Assert.*;

@SpringBootTest(classes = App.class)
@RunWith(SpringRunner.class)
public class IEmployeeServiceTest {

    @Autowired
    private IEmployeeService employeeService;

    @Test
    public void add() {
        employeeService.add(new Employee("zs"));
    }

    @Test
    public void del() {
    }

    @Test
    public void update() {
    }

    @Test
    public void getById() {
    }

    @Test
    public void getAll() {
    }
}

3.5.小结

4.Spring boot spring data jpa crud&事务管理

4.1.Crud

package cn.itsource.service.impl;

import cn.itsource.entity.Employee;
import cn.itsource.repository.EmployeeRepository;
import cn.itsource.service.IEmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class EmployeeServiceImpl implements IEmployeeService {
    @Autowired
    private EmployeeRepository repository;
    @Override
    public void add(Employee employee) {
        repository.save(employee);
    }

    @Override
    public void del(Long id) {
        repository.deleteById(id);
    }

    @Override
    public void update(Employee employee) {
        repository.save(employee);

    }

    @Override
    public Employee getById(Long id) {
        return repository.findById(id).get();
    }

    @Override
    public List<Employee> getAll() {
        return repository.findAll();
    }
}
package cn.itsource.service;

import cn.itsource.App;
import cn.itsource.entity.Employee;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import static org.junit.Assert.*;

@SpringBootTest(classes = App.class)
@RunWith(SpringRunner.class)
public class IEmployeeServiceTest {

    @Autowired
    private IEmployeeService employeeService;

    @Test
    public void add() {
        employeeService.add(new Employee("zs"));
    }

    @Test
    public void del() {
        Employee employee = employeeService.
                getById(1L);
        System.out.println(employee);
        employeeService.del(1L);
        employee = employeeService.
                getById(1L);
        System.out.println(employee);
    }

    @Test
    public void update() {
        Employee employee = employeeService.
                getById(1L);
        System.out.println(employee);
        employee.setName(employee.getName()+"-edit");
        employeeService.update(employee);
        employee = employeeService.
                getById(1L);
        System.out.println(employee);
    }

    @Test
    public void getById() {
        System.out.println(employeeService.getById(1L));
    }

    @Test
    public void getAll() {
        System.out.println(employeeService.getAll());
    }
}

4.2.事务管理

@Service
@Transactional(propagation = Propagation.SUPPORTS,readOnly = true)
public class EmployeeServiceImpl implements IEmployeeService {
    @Autowired
    private EmployeeRepository repository;
    @Override
    @Transactional
    public void add(Employee employee) {
        repository.save(employee);
        int i = 1/0;
    }

5.Springboot spring data jpa细节

5.1.配置自动生成表(建表策略)

5.1.1.配置属性名称:hibernate.hbm2ddl.auto

如果需要生成表,只需要表名,列名以及对应列名的类型,这些全部在持久类里面都有定义
创建表的时间:成功获取到EntityManagerFactory对象

5.1.2.create-drop

这个开发一般不会用,面试会被问到
先删除表,再创建表,再删除表
删除表的时间:必须把EntityManagerFactory关闭
A105_springdata jpa_day1

5.1.3.create 只有在测试的时候使用

先删除表,再创建表,不会再删除表
如果更改了domain类的映射,会马上生效

5.1.4.update 用在测试和web项目

如果没表就根据最新的映射信息来创建表
如果表里面已经有这个属性,如修改属性的长度,不会更新到表里面
需要更新这个列先删除表或者删除这个属性对应的列名
如果表里面没有属性,映射信息存在,会增加这个列

5.1.5.validate 用在系统已经上线或者客户给定了数据库

表不存在,会抛出异常
Domain类映射信息少属性,表比映射定义的列要多,不会报错
反之,抛出异常
核心 API包含咱们昨天学习的几个对象,今天我们将对他们进行相应的分析:

5.2.映射细节

5.2.1.主键

A105_springdata jpa_day1

public enum GenerationType {
    TABLE,
    SEQUENCE,
    IDENTITY,
    AUTO;

    private GenerationType() {
    }
}

GeneratorType strategy
strategy是 GenerationType类型的枚举值,它的内容将指定 OpenJPA 容器自动生成实体标识的方式。strategy属性可以是下列

  • 作者:HLPTHQL
  • 原文链接:https://blog.csdn.net/ffhgjgj6576567/article/details/118737020
    更新时间:2023年2月19日12:28:34 ,共 10531 字。