SpringBoot学习笔记(四、JPA)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: SpringBoot学习笔记(四、JPA)

前置:Jsp视图

Springboot的默认视图支持是Thymeleaf,还没学到,jsp用起来比较熟,先用它过渡一下。

1、在pom.xml中添加对Jsp的支持:

<!-- servlet依赖. -->
        <dependency>
              <groupId>javax.servlet</groupId>
              <artifactId>javax.servlet-api</artifactId>
        </dependency>
              <dependency>
                     <groupId>javax.servlet</groupId>
                     <artifactId>jstl</artifactId>
              </dependency>
        <!-- tomcat的支持.,用于编译jsp-->
        <dependency>
               <groupId>org.apache.tomcat.embed</groupId>
               <artifactId>tomcat-embed-jasper</artifactId>
        </dependency> 

application.properties配置:

spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp

这个是jsp文件的前置和后缀,在webapp下新建WEB-INF文件夹,在WEB-INF下新建jsp文件夹,jsp文件就放在这,关于jsp的配置就完成了,也可以写个Controller和jsp来测试一下是否配置成功。

一、整合JPA

我以前是没见过这玩意的,先了解一下JPA:

JPA全称Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。

JPA 的目标之一是制定一个可以由很多供应商实现的API,并且开发人员可以编码来实现该API,而不是使用私有供应商特有的API。

JPA是需要Provider来实现其功能的,Hibernate就是JPA Provider中很强的一个,应该说无人能出其右。从功能上来说,JPA就是Hibernate功能的一个子集。

1、在pom.xml中添加相应的依赖添加依赖:

添加spring-boot-starter-jdbc依赖:

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

添加mysql连接类和连接池类:

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

完整的pom.xml

<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>edu.hpu</groupId>
  <artifactId>SpringBoot</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>SpringBoot</name>
  <!-- Spring Boot 启动父依赖 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
    </parent>
    <dependencies>
        <!-- Spring Boot web依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- spring test -->
        <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-test</artifactId>
           <scope>test</scope>
        </dependency>
        <!-- Junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!-- 添加servlet依赖 -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
        </dependency>
        <!--添加 jstl依赖 -->
        <dependency>
           <groupId>javax.servlet</groupId>
           <artifactId>jstl</artifactId>
        </dependency>
        <!-- 用于编译jsp -->
        <dependency>
           <groupId>org.apache.tomcat.embed</groupId>
           <artifactId>tomcat-embed-jasper</artifactId>
        </dependency>
        <!-- 热部署依赖 -->
        <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional> <!-- 这个需要为 true 热部署才有效 -->
        </dependency>
        <!-- 添加对mysql的支持 -->
        <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <version>5.1.21</version>
        </dependency>
        <!-- 添加对jpa的支持 -->
        <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
    </dependencies>
    <properties>
      <java.version>1.8</java.version>
    </properties>
    <build>
       <plugins>
           <plugin>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-maven-plugin</artifactId>
           </plugin>
       </plugins>
    </build>
</project>

2、数据源

JPA是干什么的,是搞数据库持久化的,我们得有数据。这里数据库用的是mysql.

创建数据库:

create database springbootjpa;

创建表:

use springbootjpa;
CREATE TABLE category_ (
  id int(11) NOT NULL AUTO_INCREMENT,
  name varchar(30),
  PRIMARY KEY (id)
) DEFAULT CHARSET=UTF8;

添加数据:

这个看着随便添加吧。

3、数据源配置:

在application中配置相应数据源,

spring.datasource.url=jdbc:mysql://localhost:3306/springbootjpa?characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=xing0515
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.hbm2ddl.auto=update

完整的application.properties:

spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
spring.datasource.url=jdbc:mysql://localhost:3306/springbootjpa?characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=xing0515
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.hbm2ddl.auto=update

4、创建实体类

新建一个包edu.hpu.springboot.pojo,在包下新建实体类Category,代码如下:

package edu.hpu.springboot.pojo;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
//对应category_的实体类
@Entity                            //表示这是个实体类
@Table(name="category_")       //表示对应的表
public class Category {
   @Id                               //表示主键
   @GeneratedValue(strategy = GenerationType.IDENTITY)   //表明自增长方式
   @Column(name="id")                           //表示对应的字段
   private int id;
   @Column
   private String name;
public int getId() {
  return id;
}
public void setId(int id) {
  this.id = id;
}
public String getName() {
  return name;
}
public void setName(String name) {
  this.name = name;
}
   @Override
  public String toString() {
    return "Category [id=" + id + ", name=" + name + "]";
  }
}

关于相应注解:

注解 解释
@Entity 声明类为实体或表。
@Table 声明表名。
@Basic 指定非约束明确的各个字段。
@Embedded 指定类或它的值是一个可嵌入的类的实例的实体的属性。
@Id 指定的类的属性,用于识别(一个表中的主键)。
@GeneratedValue 指定如何标识属性可以被初始化,例如自动、手动、或从序列表中获得的值。
@Transient 指定的属性,它是不持久的,即:该值永远不会存储在数据库中。
@Column 指定持久属性栏属性。
@SequenceGenerator 指定在@GeneratedValue注解中指定的属性的值。它创建了一个序列。
@TableGenerator 指定在@GeneratedValue批注指定属性的值发生器。它创造了的值生成的表。
@AccessType 这种类型的注释用于设置访问类型。如果设置
@AccessType(FIELD ) 则可以直接访问变量并且不需要getter和setter,但必须为public。如果设置@AccessType(PROPERTY),通过getter和setter方法访问Entity的变量。
@JoinColumn 指定一个实体组织或实体的集合。这是用在多对一和一对多关联。
@UniqueConstraint 指定的字段和用于主要或辅助表的唯一约束。
@ColumnResult 参考使用select子句的SQL查询中的列名。
@ManyToMany 定义了连接表之间的多对多一对多的关系。
@ManyToOne 定义了连接表之间的多对一的关系。
@OneToMany 定义了连接表之间存在一个一对多的关系。
@OneToOne 定义了连接表之间有一个一对一的关系。
@NamedQueries 指定命名查询的列表。
@NamedQuery 指定使用静态名称的查询

5、CategoryDao

 新建包edu.hpu.springoot.dao,在包下新建接口CategoryDao,继承继承了JpaRepository,并且提供泛型<Category,Integer>  表示这个是针对Category类的DAO,Integer表示主键是Integer类型。

package edu.hpu.springboot.dao;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import edu.hpu.springboot.pojo.*;
/*继承了JpaRepository,并且提供泛型<Category,Integer> 
 * 表示这个是针对Category类的DAO,Integer表示主键是Integer类型
 * JpaRepository 这个父接口,就提供了CRUD, 分页等等一系列的查询了,直接拿来用
 */
public interface CategoryDao extends JpaRepository<Category, Integer>{
     public List<Category> findByName(String name);
     public List<Category> findByNameLikeAndIdGreaterThanOrderByNameAsc(String name, int id);
}

JpaRepository提供的一些预先生成方法:

image.png

还可以自定义一些查询,后面再看。

6、CategoryController

这个省略了Service,一般是不能省略的,新建包edu…hpu.springboot.web,创建类CategoryController

package edu.hpu.springboot.web;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import com.how2java.springboot.dao.CategoryDAO;
import com.how2java.springboot.pojo.Category;
@Controller
public class CategoryController {
    @Autowired CategoryDAO categoryDAO;
    @RequestMapping("/listCategory")
    public String listCategory(Model m) throws Exception {
        List<Category> cs=categoryDAO.findAll();
        m.addAttribute("cs", cs);
        return "listCategory";
    }
}

7、listCategory.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<table align='center' border='1' cellspacing='0'>
    <tr>
        <td>id</td>
        <td>name</td>
    </tr>
    <c:forEach items="${cs}" var="c" varStatus="st">
        <tr>
            <td>${c.id}</td>
            <td>${c.name}</td>
        </tr>
    </c:forEach>
</table>

8、启动Application,访问网址http://127.0.0.1:8080/listCategory

官方文档也看了一下,不是想象中的那么费劲,有空可以仔细看看,提升一下自己的英文文档阅读能力。Accessing Data with JPA

二、CRUD+分页

1、修改CategoryController,增加、删除、获取、修改映射

package edu.hpu.springboot.web;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import edu.hpu.springboot.dao.CategoryDao;
import edu.hpu.springboot.pojo.Category;
@Controller
public class CategoryController {
   @Autowired
   CategoryDao categoryDao;
   @RequestMapping("/addCategory")
   public String addCategory(Category c) throws Exception{
     categoryDao.save(c);
     return "redirect:listCategory";
   }
   @RequestMapping("/deleteCategory")
   public String deleteCategory(Category c) throws Exception{
     categoryDao.delete(c);
     return "redirect:listCategory";
   }
   @RequestMapping("/editCategory")
   public String editCategory(int id,Model m) throws Exception{
     Category c=categoryDao.findOne(id);
     m.addAttribute("c", c);   
     return "editCategory";
   }
   @RequestMapping("/updateCategory")
   public String updateCategory(Category c) throws Exception{
     categoryDao.save(c);
    return "redirect:listCategory";
   }
   @RequestMapping("/listCategory")
    public String listCategory(Model m,@RequestParam(value = "start", defaultValue = "0")
        int start,@RequestParam(value="size",defaultValue="5")int size) throws Exception{
     start = start<0?0:start;
     Sort sort=new Sort(Sort.Direction.DESC, "id");
     Pageable pageable=new PageRequest(start, size, sort);
     Page<Category> page=categoryDao.findAll(pageable);
     System.out.println(page.getNumber());
       System.out.println(page.getNumberOfElements());
       System.out.println(page.getSize());
       System.out.println(page.getTotalElements());
       System.out.println(page.getTotalPages());
       m.addAttribute("page", page);
     return "listCategory";
   }
}

查询映射也做了相应的更改:

(1)、 在参数里接受当前是第几页 start ,以及每页显示多少条数据 size。 默认值分别是0和5。

(Model m,@RequestParam(value = "start", defaultValue = "0") int start,@RequestParam(value = "size", defaultValue = "5") int size)

(2)、 如果 start 为负,那么修改为0. 这个事情会发生在当前是首页,并点击了上一页的时候

start = start<0?0:start;

(3)、 设置倒排序

Sort sort = new Sort(Sort.Direction.DESC, "id");

(4)、 根据start,size和sort创建分页对象

Pageable pageable = new PageRequest(start, size, sort);

(5)、 CategoryDAO根据这个分页对象获取结果page.

Page<Category> page =categoryDAO.findAll(pageable);

在这个page对象里,不仅包含了分页信息,还包含了数据信息,即有哪些分类数据。 这个可以通过getContent()获取出来。

(6)、把page放在"page"属性里,跳转到listCategory.jsp

m.addAttribute("page", page);
return "listCategory";

2、listCategory.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>   
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>查看分类</title>
</head>
<body>
  <div style="width: 500px; margin: 20px auto; text-align: center">
    <table align='center' border='1' cellspacing='0'>
      <tr>
        <td>id</td>
        <td>name</td>
        <td>编辑</td>
        <td>删除</td>
      </tr>
      <c:forEach items="${page.content}" var="c" varStatus="st">
        <tr>
          <td>${c.id}</td>
          <td>${c.name}</td>
          <td><a href="editCategory?id=${c.id}">编辑</a></td>
          <td><a href="deleteCategory?id=${c.id}">删除</a></td>
        </tr>
      </c:forEach>
    </table>
    <br>
    <div>
      <a href="?start=0">[首 页]</a> <a href="?start=${page.number-1}">[上一页]</a>
      <a href="?start=${page.number+1}">[下一页]</a> <a
        href="?start=${page.totalPages-1}">[末 页]</a>
    </div>
    <br>
    <form action="addCategory" method="post">
      name: <input name="name"> <br>
      <button type="submit">提交</button>
    </form>
</body>
</html>

3、editCategory.jsp

修改分类:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>修改</title>
</head>
<body>
  <div style="margin: 0px auto; width: 500px">
    <form action="updateCategory" method="post">
      name: <input name="name" value="${c.name}"> <br> <input
        name="id" type="hidden" value="${c.id}">
      <button type="submit">提交</button>
    </form>
  </div>
</body>
</html>

4、运行

由于采用的是热部署,直接访问

image.pngimage.png5、最后再加一点JPA的拓展:自定义简单查询

自定义的简单查询就是根据方法名来自动生成 SQL,主要的语法是findXXBy,readAXXBy,queryXXBy,countXXBy, getXXBy后面跟属性名称:

Category findByCategoryName(String name);

也使用一些加一些关键字And 、 Or

Category findByCategoryNameOrId(String name,int id);

JPA同样可以实现复杂查询——分页查询、限制查询,

自定义SQL查询

多表查询

直接参考,用时再查:

Spring Boot(五):Spring Boot Jpa 的使用

Spring Data JPA - Reference Documentation


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
7月前
|
Java Spring
Springboot+jpa如何设置启动项目表不存在就主动创建,字段没有就新增
Springboot+jpa如何设置启动项目表不存在就主动创建,字段没有就新增
520 0
|
7月前
|
Java
Springboot+JPA+Sqlite整合demo
Springboot+JPA+Sqlite整合demo
249 0
|
6月前
|
druid Java 关系型数据库
Spring Boot2 系列教程(二十五)Spring Boot 整合 Jpa 多数据源
Spring Boot2 系列教程(二十五)Spring Boot 整合 Jpa 多数据源
|
2月前
|
SQL Java 关系型数据库
Springboot引入jpa来管理数据库
Springboot引入jpa来管理数据库
47 0
Springboot引入jpa来管理数据库
|
2月前
|
SQL Java 数据库连接
springBoot+Jpa(hibernate)数据库基本操作
springBoot+Jpa(hibernate)数据库基本操作
53 0
|
3月前
|
Java 数据库连接 API
【Java笔记+踩坑】Spring Data JPA
从常用注解、实体类和各层编写方法入手,详细介绍JPA框架在增删改查等方面的基本用法,以及填充用户名日期、分页查询等高级用法。
【Java笔记+踩坑】Spring Data JPA
|
4月前
|
Java 关系型数据库 MySQL
|
4月前
|
安全 Java 数据安全/隐私保护
基于SpringBoot+Spring Security+Jpa的校园图书管理系统
本文介绍了一个基于SpringBoot、Spring Security和JPA开发的校园图书管理系统,包括系统的核心控制器`LoginController`的代码实现,该控制器处理用户登录、注销、密码更新、角色管理等功能,并提供了系统初始化测试数据的方法。
62 0
基于SpringBoot+Spring Security+Jpa的校园图书管理系统
|
4月前
|
Java Spring 数据库
怎样动动手指就能实现数据操作?Spring Data JPA背后的魔法揭秘
【8月更文挑战第31天】在Java开发中,数据库交互至关重要。传统的JDBC操作繁琐且难维护,而Spring Data JPA作为集成JPA的数据访问层解决方案,提供了CRUD等通用操作接口,显著减少代码量。通过继承`JpaRepository`,开发者能轻松实现数据的增删改查,甚至复杂查询和分页也不再困难。本文将通过示例详细介绍如何利用Spring Data JPA简化数据访问层的开发,提升代码质量和可维护性。
45 0
|
4月前
|
存储 Java 数据库