zoukankan      html  css  js  c++  java
  • 笔记65 Spring Boot快速入门(五)

    SpringBoot+JPA

    一、什么是JPA?

      JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。真正干活的可能是Hibernate,TopLink等等实现了JPA规范的不同厂商,默认是Hibernate。

    二、在springboot中使用JPA对数据库进行抽插

    (一)目录结构

    (二)pom.xml

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     3          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     4     <modelVersion>4.0.0</modelVersion>
     5 
     6     <groupId>com.example</groupId>
     7     <artifactId>springboot-jpa-demo</artifactId>
     8     <version>0.0.1-SNAPSHOT</version>
     9     <packaging>jar</packaging>
    10 
    11     <name>springboot-jpa-demo</name>
    12     <description>Demo project for Spring Boot</description>
    13 
    14     <parent>
    15         <groupId>org.springframework.boot</groupId>
    16         <artifactId>spring-boot-starter-parent</artifactId>
    17         <version>1.5.9.RELEASE</version>
    18         <relativePath/> <!-- lookup parent from repository -->
    19     </parent>
    20 
    21     <properties>
    22         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    23         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    24         <java.version>1.8</java.version>
    25     </properties>
    26 
    27     <dependencies>
    28         <dependency>
    29             <groupId>org.springframework.boot</groupId>
    30             <artifactId>spring-boot-starter-data-jpa</artifactId>
    31         </dependency>
    32         <dependency>
    33             <groupId>org.springframework.boot</groupId>
    34             <artifactId>spring-boot-starter-jdbc</artifactId>
    35         </dependency>
    36         <dependency>
    37             <groupId>org.springframework.boot</groupId>
    38             <artifactId>spring-boot-starter-tomcat</artifactId>
    39         </dependency>
    40         <dependency>
    41             <groupId>org.springframework.boot</groupId>
    42             <artifactId>spring-boot-starter-web</artifactId>
    43         </dependency>
    44 
    45         <dependency>
    46             <groupId>mysql</groupId>
    47             <artifactId>mysql-connector-java</artifactId>
    48             <version>5.1.21</version>
    49         </dependency>
    50         <dependency>
    51             <groupId>org.springframework.boot</groupId>
    52             <artifactId>spring-boot-starter-test</artifactId>
    53             <scope>test</scope>
    54         </dependency>
    55 
    56         <dependency>
    57             <groupId>org.springframework.boot</groupId>
    58             <artifactId>spring-boot-starter-thymeleaf</artifactId>
    59         </dependency>
    60     </dependencies>
    61 
    62     <build>
    63         <plugins>
    64             <plugin>
    65                 <groupId>org.springframework.boot</groupId>
    66                 <artifactId>spring-boot-maven-plugin</artifactId>
    67             </plugin>
    68         </plugins>
    69     </build>
    70 
    71 
    72 </project>

    1.数据库准备:创建表,插入数据等(略)

    给出application.properties

    1 spring.datasource.url=jdbc:mysql://127.0.0.1:3306/sh?characterEncoding=UTF-8
    2 spring.datasource.username=root
    3 spring.datasource.password=123456
    4 spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    5 spring.jpa.properties.hibernate.hbm2ddl.auto=update
    6 
    7 server.port=8080
    8 server.context-path=/Test·

    2.IDEA新建项目(列出比较重要的步骤)

    3.新建pojo——Category

     1 package com.example.springbootjpademo.pojo;
     2 
     3 import javax.persistence.*;
     4 
     5 @Entity
     6 @Table(name = "category")
     7 public class Category {
     8     @Id
     9     @GeneratedValue(strategy = GenerationType.IDENTITY)
    10     @Column(name = "id")
    11     private int id;
    12 
    13     @Column(name = "name")
    14     private String name;
    15     public int getId() {
    16         return id;
    17     }
    18     public void setId(int id) {
    19         this.id = id;
    20     }
    21     public String getName() {
    22         return name;
    23     }
    24     public void setName(String name) {
    25         this.name = name;
    26     }
    27 }

    4.创建DAO

      创建dao接口CategoryDAO,继承了JpaRepository,并且提供泛型<Category,Integer> 表示这个是针对Category类的DAO,Integer表示主键是Integer类型。
      JpaRepository 这个父接口,就提供了CRUD, 分页等等一系列的查询了,直接拿来用,都不需要二次开发的了。

    1 package com.example.springbootjpademo.dao;
    2 
    3 import com.example.springbootjpademo.pojo.Category;
    4 import org.springframework.data.jpa.repository.JpaRepository;
    5 
    6 public interface CategoryDAO extends JpaRepository<Category,Integer> {
    7 }

    5.创建Controller

    自动加载CategoryDAO,然后调用findAll()查询所有条目。

     1 package com.example.springbootjpademo.controller;
     2 
     3 import com.example.springbootjpademo.dao.CategoryDAO;
     4 import com.example.springbootjpademo.pojo.Category;
     5 import org.springframework.beans.factory.annotation.Autowired;
     6 import org.springframework.stereotype.Controller;
     7 import org.springframework.ui.Model;
     8 import org.springframework.web.bind.annotation.RequestMapping;
     9 
    10 import java.util.List;
    11 @Controller
    12 public class CategoryController {
    13     @Autowired
    14     CategoryDAO categoryDAO;
    15 
    16     @RequestMapping("/listCategory")
    17     public  String ListCategory(Model model) throws Exception{
    18         List<Category> categoryList=categoryDAO.findAll();
    19         model.addAttribute("categories",categoryList);
    20         return "listCategory";
    21     }
    22 }

    6.创建view(使用Thymeleaf)

    listCategory.html

     1 <!DOCTYPE html>
     2 <html lang="en" xmlns:th="http://www.thymeleaf.org">
     3 <head>
     4     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
     5     <title>Title</title>
     6 </head>
     7 <body>
     8 <div class="showing">
     9     <h2>springboot+jpa</h2>
    10 
    11     <table>
    12         <thead>
    13         <tr>
    14             <th>id</th>
    15             <th>name</th>
    16         </tr>
    17         </thead>
    18         <tbody>
    19         <tr th:each="c: ${categories}">
    20             <td align="center" th:text="${c.id}"></td>
    21             <td align="center" th:text="${c.name}"></td>
    22         </tr>
    23         </tbody>
    24     </table>
    25 </div>
    26 </body>
    27 </html>

    7.测试

    三、总结(目前遇到的问题,可能有出入)

    1.注意springboot自动扫描和装配的规则。

    SpringBoot项目的Bean装配默认规则是根据Application类所在的包位置从上往下扫描!

    “Application类”是指SpringBoot项目入口类。这个类的位置很关键:
    如果Application类所在的包为:com.boot.app,则只会扫描com.boot.app包及其所有子包,如果service或dao所在包不在com.boot.app及其子包下,则不会被扫描!
    即, 把Application类放到dao、service所在包的上级,com.boot.Application

    2.jpa与2.0.3版本的springboot之间存在冲突,会导致项目出现问题。

    3.JpaRepository 继承PagingAndSortingRepository,实现一组JPA规范相关的方法。

    <1>什么是Repository

      Repository(资源库):通过用来访问领域对象的一个类似集合的接口,在领域与数据映射层之间进行协调。这个叫法就类似于我们通常所说的DAO,在这里,我们就按照这一习惯把数据访问层叫Repository 
      Spring Data给我们提供几个Repository,基础的Repository提供了最基本的数据访问功能,其几个子接口则扩展了一些功能。它们的继承关系如下: 

    Repository: 仅仅是一个标识,表明任何继承它的均为仓库接口类,方便Spring自动扫描识别 
    CrudRepository: 继承Repository,实现了一组CRUD相关的方法 

    PagingAndSortingRepository: 继承CrudRepository,实现了一组分页排序相关的方法 

    JpaRepository: 继承PagingAndSortingRepository,实现一组JPA规范相关的方法 

    JpaSpecificationExecutor: 比较特殊,不属于Repository体系,实现一组JPA Criteria查询相关的方法 
    我们自己定义的XxxxRepository需要继承JpaRepository,这样我们的XxxxRepository接口就具备了通用的数据访问控制层的能力。

    <2>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();//删除所有实体,不用或慎用! 

    <3>PagingAndSortingRepository接口

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

    <4>JpaRepository接口

      这个接口提供了JPA的相关功能 
      List<T> findAll();//查找所有实体 
        List<T> findAll(Sort sort);//排序 查找所有实体 
        List<T> save(Iterable<? extends T> entities);//保存集合 
        void flush();//执行缓存与数据库同步 
        T saveAndFlush(T entity);//强制执行持久化 
      void deleteInBatch(Iterable<T> entities);//删除一个实体集合 
     

    四、使用JPA进行CRUD和分页

    1.在CategoryController中添加映射:增、删、改、查。

     1     @RequestMapping("/listCategories")
     2     public  String ListCategories(Model model,
     3                                   @RequestParam(value = "start",defaultValue = "0")int start,
     4                                   @RequestParam(value = "size",defaultValue = "5") int size
     5                                   ) throws Exception{
     6         start=start<0?0:start;
     7         Sort sort=new Sort(Sort.Direction.DESC,"id");
     8         Pageable pageable=new PageRequest(start,size,sort);
     9         Page<Category> page=categoryDAO.findAll(pageable);
    10         model.addAttribute("page",page);
    11         return "listCategories";
    12     }
    13 
    14     //JPA 新增和修改用的都是save. 它根据实体类的id是否为0来判断是进行增加还是修改
    15     @RequestMapping("/addCategory")
    16     public String addCategory(Category category) throws Exception{
    17         categoryDAO.save(category);
    18         return "redirect:listCategories";
    19     }
    20     @RequestMapping("/deleteCategory")
    21     public String deleteCategory(Category category)throws Exception{
    22         categoryDAO.delete(category);
    23         return "redirect:listCategories";
    24     }
    25     @RequestMapping("/updateCategory")
    26     public String updateCategory(Category category)throws Exception{
    27         categoryDAO.save(category);
    28         return "redirect:listCategories";
    29     }
    30     @RequestMapping("/editCategory")
    31     public String editCategory(int id,Model model)throws Exception{
    32         Category category=categoryDAO.getOne(id);
    33         model.addAttribute("category",category);
    34         return "editCategory";
    35     }

    知识点:

    <1>Page是Spring Data提供的一个接口,该接口表示一部分数据的集合以及其相关的下一部分数据、数据总数等相关信息,通过该接口,我们可以得到数据的总体信息(数据总数、总页数...)以及当前数据的信息(当前数据的集合、当前页数等)。

     1 public interface Page<T> extends Iterable<T> {
     2  
     3     int getNumber();            //当前第几页   返回当前页的数目。总是非负的
     4  
     5     int getSize();                //返回当前页面的大小。
     6  
     7     int getTotalPages();         //返回分页总数。
     8  
     9     int getNumberOfElements();   //返回当前页上的元素数。
    10  
    11     long getTotalElements();    //返回元素总数。
    12  
    13     boolean hasPreviousPage();  //返回如果有上一页。
    14  
    15     boolean isFirstPage();      //返回当前页是否为第一页。
    16  
    17     boolean hasNextPage();      //返回如果有下一页。
    18  
    19     boolean isLastPage();       //返回当前页是否为最后一页。
    20  
    21     Iterator<T> iterator();
    22  
    23     List<T> getContent();     //将所有数据返回为List
    24  
    25     boolean hasContent();     //返回数据是否有内容。
    26  
    27     Sort getSort();          //返回页的排序参数。
    28 }

    <2>Pageable 是Spring Data库中定义的一个接口,该接口是所有分页相关信息的一个抽象,通过该接口,我们可以得到和分页相关所有信息(例如pageNumber、pageSize等),这样,Jpa就能够通过pageable参数来得到一个带分页信息的Sql语句。

     1 /**
     2  * 分页信息抽象接口
     3  * 
     4  * @author Oliver Gierke
     5  */
     6 public interface Pageable {
     7  
     8     /**
     9      * 返回要返回的页面.
    10      * 
    11      * @return the page to be returned.
    12      */
    13     int getPageNumber();
    14  
    15     /**
    16      * 返回要返回的项目的数量。
    17      * 
    18      * @return the number of items of that page
    19      */
    20     int getPageSize();
    21  
    22     /**
    23      * 根据底层页面和页面大小返回偏移量。
    24      * 
    25      * @return the offset to be taken
    26      */
    27     int getOffset();
    28  
    29     /**
    30      * 返回排序参数。
    31      * 
    32      * @return
    33      */
    34     Sort getSort();
    35 }

    2.数据展示页listCategories.html

     1 <!DOCTYPE html>
     2 <html lang="en" xmlns:th="http://www.thymeleaf.org">
     3 <head>
     4     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
     5     <title>Title</title>
     6 </head>
     7 <body>
     8 <div class="showing">
     9     <h2>springboot+jpa</h2>
    10     <div style="500px;margin:20px auto;text-align: center">
    11         <table align="center" border="1" cellspacing="0">
    12             <thead>
    13             <tr>
    14                 <th>id</th>
    15                 <th>name</th>
    16                 <td>编辑</td>
    17                 <td>删除</td>
    18             </tr>
    19             </thead>
    20             <tbody>
    21             <tr th:each="c: ${page}">
    22                 <td align="center" th:text="${c.id}"></td>
    23                 <td align="center" th:text="${c.name}"></td>
    24                 <td align="center" ><a th:href="@{/editCategory(id=${c.id})}">编辑</a></td>
    25                 <td align="center" ><a th:href="@{/deleteCategory(id=${c.id})}">删除</a></td>
    26             </tr>
    27             </tbody>
    28         </table>
    29         <br />
    30         <div>
    31             <a th:href="@{/listCategories(start=0)}">[首  页]</a>
    32             <a th:href="@{/listCategories(start=${page.number -1})}">[上一页]</a>
    33             <a th:href="@{/listCategories(start=${page.number +1})}">[下一页]</a>
    34             <a th:href="@{/listCategories(start=${page.totalPages -1})}">[末  页]</a>
    35         </div>
    36         <form action="/addCategory" method="post">
    37             name:<input name="name"/><br/>
    38             <button type="submit">提交</button>
    39         </form>
    40     </div>
    41 </div>
    42 </body>
    43 </html>

    3.修改页面editCategory.html

     1 <!DOCTYPE html>
     2 <html lang="en" xmlns:th="http://www.thymeleaf.org">
     3 <head>
     4     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
     5     <title>Title</title>
     6 </head>
     7 <body>
     8 <div class="showing">
     9     <h2>springboot+jpa</h2>
    10 
    11     <div style="margin:0px auto; 500px">
    12 
    13         <form action="/updateCategory" method="post">
    14 
    15             name: <input name="name" th:value="${category.name}" /> <br/>
    16 
    17             <input name="id" type="hidden" th:value="${category.id}" />
    18             <button type="submit">提交</button>
    19 
    20         </form>
    21     </div>
    22 </div>
    23 </body>
    24 </html>

    4.测试

     五、代码

    https://github.com/lyj8330328/springboot-jpa-demo

  • 相关阅读:
    jetbrains 官网进不去以及webstorm、node下载慢的问题
    因为后端 xss 全局过滤器导致的 jquery ajax post 提交的数据全部为null的问题
    华为jdk镜像地址
    shiro解决两个请求的sessionId相同,但是某一个传入sessionId之后找不到session的原因
    推荐一个好的webapp的服务,支持android/ios/小程序打包,集成了大量本地api
    对前后端分离的一些经验记录
    「caffe编译bug」python/caffe/_caffe.cpp:10:31: fatal error: numpy/arrayobject.h: No such file or directory
    「caffe编译bug」 undefined reference to `boost::match_results<__gnu_cxx::__normal_iterator<char const*, std::__cxx11
    「caffe编译bug」.build_release/lib/libcaffe.so: undefined reference to cv::imread
    python的sorted函数对字典按value进行排序
  • 原文地址:https://www.cnblogs.com/lyj-gyq/p/9301532.html
Copyright © 2011-2022 走看看