SpringData 与 JPA

目录

Spring Data 与 JPA

ORM思想

JPA规范

一、基本的CRUD

二、 JPA数据查询

三、对象关系映射 --- 如何让  dept 和  emp 表产生关系


Spring Data 与 JPA

  JPA  是 Java Persistence API  的简称,中文名 Java 持久层 API, 是 JDK5.0 注解 或 XML 描述对象- 关系表的映射关系,并将运行期的实体对象持久化到数据库中,JPA 是 ORM 映射框架。(51CTO老齐学编程)

ORM思想

  • 对象关系映射(Object Relational Mapping,简称ORM)是通过使用描述对象和数据库之间映射的元数据,将面向对象语言程序中的对象自动持久化到关系数据库中。 本质上就是将数据从一种形式转换到另外一种形式。
  • 主要目的:操作实体类就相当于操作数据库中的表。
  • 建立两个映射关系

                              实体类和表的映射关系
                              实体类中的属性和表中字段的映射关系
                              不再重点关注:sql语句

  • 实现ORM思想的框架:mybatis、hibernate。

JPA规范

当ORM思想刚出现的时候,许多厂家推出一大堆框架采用ORM思想,所以sun公司最后为了统一标准,指定了jpa规范,实现了这个规范的有:hibernate、toplink等,真正工作的不是jpa,而是hibernate或者toplink等框架。
在这里插入图片描述

一、基本的CRUD

创建数据库文件

执行 SQL 脚本

/*
 Navicat Premium Data Transfer

 Source Server         : localhost
 Source Server Type    : MySQL
 Source Server Version : 50718
 Source Host           : localhost:3306
 Source Schema         : scott

 Target Server Type    : MySQL
 Target Server Version : 50718
 File Encoding         : 65001

 Date: 20/04/2018 16:57:32
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for bonus
-- ----------------------------
DROP TABLE IF EXISTS `bonus`;
CREATE TABLE `bonus`  (
  `ename` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `job` varchar(9) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `sal` decimal(7, 2) NULL DEFAULT NULL,
  `comm` decimal(7, 2) NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for dept
-- ----------------------------
DROP TABLE IF EXISTS `dept`;
CREATE TABLE `dept`  (
  `deptno` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `dname` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `loc` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`deptno`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 54 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of dept
-- ----------------------------
INSERT INTO `dept` VALUES (10, 'ACCOUNTING', 'NEW YORK');
INSERT INTO `dept` VALUES (20, 'RESEARCH', 'DALLAS');
INSERT INTO `dept` VALUES (30, 'SALES', 'CHICAGO');
INSERT INTO `dept` VALUES (40, 'OPERATIONS', 'BOSTON');


-- ----------------------------
-- Table structure for emp
-- ----------------------------
DROP TABLE IF EXISTS `emp`;
CREATE TABLE `emp`  (
  `empno` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `ename` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `job` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `mgr` int(10) UNSIGNED NULL DEFAULT NULL,
  `hiredate` date NULL DEFAULT NULL,
  `sal` decimal(7, 2) NULL DEFAULT NULL,
  `comm` decimal(7, 2) NULL DEFAULT NULL,
  `deptno` int(10) UNSIGNED NULL DEFAULT NULL,
  PRIMARY KEY (`empno`) USING BTREE,
  INDEX `deptno`(`deptno`) USING BTREE,
  CONSTRAINT `emp_ibfk_1` FOREIGN KEY (`deptno`) REFERENCES `dept` (`deptno`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 7935 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of emp
-- ----------------------------
INSERT INTO `emp` VALUES (7369, 'SMITH', 'CLERK', 7902, '1980-12-17', 800.00, NULL, 20);
INSERT INTO `emp` VALUES (7499, 'ALLEN', 'SALESMAN', 7698, '1981-02-20', 1600.00, 300.00, 30);
INSERT INTO `emp` VALUES (7521, 'WARD', 'SALESMAN', 7698, '1981-02-22', 1250.00, 500.00, 30);
INSERT INTO `emp` VALUES (7566, 'JONES', 'MANAGER', 7839, '1981-04-02', 2975.00, NULL, 20);
INSERT INTO `emp` VALUES (7654, 'MARTIN', 'SALESMAN', 7698, '1981-09-28', 1250.00, 1400.00, 30);
INSERT INTO `emp` VALUES (7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01', 2850.00, NULL, 30);
INSERT INTO `emp` VALUES (7782, 'CLARK', 'MANAGER', 7839, '1981-06-09', 2450.00, NULL, 10);
INSERT INTO `emp` VALUES (7788, 'SCOTT', 'ANALYST', 7566, '1987-07-13', 3000.00, NULL, 20);
INSERT INTO `emp` VALUES (7839, 'KING', 'PRESIDENT', NULL, '1981-11-17', 5000.00, NULL, 10);
INSERT INTO `emp` VALUES (7844, 'TURNER', 'SALESMAN', 7698, '1981-09-08', 1500.00, 0.00, 30);
INSERT INTO `emp` VALUES (7876, 'ADAMS', 'CLERK', 7788, '1987-07-13', 1100.00, NULL, 20);
INSERT INTO `emp` VALUES (7900, 'JAMES', 'CLERK', 7698, '1981-12-03', 950.00, NULL, 30);
INSERT INTO `emp` VALUES (7902, 'FORD', 'ANALYST', 7566, '1981-12-03', 3000.00, NULL, 20);
INSERT INTO `emp` VALUES (7934, 'MILLER', 'CLERK', 7782, '1982-01-23', 1300.00, NULL, 10);

-- ----------------------------
-- Table structure for salgrade
-- ----------------------------
DROP TABLE IF EXISTS `salgrade`;
CREATE TABLE `salgrade`  (
  `grade` int(10) UNSIGNED NULL DEFAULT NULL,
  `losal` int(10) UNSIGNED NULL DEFAULT NULL,
  `hisal` int(10) UNSIGNED NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of salgrade
-- ----------------------------
INSERT INTO `salgrade` VALUES (1, 700, 1200);
INSERT INTO `salgrade` VALUES (2, 1201, 1400);
INSERT INTO `salgrade` VALUES (3, 1401, 2000);
INSERT INTO `salgrade` VALUES (4, 2001, 3000);
INSERT INTO `salgrade` VALUES (5, 3001, 9999);

SET FOREIGN_KEY_CHECKS = 1;

创建项目

下一步

next:

pom.xml  文件介绍

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.2.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.kangna</groupId>
	<artifactId>springdatajpa</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>springdatajpa</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
        <!-- 加载  hibernate 核心包 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
        <!-- 加载 web项目所需要的包 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
        <!-- 加载 MySQL的驱动包 -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
        <!-- 用于测试的包 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

          maven 镜像 要配置好,我第一次 竟然 下载不到springWeb 依赖包 ,重新创建了一个新的工程。

resource 下 application.properties 配置 数据源的基本信息

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/scott?useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=123456
# display sql in console
spring.jpa.show-sql=true

创建实体类

package com.kangna.springdatajpa.entity;

import javax.persistence.*;

/********************************
 * @Author: kangna
 * @Date: 2020/1/9 16:59
 * @Version: 1.0
 * @Desc:
 ********************************/
@Entity // 告诉Spring Boot 这个一个实体类,在 SB 启动的时候加载这个类
@Table(name = "dept")
public class Dept {

    @Id // 指定主键
    @GeneratedValue(strategy = GenerationType.IDENTITY) // 主键自增长 相当于 MySQL中的 auto_increment
    @Column(name = "deptno") // deptno 属性 对用deptno 字段
    private Integer deptno;

    @Column(name = "dname")
    private String dname;

    @Column(name = "loc")
    private String location;

    public Integer getDeptno() {
        return deptno;
    }

    public void setDeptno(Integer deptno) {
        this.deptno = deptno;
    }

    public String getDname() {
        return dname;
    }

    public void setDname(String dname) {
        this.dname = dname;
    }

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }
}

创建接口 DeptRepository

package com.kangna.springdatajpa.repository;

import com.kangna.springdatajpa.entity.Dept;
import org.springframework.data.jpa.repository.JpaRepository;

/** JpaRepository 是Spring Boot 为我们提供的简化类,默认提供了增删改查方法
 * 我们需要 定义 Repository 接口就可以了,在 Spring Boot 启动的时候会自动帮我们生成具体的实现类,来实现具体的CRUD方法
 */
public interface DeptRepository extends JpaRepository<Dept, Integer>{

}

创建DeptController

package com.kangna.springdatajpa.controller;

import com.kangna.springdatajpa.entity.Dept;
import com.kangna.springdatajpa.repository.DeptRepository;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.util.Optional;

/********************************
 * @Author: kangna
 * @Date: 2020/1/9 17:30
 * @Version: 1.0
 * @Desc:
 ********************************/
@Controller
@RequestMapping("/dept")
public class DeptController {

    @Resource
    private DeptRepository deptRepository = null;

    @GetMapping("/{id}")
    @ResponseBody
    public Dept findById(@PathVariable("id") Integer id) {
        // Optional 是实体类的包装类, 用于判断对象是否存在
        Optional<Dept> optional = deptRepository.findById(id);
        Dept dept = null;
        if (optional.isPresent() == true) {
            // 获取到对应的实体类
            dept = optional.get();
        }
        return dept;
    }
}

启动 Web应用

 到 指定的 路径查看查询结果

添加 ,修改 ,删除 

控制台打印:

定义 好映射关系 ,hibernate 帮我们自动生成 SQL 语句


 

二、 JPA数据查询

需求:按照 部门名称   查找部门信息

接口中  方法的定义

package com.kangna.springdatajpa.repository;

import com.kangna.springdatajpa.entity.Dept;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.util.List;

/** JpaRepository 是Spring Boot 为我们提供的简化类,默认提供了增删改查方法
 * 我们需要 定义 Repository 接口就可以了,在 Spring Boot 启动的时候会自动帮我们生成具体的实现类,来实现具体的CRUD方法
 */
public interface DeptRepository extends JpaRepository<Dept, Integer>{

    // select * from dept where dname ....
    //List<Dept> findByDName(String dname);

    /**
     * JPQL  java persistence query language 持久化查询语言
     *    类SQL语法,使用时注意以下几点
     *     (1) 大多数情况下,将 *  替换为别名
     *     (2) 表名改为类名
     *     (3) 字段名改为 属性名
     */
    @Query("select d from Dept d where d.dname = 'Tranning'")
    List<Dept> findDepts();
}

 findDepts 方法 在 DeptController 类中的实现

    @GetMapping("/find")
    @ResponseBody
    public List<Dept> findDepts(String dname) {
        List<Dept> list = deptRepository.findDepts();
        return list;
    }

查询结果

需求:按照部门编号升序 查询所有部门

JPQL实现

public interface DeptRepository extends JpaRepository<Dept, Integer>{

    // select * from dept where dname ....
    //List<Dept> findByDName(String dname);

    /**
     * JPQL  java persistence query language 持久化查询语言
     *    类SQL语法,使用时注意以下几点
     *     (1) 大多数情况下,将 *  替换为别名
     *     (2) 表名改为类名
     *     (3) 字段名改为 属性名
     */
    //@Query("select d from Dept d where d.dname = 'Tranning'")
    //List<Dept> findDepts();
    @Query("select d from Dept d where d.dname = :dn order by deptno asc")
    // 将 dname 参数的值 带入到 :dn 中
    List<Dept> findDepts(@Param("dn") String dname);
}

Controller 完善

    @GetMapping("/find")
    @ResponseBody
    public List<Dept> findDepts(String dname) {
        List<Dept> list = deptRepository.findDepts(dname);
        return list;
    }

结果显示 


补充:看看 JpaRepository

package org.springframework.data.jpa.repository;

import java.util.List;

import javax.persistence.EntityManager;

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 PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {

	@Override
	List<T> findAll();


	@Override
	List<T> findAll(Sort sort);

	@Override
	List<T> findAllById(Iterable<ID> ids);

	
	@Override
	<S extends T> List<S> saveAll(Iterable<S> entities);

	
	void flush();


	<S extends T> S saveAndFlush(S entity);

	void deleteInBatch(Iterable<T> entities);

	
	void deleteAllInBatch();


	T getOne(ID id);


	@Override
	<S extends T> List<S> findAll(Example<S> example);

	@Override
	<S extends T> List<S> findAll(Example<S> example, Sort sort);
}

JpaRepository接口 定义我们   常用 的 CRUD方法


 

三、对象关系映射 --- 如何让  dept 和  emp 表产生关系

添加 emp 实体类

package com.kangna.springdatajpa.entity;

import javax.persistence.*;
import java.util.Date;

/********************************
 * @Author: kangna
 * @Date: 2020/1/9 21:42
 * @Version: 1.0
 * @Desc:
 ********************************/
@Entity
@Table
public class Emp {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer empno;
    private String ename;
    private String job;
    private Integer mgr;
    private Date hiredate;
    private Float sal;
    private Float comm;
    // 多的一方 使用 ManyToOne  一个部门多个员工
    @ManyToOne
    @JoinColumn(name = "deptno") // 指定关联的 字段,一般为主键
    private Dept dept;

    public Integer getEmpno() {
        return empno;
    }

    public void setEmpno(Integer empno) {
        this.empno = empno;
    }

    public String getEname() {
        return ename;
    }

    public void setEname(String ename) {
        this.ename = ename;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    public Integer getMgr() {
        return mgr;
    }

    public void setMgr(Integer mgr) {
        this.mgr = mgr;
    }

    public Date getHiredate() {
        return hiredate;
    }

    public void setHiredate(Date hiredate) {
        this.hiredate = hiredate;
    }

    public Float getSal() {
        return sal;
    }

    public void setSal(Float sal) {
        this.sal = sal;
    }

    public Float getComm() {
        return comm;
    }

    public void setComm(Float comm) {
        this.comm = comm;
    }

    public Dept getDept() {
        return dept;
    }

    public void setDept(Dept dept) {
        this.dept = dept;
    }
}

EmpController

package com.kangna.springdatajpa.controller;

import com.kangna.springdatajpa.entity.Dept;
import com.kangna.springdatajpa.entity.Emp;
import com.kangna.springdatajpa.repository.DeptRepository;
import com.kangna.springdatajpa.repository.EmpRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

/********************************
 * @Author: kangna
 * @Date: 2020/1/9 21:57
 * @Version: 1.0
 * @Desc:
 ********************************/
@RestController // 默认所有的方法返回的是 JSON 字符串
@RequestMapping("/emp")
public class EmpController {

    @Autowired
    private EmpRepository empRepository;

    @Autowired
    private DeptRepository deptRepository;

    @GetMapping("/{id}")
    public Emp findById(@PathVariable("id") Integer id) {
        return empRepository.findById(id).get();
    }

    @GetMapping("/create")
    public Emp create() {
        Emp emp = new Emp();
        emp.setComm(0f);
        emp.setEname("kangna");
        emp.setHiredate(new Date());
        emp.setJob("deve");
        emp.setMgr(null);
        emp.setSal(25000f);
        Dept dept = deptRepository.findById(20).get();
        emp.setDept(dept);
        empRepository.save(emp);
        return emp;
    }
}

 新增

控制台打印出的SQL

insert into emp (comm, deptno, ename, hiredate, job, mgr, sal) values (?, ?, ?, ?, ?, ?, ?)

再去数据库看看数据是否插入

      

发布了114 篇原创文章 · 获赞 143 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_35995514/article/details/103894266
今日推荐