【Java】最简结构50行代码完成SpringBoot版的Hello World并且一篇文章学会SpringBoot版的MySQL增删改查全套

目录

 

0. 本文目的

1. 软件及版本

2. 新建项目

3.最简POM

4. Spring Boot启动类

5. 最简实体类

6.最简DAO

7. 普通的Controller

8.最简结构

9.不要过度设计

10.最后


0. 本文目的

产生背景

本人要参加某个全国计算机比赛,要求在4小时内局域网环境内编写B/S程序。4个小时的比赛时间非常紧张,于是需要准备能快速并且最少配置的搭建开发框架。因为没有互联网,就无法百度,无法查阅资料,一旦配置出错,后果是灾难性的。赛前在各种网站上一直没有找到最简单的增删改查,有的都是浅尝辄止的Hello World。于是,赛后我觉得一定要自己做个最简洁最高效的CUAD。并且要把关键代码直接贴到博客里,而不仅仅是的放到压缩包里。

内容说明

本文用最简的POM文件、最简的层次结构(Controller\Service\DAO\Model)、最简的DAO类、最简的实体类,采用Spring-DATA-JPA 、Thymeleaf技术来最终实现表的增删改查。若你发现你不会使用Spring Data JPA,不会使用Thymeleaf,不要紧很简单,看完案例,你会发现这些技术都很基础和简单。用上它们才是简洁制胜的法宝。

项目结构


1. 软件及版本

IDE:IntelliJ IDEA 2017.3 专业版(收费版)。破解方法自寻。

Maven 3.6.1

2. 新建项目

此步非本文重点,不作截图,仅文字描述。我们这里使用从maven处新建项目,所以保证您和maven服务器之间有网络连接。无论您连接的是互联网maven官网,或是局域网内的maven服务器。请确保maven服务器上有本文所需要的全部 jar 包。

  1. File-New-Project-Maven-选中【Create From archetype】-找到【org.apache.maven-archetypes:maven-archetype-webapp】(注意别找错了,有类似的);
  2. 输入GroupId: com.zxb 和ArtifactId: testBoot,或自拟;
  3. 一直下一步,直至出现新的项目窗口。
  4. 把下文中的代码或直接粘贴,或新建文件后粘贴进去,再进行适应性修改。

3.最简POM

下面是最简的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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zxb</groupId>
    <artifactId>testBoot</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!-- 指定Spring Boot的版本 2.0.4.RELEASE -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.4.RELEASE</version>
    </parent>

    <dependencies>
        <!-- 导入Spirng Boot  web 所需的jar包 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
    </dependencies>

    <packaging>jar</packaging>

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

仅需配置 Spring boot、spring-boot-starter-web(可以连接为Spring Booter核心)、spring-boot-starter-data-jpa(ORM持久层接口)、spring-boot-starter-thymeleaf(Spring Boot推荐的替代JSP的模板引擎)、mysql-connector-jara(连接mysql)。

这五个jar包就足够搭建个完整的可以对MySQL进行增删改查,页面遍历复杂列表数据的网站系统了。

如果你觉得没学过 Thymeleaf模板引擎,可以先看下去,你会发现它其实很简单,和<c:if>之流类似。

POM.xml文件编写好后,然后在IDEA的maven窗口右键 Reimport 一下,IDEA会自动导入POM.xml中所需要的jar包。

4. Spring Boot启动类

MyMain.java

package com.zxb.controller;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

/**
 * @SpringBootApplication:标注一个主程序类,用来标明这是一个Spring Boot应用
 */
@EnableAutoConfiguration
@SpringBootApplication
@EnableJpaRepositories
public class MyMain {
    // Spring应用启动起来
    public static void main(String[] args) {

        SpringApplication.run(MyMain.class,args);
    }
}

启动类写完,就可 Run 一次了。可以在浏览器中打开 http://localhost:8080,可以看到有文字显示。

至此,Spring Boot版本的Hello World就完成了,可以说这些步骤毫无使用价值。下面看如何实现MySQL表的增删改查,包括model/Entity/POJO层、Service层、DAO层、Controller层设计。

5. 最简实体类

这个项目里,我们全使用注解,不需一个实体类映射文件,也不需要任何Mybatis的xml文件。简洁高效,这才是理想的开发。举个例子。

BookEntity.java

package com.zxb.controller.model;

import java.io.Serializable;
import javax.persistence.*;

@Entity
@Table(name="bookstore")
public class BookEntity implements Serializable{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    protected Long id;

    public String getStorename() {
        return storename;
    }

    public void setStorename(String storename) {
        this.storename = storename;
    }

    @Column(name = "storename")
    protected String storename;

    public String getLocation() {
        return location;
    }

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

    @Column(name = "location")
    protected String location;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }


}

6.最简DAO

看看这个DAO层(与数据库交互的层)有多简单,这全都是Spring Data JPA框架的功劳。

BookDAO.java

package com.zxb.controller.dao;

import com.zxb.controller.model.BookEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;

@Repository
public interface BookDAO extends JpaRepository<BookEntity, Integer>{

    public BookEntity findById(Long id);

    public BookEntity save(BookEntity user);

    @Query(value = "SELECT u FROM BookEntity u WHERE storename=:storename")
    public BookEntity findName(@Param("storename") String storename);

    @Query(value="select u FROM BookEntity u ")
    public List<BookEntity> findAll();

}

当然,这里仅仅列举了最简单的几个函数,但从中可以窥见 Spring Data JPA技术为我们做了很多的工作。我们既然选用Spring Boot,却为何放这么好的工具不用呢,却手动去造轮子,重复编写 MyBaits 查询?

这里是使用了注解形式进行查询,注解中的查询语句既可以是Hibernate的HQL语句,也可以是 原声的 SQL语句。若想使用原生态的SQL语句,则可以使用这个注解:

@Query(value="select * from Book" ,native= true) 

native=true的意思就是使用原生的SQL查询。

我们仔细看看这个写法。注意:这个 BookDAO 不是个类,而是个 Interface,继承了 JpaRepository 这个Spring Data JPA给我们设计好的数据库持久接口,我们可以打开这个 JpaRepository,看看它给我们已经做好了哪些工作。

package org.springframework.data.jpa.repository;

import java.util.List;
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> {
    List<T> findAll();

    List<T> findAll(Sort var1);

    List<T> findAllById(Iterable<ID> var1);

    <S extends T> List<S> saveAll(Iterable<S> var1);

    void flush();

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

    void deleteInBatch(Iterable<T> var1);

    void deleteAllInBatch();

    T getOne(ID var1);

    <S extends T> List<S> findAll(Example<S> var1);

    <S extends T> List<S> findAll(Example<S> var1, Sort var2);
}

其实,这里面还有很多智能化的东西,我没有深入去研究。大家可以自己去搜索,Spring Data JPA的用法。下面我们看看这个DAO接口如何使用,我贴出Service层。

BookService.java

package com.zxb.controller.service;

import com.zxb.controller.dao.BookDAO;
import com.zxb.controller.model.BookEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class BookService {
    @Autowired
    private BookDAO bookDAO;

    public void save(BookEntity bookEntity){
        bookDAO.save(bookEntity);
    }

    public List list(){
        return bookDAO.findAll();
    }
}

如上图所示,我们的 BookDAO 接口是可以直接使用的,无需实现该接口的继承类。并且还可以直接使用 BookDAO 的父亲接口 ,也就是 Spring Data JPA给我们设计好的 JpaRepository 里面的通用方法,是不是超简单。

7. 普通的Controller

Controller层已经很简单,还是普通的用法。

TestContoller.java

package com.zxb.controller.control;

import com.zxb.controller.model.BookEntity;
import com.zxb.controller.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import java.awt.print.Book;
import java.util.List;

@Controller
@EnableAutoConfiguration
public class TestController {

    @Autowired
    private BookService bookService;

    //系统首页
    @RequestMapping("/")
    @ResponseBody
    public String index(){
        return "Hello Spring Boot.访问http://localhost:8080/book/add进行新增测试;访问http://localhost:8080/book/list查看列表";
    }

    //跳转至录入页面
    @RequestMapping("/book/add")
    public ModelAndView add(){
        System.out.print("add..............");
        ModelAndView mv = new ModelAndView();
        mv.setViewName("add");
        return mv;
    }

    //跳转至列表页面
    @RequestMapping("/book/list")
    public ModelAndView list(){
        List<BookEntity> bookList = bookService.list();
//        for (int i = 0; i < bookList.size(); i++) {
//            System.out.print("---------------------"+bookList.get(i).getId());
//        }
        ModelAndView mv = new ModelAndView();
        mv.setViewName("list");
        mv.addObject("bookList",bookList);

        return mv;
    }

    //保存表单
    @RequestMapping("/book/save")
    public String save(@RequestParam(name="bookstore")
            String storename, @RequestParam(name="location") String location){
        BookEntity bookEntity = new BookEntity();
        System.out.print(storename);
        bookEntity.setStorename(storename);
        bookEntity.setLocation(location);
        bookService.save(bookEntity);
        System.out.print(bookEntity.getStorename());
        return "redirect:/book/list";
    }


}

8.最简结构

我很反感这样的层次结构:

sevice/serviceImple、DAO/DAOImpl、BookEntity/BookEntity.hbm.xml/Mapper.xml。

我觉得软件应以生产效率为目标,而坚持非死板的教条主义。我也做过有些规模的软件项目,这样的结构并没有想象中的那样灵活,更多时候在出现需求变更时,我们直接全都是新建类、新建方法,全都是新建,并没有体现出接口和接口实现的作用。我不否认自己未严格按照最优设计去做。但还是要务实些,这些接口和接口实现不会在实践中出现。

我认为小项目结构更适合这个:

Contoller、单层Service、单层DAO、单层Model/Entity/POJO。

9.不要过度设计

一切为生产为实际服务。务实,一定要务实。项目大型程度决定设计复杂程度。效率第一。

10.最后

附上其它文件,使得你可以不用下载zip就能对整个结构有个清晰的了解:

最简配置文件 application.properties

#使用Spring Boot默认的thymeleat模板引擎,可不用显示配置视图解析器,仅需将html等文件
#放在指定的默认目录: resources/template 下即可。切记resources 复数形式的s不可丢,否则报错。

#mysql
#注意设置MYSQL的sever/database/table必须全设置为utf-8
#注意设置IDEA的所有encoding编码均为utf-8
#注意本配置文件中的url必须加上?后的参数,否则会出现汉字乱码!
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&amp&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driverclass=com.mysql.jdbc.Driver
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

这其中,连视图解析器都不用配置。只要你按Spring Boot的默认约定,把HTML都放在 resources/template 目录下。注意这个路径一个字母一个s都不能少。如果你写成 resource/template那就会报错,就需要在配置文件中配置视图解析器!

空无一物的 web.xml,这个仍是默认内容:

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
</web-app>

增加书籍页面 add.html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
新增页面
<form action="/book/save" method="post">

    书店名称:<input type="text" value="" name="bookstore"/>
    书店位置:<input type="text" value="" name="location"/>
    <input type="submit" value="提交"/>
</form>
</body>
</html>

列表页面 list.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns:th="http://www.thymeleaf.org">
<head >
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>列表页面
<p th:text="${name}"></p>

<ul th:each="item:${bookList}">
    <li>id:<span th:text="${{item.id}}" /></li>
    <li>书店:<span th:text="${item.storename}"</li>
    <li>位置:<span th:text="${item.location}"</li>
</ul>


</body>
</html>

注意:

1. 列表页面,简单的使用了 thymeleaf 做遍历数据库。

2. 列表页面,使用 thymeleaf 需要在 <html> 根标签处加上 thymeleaf 的命名空间属性。

<html xmlns:th="http://www.thymeleaf.org">

不见此属性,thymeleaf 的标签是不会被识别和解析的。切记。

发布了58 篇原创文章 · 获赞 44 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/qilei2010/article/details/102617037
今日推荐