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

  • 相关阅读:
    C++学习9 this指针详解
    福建省第八届 Triangles
    UVA 11584 Partitioning by Palindromes
    POJ 2752 Seek the Name, Seek the Fame
    UVA 11437 Triangle Fun
    UVA 11488 Hyper Prefix Sets (字典树)
    HDU 2988 Dark roads(kruskal模板题)
    HDU 1385 Minimum Transport Cost
    HDU 2112 HDU Today
    HDU 1548 A strange lift(最短路&&bfs)
  • 原文地址:https://www.cnblogs.com/lyj-gyq/p/9301532.html
Copyright © 2011-2022 走看看