A105_springdata jpa_day1

目录

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关闭
在这里插入图片描述

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

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

5.1.4.update 用在测试和web项目

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

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

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

5.2.映射细节
5.2.1.主键

在这里插入图片描述

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

    private GenerationType() {
    }
}

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

GeneratorType.AUTO
表示实体标识由 OpenJPA 容器自动生成,这也是 Strategy 属性的默认值。

GenerationType.IDENTITY
OpenJPA 容器将使用数据库的自增长字段为新增加的实体对象赋唯一值,作为实体的标识。这种情况下需要数据库提供对自增长字段的支持,常用的数据库中,HSQL、SQL Server、MySQL、DB2、Derby 等数据库都能够提供这种支持。

GenerationType.SEQUENCE mysql不支持
表示使用数据库的序列号为新增加的实体对象赋唯一值,作为实体的标识。这种情况下需要数据库提供对序列号的支持,常用的数据库中,Oracle、PostgreSQL 等数据库都能够提供这种支持。

GenerationType.TABLE
表示使用数据库中指定表的某个字段记录实体对象的标识,通过该字段的增长为新增加的实体对象赋唯一值,作为实体的标识。

5.2.2.Column细节
@Entity
public class Employee {
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;
  @Column(length = 20, nullable = false, unique = true)
  private String name;
  private String password;
// default="25"还必须同时配置一个属性insertable ="false",表示不出现在insert语句
  @Column(insertable = false, columnDefinition = "int(11) default '25'")
  private Integer age = 25;
  private Boolean sex;// 数据库没有布尔类型,bit对象
  @Column(columnDefinition = "decimal(19,2) ")
  private BigDecimal salary;// 19,2
  // update=false:一经保存就不能修改属性:身份证号码,创建时间
  // 如果填错了,客户不能改,上传身份证照片,找客服,客服验证:程序员留后台hql:
  // update Employee set idcart=? where id=?
  // 创建时间:年月日时分秒
  @Column(updatable = false)
  @Temporal(TemporalType.TIMESTAMP)
  private Date createTime;
  // 生日:年月日
@Temporal(TemporalType.DATE)
  private Date birthday;
  // 开会时间:时分秒
@Temporal(TemporalType.TIME)
  private Date time;
  // 大文本
 @Lob
  private String text;
  // 如果name属性希望不持久化数据库
  // @Transient// 临时属性
  private String temp;
5.2.3.小结
5.3.持久化对象状态
5.3.1.为什么要学习持久对象的状态

JPA持久对象的状态对我们来说非常非常重要,
主要是我们用的时候,遇到异常、问题的时候,都需要通过状态来分析,才知道这到底是为什么?是什么原因出现这种情况?怎样才可以正确使用JPA

5.3.2.临时状态(transient):瞬时状态

刚刚用new语句创建,没有和entityManager发生关系
没有被持久化,不处于entityManager中。该对象成为临时对象

5.3.3.持久化状态(persistent):托管状态

和entityManager发生关系
已经被持久化,加入到entityManager的一级缓存中(填充一级缓存)。
该状态的对象为持久化对象。

@Test
public void save() throws Exception {
  StateDomain stateDomain = new StateDomain();// 临时状态
  stateDomain.setName("itsource");// 临时状态

  EntityManager entityManager = JPAUtils.getEntityManager();
  entityManager.getTransaction().begin();
  entityManager.persist(stateDomain);// 持久状态
  entityManager.getTransaction().commit();
  entityManager.close();// 游离状态
}
5.3.4.游离状态(detached):脱管状态

已经被持久化,但不处于entityManager中。
该状态的对象为游离对象。

5.3.5.删除状态(removed):从JPA才开始有的状态

只有调用了entityManager.remove(domain对象)方法
对象有关联的ID,并且在entityManager管理下,
但是已经被计划删除,事务提交就真的被删除了。

5.3.6.脏数据更新

一个持久状态对象在事务管理内,如果改变原来的数据(非主键),此时出现脏数据,在事务提交的时候自动发出update语句去修改。
1.测试代码

@Test
public void update() throws Exception {
  save();

  EntityManager entityManager = JPAUtils.getEntityManager();
  entityManager.getTransaction().begin();
  
  StateDomain stateDomain = entityManager.find(StateDomain.class, 1L);// 持久状态
  stateDomain.setName("stateDomain");
  // 写不写效果是一样
  entityManager.merge(stateDomain);// 持久状态

  entityManager.getTransaction().commit();
  entityManager.close();// 游离状态
}

2.执行流程分析

第一步:拿到entityManager,开启事务
第二步:
	通过entityManager拿到一个对象,那么现在这个对象就是持久化的对象
	这个对象会放到一级缓存里面
	JPA会为当前这个对象准备一个快照(把这个对象进行了备份)
第三步:提交事务
	它会把快照 与 你现在这个对象的数据进行对比
	如果相同,就不需要修改,也不会发送SQL(性能就高了)
	当不相同的时候,JPA就会认为现在这个数据是脏数据
	脏数据它就会在事务提交的时候,把它进行数据库的同步(发送update SQL语句)
5.3.7.identifier of an instance of

持久状态的对象是不能修改OID(不能修改主键)
持久层修改id会报下面的错误,大家要注意小心:
org.hibernate.HibernateException: identifier of an instance of cn.itsource.jpa.state.StateDomain was altered from 1 to 200

@Test
public void update2() throws Exception {
  save();

  EntityManager entityManager = JPAUtils.getEntityManager();
  entityManager.getTransaction().begin();

  StateDomain stateDomain = entityManager.find(StateDomain.class, 1L);// 持久状态
  stateDomain.setId(200L);
  // 修改持久对象
  entityManager.merge(stateDomain);// 持久状态

  entityManager.getTransaction().commit();
  entityManager.close();
}
5.3.8.持久对象(domain层)定义规则
  1. 类不能定义为final类
    因为domain类需要被继承的,否则延迟加载会失效
  2. 所有属性的类型都必须是包装类型
    不能是8个基本类型(int,byte,short,long,char,boolean,float,double)
    因为JPA内部代码很多判断都是基于是否等于null
  3. 必须有默认无参构造方法
    因为find方法获取的时候会在内存实例化domain对象
    否则报org.hibernate.InstantiationException: No default constructor for entity异常
5.3.9.entityManager的方法改变持久对象的状态

在这里插入图片描述

6.单向多对一 员工对部门

在这里插入图片描述

6.1.映射
//多个员工属于同一个部门 多对一
@ManyToOne
@JoinColumn(name = "dept_id") //可以不设置字段名,默认使用属性名_id
private Department department;

6.2.测试
@Test
public void add() {

    Department department = new Department("dsb");
    departmentService.add(department);

    Employee employee = new Employee("jp");
    employee.setDepartment(department);
    employeeService.add(employee);

}
立即加载-查询多方的时候立即把一放一起查询出来 在多对一中默认就是立即加载,底层执行sqlleft join
select employee0_.id as id1_1_0_, employee0_.age as age2_1_0_, employee0_.dept_id as dept_id4_1_0_, employee0_.name as name3_1_0_, department1_.id as id1_0_1_, department1_.name as name2_0_1_ from t_employee employee0_ left outer join t_deparment department1_ on employee0_.dept_id=department1_.id where employee0_.id=?

延迟加载-用的时候才加载 @ManyToOne(fetch=FetchType.LAZY) 

在这里插入图片描述

通过网页访问
No serializer

6.3.网页访问-No serializer

No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) )

这个错我们可以到网上搜索,SpringMVC与Jpa集成的时候(有懒加载)就会出现这个问题
(这是因为你需要序列化对象有一个属性是一类类型,而你使用了Hibernate的延迟加载所以这里是个Hibernate的代理对象。该代理对象有些属性不能被序列化所以会报错。)
在类上加属性:生成的时候把这个字段忽略了:

@JsonIgnoreProperties(value={"hibernateLazyInitializer","handler","fieldHandler"})

网上有很多相应的解决方案(这里我们不做缀述),我选一下个比较暴力的。大家直接把下面的代码拷备过来使用即可:

第一步:创建一个新的类(重写com.fasterxml.jackson.databind.ObjectMapper)

package cn.itsource.pss.common;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

public class CustomMapper extends ObjectMapper {
    public CustomMapper() {
        this.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        // 设置 SerializationFeature.FAIL_ON_EMPTY_BEANS 为 false
        this.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
    }
}

第二步:springboot进行注册

package cn.itsource.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.ArrayList;
import java.util.List;

@Configuration
public class MyWebmvcConfiguration implements WebMvcConfigurer {

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {

        MappingJackson2HttpMessageConverter converter =
                new MappingJackson2HttpMessageConverter();
        List<MediaType> fastMediaTypes = new ArrayList<>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        fastMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED);
        //设置类型和编码,防止出现乱码
        converter.setSupportedMediaTypes(fastMediaTypes);


        //No serializer:配置 objectMapper 为我们自定义扩展后的 CustomMapper,解决了返回对象有关系对象的报错问题
        converter.setObjectMapper(objectMapper);
        converters.add(converter);
    }
}

7.单向一对多 部门对员工

7.1.映射
//对于多的处理,默认是懒加载
@OneToMany(fetch = FetchType.EAGER)
@JoinColumn(name = "dept_id")
private Set<Employee> employees = new HashSet<>();
7.2.测试

controller暴露方法

8. 课程总结

8.1.重点
8.2.难点
8.3.如何掌握?

1.多多理解
2.学会看说明手册

8.4.排错技巧(技巧)

1…
2…

9.课后练习

1.总结
2.课堂作业

10.面试题

11.扩展知识或课外阅读推荐(可选)

11.1.扩展知识
11.2.课外阅读

微服务那点儿事情
https://blog.csdn.net/w05980598/article/details/79007194/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值