我的第一个springboot

我的第一个springboot

一、开发工具

  1. java编译器: IntelliJ IDEA 社区版免费使用
  2. 数据库服务:MySQL 社区版免费使用
  3. 数据库管理:MySQL Workbench 社区版免费使用

二、项目构建

IntelliJ IDEA可以直接构建项目,这里采用高效的在线构建方式 spring-initializr

界面如下:

2021-06-09_221430

我将分四个区域简单描述一下如何使用spring-initializr:

  1. 项目管理工具、开发语言等

    • Project: 表示构建的工程的类型,即构建的工程所使用的项目管理工具,建议选择maven

    • Language: 表示构建的工程所使用的语言,这里选择java

    • Spring Boot: 表示使用的Spring Boot的版本,默认即可

  2. 项目基本信息

    • Group: Group id

    • Artifact: Artifact id

    • Name: 项目名称

    • Description: 项目描述

    • Package name: 包名称

    • Packaging: 打包类型

    • Java: JDK版本,推荐8.0

  3. 项目依赖,这些依赖信息在工程构建完成后,这些消息会出现在pom.xml中

    • Spring Web: Web框架
    • MyBatis Framework:一款优秀的持久层框架
    • MySQL Driver:mysql驱动
  4. 按钮组

    • GENERATECTRL: 导出构建文件

    • EXPLORECTRL : 预览构建文件

    • SPACESHARE: 分享构建链接

三、hello world

这个过程将用spring boot框架运行出第一个接口程序

  1. 使用IDE打开构建后的项目

    首次打开

  2. 修改配置文件,resource文件夹下application.properties(项目创建时自动生成这个文件的),为了语法简便,我们把application.properties改成application.yml,其编写内容如下:

    server:
      port: 8080  #tomcat端口
    
  3. 更新maven依赖,右侧打开maven工作区,点击刷新按钮即可

    maven

  4. 创建controller包,以及testController.java

    Controller

  5. 添加testController.java代码,以及相关注解,RequestMapping则为相应路由

    package com.zh.test.controller;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.BeanUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.util.StringUtils;
    import org.springframework.web.bind.annotation.*;
    import java.util.HashMap;
    import java.util.Map;
    
    @RestController
    @RequestMapping(value = "/test")
    public class testController {
    
        @RequestMapping(value = "/get")
        public String Get(){
            return "Hello world!";
        }
    }
    
  6. 选择testApplication,添加过滤数据库注解,springboot默认需要数据库

    @SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
    
  7. 选择testApplication,点击main函数旁边的运行按钮即可运行程序,下方如果出现端口号以及没有错误信息则表示正常。注意:数据库如果链接不上是不能运行的。

    run

    1. 进入浏览器,输入地址 http://127.0.0.1:8080/test/get 即可访问相关服务

    succcess

    1. 至此,一个不含数据库操作的接口已经构建完成。如果你不满足于此,请往下看。

四、进阶-完整项目

完整的结构会涉及到MVC设计模式以及三层架构,这里采用的是三层架构+控制器的方式

MVC设计模式: 视图View、模型Model、控制器Controller

三层架构分为: 表现层(UI)、业务逻辑层(BLL)、数据访问层(DAL),再加上实体类库(Model)

1. 创建完整结构

在Application同级目录创建如下包:

  • comm: 公共类

  • controller: 控制器

  • domain: 实体类库

  • mapper: 数据访问层

  • service: 业务逻辑层-接口

  • serviceImpl: 业务逻辑层-接口实现

2.创建数据库表

以管理员信息为例,建表语句如下:

create table if not exists test.admins
(
	Guid varchar(50) charset utf8 not null
		primary key,
	NickName varchar(50) not null comment '登录名称',
	Name varchar(50) not null comment '用户名',
	Password varchar(20) not null comment '密码',
	Remark varchar(200) null comment '备注'
)
comment '管理员';

3.实体类库

示例:domain > Admins.java

package com.zh.test.domain;

import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Date;

/**
 * 管理员
 * zh
 * 2021-06-08
 */
public class Admins {

    private String guid;
    private String nickname;
    private String name;
    private String password;
    private String remark;

    public String getGuid() {
        return guid;
    }
    public void setGuid(String guid) {
        this.guid = guid;
    }
    public String getNickname() {
        return nickname;
    }
    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getRemark() {
        return remark;
    }
    public void setRemark(String remark) {
        this.remark = remark;
    }
}

4.数据访问层 mapper

示例:mapper > AdminsMapper.java

package com.zh.test.mapper;

import com.zh.test.domain.Admins;
import java.util.List;
import java.util.Map;

/**
 * AdminsMapper
 * zh
 * 2021-06-09
 */
public interface AdminsMapper {
    /**
     * 全字段插入
     */
    int insert(Admins record);

    /**
     * 对非空字段插入
     */
    int insertSelective(Admins record);

    /**
     * 对非空字段更新
     */
    int updateByPrimaryKeySelective(Admins record);

    /**
     * 全字段更新
     */
    int updateByPrimaryKey(Admins record);

    /**
     * 通过主键字段删除
     */
    int deleteByPrimaryKey(String Guid);

    /**
     * 通过主键字段查询
     */
    Admins selectByPrimaryKey(String Guid);

    /**
     * 获取序列值
     */
    Long getNextVal();

    /**
     * 获取数据
     */
    List<Admins> selectAllByMap(Map map);
}

5.业务逻辑层-接口

示例:service > IAdminsService.java

package com.zh.test.service;

import com.zh.test.domain.Admins;
import com.github.pagehelper.PageInfo;
import java.util.Map;
import java.util.List;

/**
 * AdminsService
 * zh
 * 2021-06-08
 */
public interface IAdminsService {

    /**
     * 新增
     */
    void add(Admins record) throws Exception;

    /**
     * 修改
     */
    void update(Admins record) throws Exception;

    /**
     * 删除
     */
    void delete(String Guid) throws Exception;

    /**
     * 获取分页数据
     */
    PageInfo getList(Map map) throws Exception;

    /**
     * 获取序列值
     */
    Long getNextVal() throws Exception;

    /**
     * 获取列表数据
     */
    List<Admins> selectAll(Map map) throws Exception;

    /**
     * 获取实体
     */
    Admins getModel(String Guid) throws Exception;

}

6.业务逻辑层-接口实现

示例:serviceImpl > AdminsServiceImpl.java

package com.zh.test.serviceImpl;

import com.zh.test.mapper.AdminsMapper;
import com.zh.test.domain.Admins;
import com.zh.test.service.IAdminsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import java.util.List;
import java.util.Map;

/**
 * AdminsServiceImpl
 * zh
 * 2021-06-08
 */
@Service
public class AdminsServiceImpl implements IAdminsService {

    @Autowired
    private AdminsMapper adminsMapper;


    /**
     * 获取序列值
     */
    @Override
    public Long getNextVal() throws Exception {
        return adminsMapper.getNextVal();
    }

    /**
     * 新增
     */
    @Override
    public void add(Admins record) throws Exception {
        adminsMapper.insertSelective(record);
    }

    /**
     * 修改
     */
    @Override
    public void update(Admins record) throws Exception {
        adminsMapper.updateByPrimaryKeySelective(record);
    }

    /**
     * 删除
     */
    @Override
    public void delete(String Guid) throws Exception {
        adminsMapper.deleteByPrimaryKey(Guid);
    }

    /**
     * 获取实体
     */
    @Override
    public Admins getModel(String Guid) throws Exception {
        return adminsMapper.selectByPrimaryKey(Guid);
    }

    /**
     * 获取列表
     */
    @Override
    public List<Admins> selectAll(Map map) throws Exception {
        return adminsMapper.selectAllByMap(map);
    }

    /**
     * 获取分页数据
     */
    @Override
    public PageInfo getList(Map map) throws Exception {
        int pageNum = 1;
        int pageSize = 10;
        if (!StringUtils.isEmpty(map.get("page"))) {
            pageNum = Integer.parseInt((String) map.get("page"));
        }
        if (!StringUtils.isEmpty(map.get("limit"))) {
            pageSize = Integer.parseInt((String) map.get("limit"));
        }
        PageHelper.startPage(pageNum, pageSize);
        List<Admins> list = adminsMapper.selectAllByMap(map);
        PageInfo pageInfo = new PageInfo(list);
        return pageInfo;
    }
}

7.控制器

示例:controller > testController.java

注意:相关参数的注解

package com.zh.test.controller;

import com.zh.test.comm.BusinessException;
import com.zh.test.comm.CommonEnum;
import com.zh.test.comm.Response;
import com.zh.test.domain.Admins;
import com.zh.test.service.IAdminsService;
import io.swagger.annotations.ApiImplicitParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.util.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.github.pagehelper.PageInfo;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.WebRequest;
import java.beans.PropertyEditorSupport;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping(value = "/test")
public class testController {

    @Autowired
    private IAdminsService adminsService;
    private static final Logger logger = LoggerFactory.getLogger(testController.class);

    @RequestMapping(value = "/get")
    public String Get(){
        return "Hello world!";
    }

    /**
     * 获取分页数据
     */
    @ApiOperation(value = "获取分页数据")
    @PostMapping("/getData")
    public Response list(@RequestParam Map map) throws Exception {
        PageInfo pageInfo = adminsService.getList(map);
        return new Response().success(pageInfo.getList(), pageInfo.getTotal());
    }

    /**
     * 获取实体
     */
    @ApiOperation(value = "获取实体")
    @PostMapping("/getOne")
    public Response getOne(@ApiParam(value = "Guid") @RequestParam("Guid") String Guid) throws Exception {
        return new Response().success(adminsService.getModel(Guid));
    }

    /**
     * 保存
     */
    @ApiOperation(value = "保存")
    @PostMapping(value = "/add",produces = "application/json;charset=UTF-8")
    public Response Save(@RequestBody Admins record) throws Exception {
        Admins insertRecord = new Admins();
        BeanUtils.copyProperties(record, insertRecord);
        adminsService.add(insertRecord);
        return new Response().success();
    }

    /**
     * 修改
     */
    @ApiOperation(value = "修改")
    @PostMapping(value = "/edit",produces = "application/json;charset=UTF-8")
    public Response Edit(@RequestBody  Admins record) throws Exception {
        Admins updateRecord = new Admins();
        BeanUtils.copyProperties(record, updateRecord);
        adminsService.update(updateRecord);
        return new Response().success();
    }

    /**
     * 删除
     */
    @ApiOperation(value = "删除")
    @PostMapping("/delete")
    public Response remove(@ApiParam(value = "Guid") @RequestParam("Guid") String Guid) throws Exception {
        adminsService.delete(Guid);
        return new Response().success();
    }
}

8.数据访问层 mapperXml

示例:mapperXml > Admins.xml

resources 文件夹下创建包 mapperXml,application.yml中配置xml依赖

mybatis:
  mapper-locations: classpath:mapperXml/*.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.zh.test.mapper.AdminsMapper">
    <resultMap id="BaseResultMap" type="com.zh.test.domain.Admins">
        <id column="Guid" property="guid" jdbcType="VARCHAR" />
        <result column="NickName" property="nickname" jdbcType="VARCHAR" />
        <result column="Name" property="name" jdbcType="VARCHAR" />
        <result column="Password" property="password" jdbcType="VARCHAR" />
        <result column="Remark" property="remark" jdbcType="VARCHAR" />
    </resultMap>

    <sql id="Base_Column_List">
        `Guid`,`NickName`,`Name`,`Password`,`Remark`
    </sql>
    <sql id="Base_Where">
        <if test="guid != null">(Guid like #{guid})and </if>
        <if test="nickname != null">(nickname like #{nickname})and </if>
        <if test="Name != null">(Name like #{Name})and </if>
        <if test="remark != null">(Remark like #{remark})and </if>
    </sql>

    <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.String">
        select
        <include refid="Base_Column_List"/>
        from admins
        where Guid = #{guid,jdbcType=VARCHAR}
    </select>

    <select id="getNextVal" resultType="java.lang.Long" useCache="false" flushCache="false">
        select SEQ_admins.nextval as id from dual
    </select>

    <select id="selectAllByMap" resultMap="BaseResultMap" parameterType="java.util.Map">
        select
        <include refid="Base_Column_List"/>
        from admins
        <trim prefix="WHERE" suffixOverrides="and|or">
            <include refid="Base_Where"/>
        </trim>
    </select>

    <delete id="deleteByPrimaryKey" parameterType="java.lang.String">
        delete
        from  admins
        where Guid = #{guid,jdbcType=VARCHAR}
    </delete>

    <insert id="insert" parameterType="com.zh.test.domain.Admins" >
        insert into admins ( `Guid`,`NickName`,`Name`,`Password`,`Remark` )
        values (#{guid,jdbcType=VARCHAR},#{nickname,jdbcType=VARCHAR},#{name,jdbcType=VARCHAR},#{password,jdbcType=VARCHAR},#{remark,jdbcType=VARCHAR} )
    </insert>

    <insert id="insertSelective" parameterType="com.zh.test.domain.Admins" >
        insert into admins
        <trim prefix="(" suffix=")" suffixOverrides="," >
            <if test="guid != null" >`Guid`,</if>
            <if test="nickname != null" >`NickName`,</if>
            <if test="name != null" >`Name`,</if>
            <if test="password != null" >`Password`,</if>
            <if test="remark != null" >`Remark`,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides="," >
            <if test="guid != null" >#{guid,jdbcType=VARCHAR},</if>
            <if test="nickname != null" >#{nickname,jdbcType=VARCHAR},</if>
            <if test="name != null" >#{name,jdbcType=VARCHAR},</if>
            <if test="password != null" >#{password,jdbcType=VARCHAR},</if>
            <if test="remark != null" >#{remark,jdbcType=VARCHAR},</if>
        </trim>
    </insert>

    <update id="updateByPrimaryKey" parameterType="com.zh.test.domain.Admins" >
        update admins set
        `NickName` = #{nickname,jdbcType=VARCHAR},
        `Name` = #{name,jdbcType=VARCHAR},
        `Password` = #{password,jdbcType=VARCHAR},
        `Remark` = #{remark,jdbcType=VARCHAR}
        where Guid = #{guid,jdbcType=VARCHAR}
    </update>

    <update id="updateByPrimaryKeySelective" parameterType="com.zh.test.domain.Admins" >
        update admins
        <set >
            <if test="nickname != null" > `NickName` = #{nickname,jdbcType=VARCHAR},</if>
            <if test="name != null" > `Name` = #{name,jdbcType=VARCHAR},</if>
            <if test="password != null" > `Password` = #{password,jdbcType=VARCHAR},</if>
            <if test="remark != null" > `Remark` = #{remark,jdbcType=VARCHAR},</if>
        </set>
        where Guid = #{guid,jdbcType=VARCHAR}
    </update>
</mapper>

9.公共类 comm

示例:comm > Response.java 接口统一返回对象

package com.zh.test.comm;

/**
 * 自定义统一返回对象
 */
public class Response {
    private boolean IsError;
    private String ErrorMsg;
    private int Code;
    private Object Data;
    private long DataCount;

    public Response success(){
        this.success(1,1);
        return this;
    }
    public Response success(Object obj){
        this.success(obj,1);
        return this;
    }
    public Response success(Object obj,long count){
        this.setIsError(false);
        this.setCode(1);
        this.setData(obj);
        this.setDataCount(count);
        return this;
    }
    public Response error(String obj){
        error(0,obj);
        return this;
    }
    public Response error(int code,String obj){
        this.setCode(code);
        this.setIsError(true);
        this.setErrorMsg(obj);
        return this;
    }
    public long getDataCount() {
        return DataCount;
    }
    public void setDataCount(long dataCount) {
        DataCount = dataCount;
    }
    public boolean getIsError() {
        return IsError;
    }
    public void setIsError(boolean isError) {
         IsError=isError;
    }
    public int getCode() {
        return Code;
    }
    public void setCode(int code) {
        Code = code;
    }
    public Object getData() {
        return Data;
    }
    public void setData(Object data) {
        Data = data;
    }
    public void setError(boolean error) {
        IsError = error;
    }
    public String getErrorMsg() {
        return ErrorMsg;
    }
    public void setErrorMsg(String errorMsg) {
        ErrorMsg = errorMsg;
    }
}

10.Show Time

至此一个完整的数据库增删改查基础功能完成。里面涉及到的一些其他具体操作,将在后续相关文章中发布。以上代码皆为真实案例拷贝,如遇无法运行请检查mave及相关配置,或继续阅读下面注意事项及参考链接。

贴上完整的项目结构:

full

五、尽请期待

后续可能将会发布以下相关文章,尽请期待:

  • 全局异常捕获

  • 动态application配置

  • mybatismybatis相关用法

  • 路由权限控制器

  • 前后端整体发布流程

  • 模型生成工具

六、注意事项

  1. pom.xml 相关配置
		<!--第三方依赖-->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.47</version>
		</dependency>
		<dependency>
			<groupId>com.github.pagehelper</groupId>
			<artifactId>pagehelper</artifactId>
			<version>4.1.4</version>
		</dependency>
		<!--引入swagger-->
		<dependency>
			<groupId>io.springfox</groupId>
			<artifactId>springfox-swagger2</artifactId>
			<version>2.7.0</version>
		</dependency>
		<dependency>
			<groupId>io.springfox</groupId>
			<artifactId>springfox-swagger-ui</artifactId>
			<version>2.7.0</version>
		</dependency>
  1. 对象参数无法传递

    注意相关注解,对象参数需要相应注解才能识别:@RequestBody

  2. 无法启动

    • 请检查数据库连接:必须要正确
    • 请检查端口占用情况
  3. 过滤数据库注解

    @SpringBootApplication(exclude = DataSourceAutoConfiguration.class)

七、参考链接

授人以鱼不如授人以渔

https://blog.csdn.net/u014453898/article/details/84659349

https://blog.csdn.net/lihua5419/article/details/81536629

https://www.cnblogs.com/telwanggs/p/9459685.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值