spring, web development,

用Spring boot框架做Hello World后端网页开发

DolorHunter DolorHunter Follow Dec 20, 2020 · 56 mins read

用Spring boot框架做Hello World后端网页开发
Share this

现在市面上最如日中天的网页开发框架, 当属 Spring boot. Spring 后端是用Java语言和SQL语言编写(但不必要). 之前实习期做的就是网页后端开发, 用的就是 Spring 框架. 实习期不是很长, 因此开发流程和技术都是项目技术老大填鸭式教的, 当时第一次接触网页开发也没什么概念, 就依葫芦画瓢照着做了一个很”老派”的网页后端. 在自学了 Django 这种比较新的框架后, 并且借由正在用Spring做网页开发又重新学一遍, 发现Spring也并不一定要像实习期间做的那样”老派”, 特此总结记录一下.

不过, 如果你是为了交课设大作业, 或者只是想自己做个小网页, 可以去学学 Django. 这是一个使用 Python 语言的框架, 开发起来比较轻量. 很多热门的网页也都是使用 Django 框架开发的, 例如 Pinterest, Instagram, Udemy, Robinhood, Coursera, Accenture 等等.

之前写的 Django 框架网页开发系列

Spring配置文件pom.xml

配置文件应该是入门 Spring 最难的部分, 如果你没有掌握正确的方法. Spring 使用的是 Maven 或 Gradle 自动架构工具, 用来安装 Spring 服务中需要用到的仓库和依赖.

我在实习期间有问过项目技术老大, 问他 pom 怎么配置, 他说是依靠经验进行配置的. 我不解, 看他在网站上查找了半天资料, 终于配置好前后端一体的 Spring 框架.

不过, 依照我这次的学习发现, 其实入门门槛并没在那么高. 看 Spring 官方教程介绍, 有一个配置生成器 Spring initializr, 依照你的需求生成需要的项目模板. 或者如果你用的是 IDEA, 可以参照这个文章完成搭建 Tutorial: Create your first Spring application, 我猜模板也是用 Spring initializr 生成的.

如果你需要开发网页前端, 就选Spring Web和Thymeleaf; 如果你需要数据库, 就选Spring Data JPA(JPA比JDBC多了hibernate, 可以自动建表并用Java语言执行CRUD操作, 就不用写SQL语言了); 为了开发方便, 可以选Spring Boot DevTools. 大概就是这么多.

仔细讲下去, 如果用Postman测试接口需要用junit; 用MySQL要用mysql-connector-java; 遇到配置问题需要spring-boot-autoconfigure; 还有一些奇奇怪怪的问题就自己去搜一搜官方文档.

虽然官方文档很旧, 但是看看总没错.

配置MySQL数据库

如果你有一台VPS(虚拟服务器), 可以在服务器上安装MySQL, 之后通过本地的 Navicat 或其他软件连接此服务器.

开发过程中整理的懒人包:

配置MySQL数据库(application.properties)可以参考这一篇 Spring guides-Accessing data with MySQL, 跟着这篇几乎也把四层结构基本都配置完了.

数据库的操作并不需要像SQL课上那样, 使劲敲命令行. 通常有可视化工具可以实现, 比如说Navicat, IDEA内的SQL可视化工具听说也不错.

Spring的四层结构

通常开发Spring, 会在Java下制作四层结构. 从上到下是Controller, Service&API, DAO, Entity.

Controller

Controller用于前端的调用, 给出一个地址和传入参数.

package com.autotboxdatasystem.demo.controller;

import com.autotboxdatasystem.demo.entity.UserEntity;
import com.autotboxdatasystem.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@Controller
@RequestMapping(path = "/User")
public class UserController {
    private final UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }

    // 添加用户
    @PostMapping(path = "/addUser")
    public @ResponseBody
    ResponseEntity<String> addUser(@RequestBody UserEntity userEntity) {
        String ans = userService.addUser(userEntity);
        if (!ans.equals("")) {
            return new ResponseEntity<>("Add User Failed. " + ans, HttpStatus.OK);
        }
        return new ResponseEntity<>("Succeed.", HttpStatus.OK);
    }
}

ServiceImpl & Service 或 Service & API

ServiceImpl用于Controller的逻辑处理, Service是ServiceImpl的接口, ServiceImpl是Service的应用. Controller调用的是Service(接口).

注: 增删改查的实现: 直接 save(entity) 就是加入; 如果entity内有Id, save为更新; 删除直接 delete(entity); 查找可用 findBy功能(Repository/DAO部分有讲, 请往下看).

ServiceImpl 示例

package com.autotboxdatasystem.demo.service.impl;

import com.autotboxdatasystem.demo.dao.*;
import com.autotboxdatasystem.demo.entity.*;
import com.autotboxdatasystem.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserServiceImpl implements UserService {
    private final UserDAO userDAO;

    @Autowired
    public UserServiceImpl(UserDAO userDAO) {
        this.userDAO = userDAO;
    }

    @Override
    public String addUser(UserEntity userEntity) {
        userDAO.save(userEntity);
        return "";
    }
}

Service 示例

package com.autotboxdatasystem.demo.service;

import com.autotboxdatasystem.demo.entity.UserEntity;
import org.springframework.data.domain.Page;

public interface UserService {
    String addUser(UserEntity userEntity);
}

Repository 或 DAO

Repository(DAO)是负责数据库相关的操作, 如果有Mapper(SQL), 则调用Mapper; 若无(使用JPA), 可以用Java语句实现数据库的增删改查.

继承 CrudRepository<User, Integer> 就可以调用增删改查, 如果要自己创建操作, 命名为 findByELEM 就行了(ELEM填属性名) 就会自动生成操作, 调用即可.

Repository示例

package com.autotboxdatasystem.demo.dao;

import com.autotboxdatasystem.demo.entity.UserEntity;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface UserDAO extends CrudRepository<User, Integer> {
    UserEntity findByUsername(String username);
}

Entity

Entity是实体类, 用于定义类属性和方法.

Entity 示例

package com.example.accessingdatamysql;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity // This tells Hibernate to make a table out of this class
public class User {
  @Id
  @GeneratedValue(strategy=GenerationType.AUTO)
  private Integer id;

  private String name;

  private String email;

  ...get & set
}

数据库相关:JPA与Hibernate

之前提到, Spring使用JPA可以不写SQL, 具体要怎么实现呢? 就是利用注解.

上一部分的内容其实已经出现了一些如: @Controller, @Autowired, @Entity, @Id 之类的注解. 这些注解的用处是在于辅助实现功能. 自动创建数据库表也需要用到这个功能.

数据表对应的就是Entity内的实体类. 只要在要建表的实体类上加入注解, 就能生成表(如果application.properties的是spring.jpa.hibernate.ddl-auto=update或create或create-drop).

比如我建立一个实体类UserEntity. 首先用@Entity标记为实体类自动建表, 再用@Id标记主键, @GeneratedValue(strategy = GenerationType.IDENTITY)表示@Id为自增. @Column表示属性类型, 设置属性类型, 是否为空, 默认值, 备注等信息.

还有个自动生成 get & set 的注解, 有兴趣可以玩玩看. 注解可参考 不發光的螢火蟲-JPA之Entity注解说明.

package com.autotboxdatasystem.demo.entity;

import javax.persistence.MappedSuperclass;
import javax.persistence.Id;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Column;

@Entity
public class UserEntity {
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Id
    @Column(nullable = false, columnDefinition = "int comment 'ID'")
    private Integer id;
    @Column(nullable = false, columnDefinition = "VARCHAR(20) comment '用户名'")
    private String username;
    @Column(nullable = false, columnDefinition = "VARCHAR(50) comment '密码'")
    private String password;
    @Column(columnDefinition = "VARCHAR(20) comment '邮箱'")
    private String email;
    @Column(columnDefinition = "VARCHAR(20) comment '电话'")
    private String phone;
    @Column(columnDefinition = "VARCHAR(20) comment '头像'")
    private String avatar;

    ...get & set

第一篇差不多就写这样了, Spring内容很多很杂, 查资料不太难. 选择很多, 一条路走不通就换一条路.

参考资料:

Join Newsletter
Get the latest news right in your inbox. We never spam!
DolorHunter
Written by DolorHunter
Developer & Independenet Blogger