美文网首页
iOS Developer的全栈之路 - 运行SpringBoo

iOS Developer的全栈之路 - 运行SpringBoo

作者: 西西的一天 | 来源:发表于2019-11-11 23:23 被阅读0次

在这一章里,我们基于第一章中的项目,让SpringBoot跑起来。

添加依赖

既然这是一个SpringBoot的项目,首先需要安装SpringBoot的依赖。在根项目的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">
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
        <relativePath />
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.iossocket</groupId>
    <artifactId>foodie-dev</artifactId>
    <version>1.0-SNAPSHOT</version>

    <modules>
        <module>foodie-dev-common</module>
        <module>foodie-dev-pojo</module>
        <module>foodie-dev-mapper</module>
        <module>foodie-dev-service</module>
        <module>foodie-dev-api</module>
    </modules>

    <packaging>pom</packaging>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

</project>
  1. <properties>下添加了Encoding的方式,以及java的版本
  2. <parent>声明这个项目是基于springboot的,并指明了SpringBoot的版本
  3. <dependencies>声明了项目的基础依赖
    3.1 spring-boot-starter-web web依赖
    3.2 spring-boot-configuration-processor 提供对于其他配置文件的解析能力,默认情况下只支持yml文件,添加后可以支持xml等。

在这些依赖中都没有声明版本号,这些依赖的版本号都由<parent>标签下的spring-boot-starter-parent进行统一管理。如何查看这些被管理的版本号呢?进入org.springframework.boot的定义,再进入spring-boot-dependencies的定义即可查阅。

入口main

在api的module下创建两个类Application和HelloController,分别位于package:com.xxxx和com.xxxx.controller下

Application.java,main函数作为App的启动入口

package com.iossocket;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

HelloController.java,添加一个测试的url,路由为/hello

package com.iossocket.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello() {
        return "Hello world";
    }
}

mvn install后即可运行main函数,又有SpringBoot会默认内嵌一个Tomcat服务器,所有运行后可以直接通过浏览器打开localhost:8080/hello查看运行效果。
SpringBoot通过注解摆脱了繁琐的配置,这里有几个基础的注解@SpringBootApplication@RestController@GetMapping("/hello"),它们的作用是什么呢?建议动手撸一个简易版的SpringBoot,这里有一个课程 手写SpringMVC,剑指优秀开源框架灵魂,这里在附上我的项目我的项目代码仅供参考。

连接数据库

这里使用了mybatis作为orm框架,现在根项目的pom文件中添加mybatis以及MySQL的依赖:

<?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">
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
    ...
    <dependencies>
        ...
        <!-- mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.18</version>
        </dependency>
        <!-- mybatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.0</version>
        </dependency>
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
            <version>2.1.5</version>
        </dependency>
    </dependencies>
</project>

关于mybatis-generator的使用方式可参考这里连接,并将生成好的UsersUsersMapperMyMapperUsersMapper.xml拷贝至项目的相应目录。

  1. 首先先来看一下MyMapper所继承的父类,如
interface MyMapper<T> extends Mapper<T>,MySqlMapper<T>

这里有两个父类,Mapper<T>与MySqlMapper<T>,我们可以打开MySqlMapper<T>看一下:

interface MySqlMapper<T> extends InsertListMapper<T>,InsertUseGeneratedKeysMapper<T>{}

这里面又继承了了两个mapper,从类名上可以看得出来,是用于操作数据库的,这两个类里又分别包含了如下方法,简单归类一下:

insertList(list):数据批量插入,主键须自增
insertUseGeneratedKeys(record):插入表数据,主键须自增

很明显,在传统JavaWeb开发,这两个方法使用是没有问题的,但是我们的数据库表主键设计肯定是全局唯一的,所以不可能使用自增长id(如何设计全局唯一分布式主键,在后续章节里有具体的讲解),所以这两个方法在我们开发过程中是不会使用的,这一点需要注意噢~!

  1. 随后再来看一下Mapper<T>中所继承的父类,如下:
interface Mapper<T> extends BaseMapper<T>,ExampleMapper<T>,RowBoundsMapper<T>,

分别来看一下各个父类中的方法有些啥?
BaseMapper<T>

方法 说明
单元格 单元格 单元格
BaseSelectMapper T selectOne(T record) 根据实体类中的属性查询表数据,返回单个实体
List select(T record) 根据实体类中的属性查询表数据,返回符合条件的list
List selectAll() 返回该表所有记录
int selectCount(T record) 根据条件查询记录数
T selectByPrimaryKey(Object key) 根据主键查询单挑记录
boolean existsWithPrimaryKey(Object key) 查询主键是否存在,返回true或false
BaseInsertMapper int insert(T record) 插入一条记录,属性为空也会保存
int insertSelective(T record) 插入一条记录,属性为空不保存,会使用默认值
BaseUpdateMapper int updateByPrimaryKey(T record) 根据实体类更新数据库,属性有null会覆盖原记录
int updateByPrimaryKeySelective(T record) 根据实体类更新数据库,属性有null改属性会忽略
BaseDeleteMapper int delete(T record) 根据实体类中属性多条件删除记录
int deleteByPrimaryKey(Object key) 根据主键删除记录

ExampleMapper<T>,Example类是用于提供给用户实现自定义条件的,也就是where条件,主要方法见如下表格:

方法 操作
SelectByExampleMapper List selectByExample(Object example) 根据条件查询记录list
SelectOneByExampleMapper T selectOneByExample(Object example) 根据条件查询单条记录
SelectCountByExampleMapper int selectCountByExample(Object example) 根据条件查询记录数
DeleteByExampleMapper int deleteByExample(Object example) 根据条件删除记录
UpdateByExampleMapper int updateByExample(T record, @Param(“example”) Object example); 根据条件更新数据,null会覆盖原数据
UpdateByExampleSelectiveMapper int updateByExampleSelective(T record, Object example); 根据条件更新数据,null会忽略

RowBoundsMapper<T>,这个是用于做分页的,我们在后续阶段中会使用page-helper这个组件来替代这个分页实现。

小结

通用mapper所提供的CRUD方法对单表操作,大大提高开发效率,当然复杂的多表操作还是需要在mapper.xml中自己去编写sql代码实现。

小试牛刀

我们来让SpringBoot连接上数据库跑起来,首先我们先创建数据库及users表,创建数据库的方式,我们采用Navicat,连接上本地数据库,新建数据库foodie-shop-dev,之后在左侧导航栏双击数据库,选中当前新建的数据库。

在顶级菜单中新建New Query,写一个创建表的SQL,并执行。

DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
  `id` varchar(64) NOT NULL COMMENT '主键id 用户id',
  `username` varchar(32) NOT NULL COMMENT '用户名 用户名',
  `password` varchar(64) NOT NULL COMMENT '密码 密码',
  `nick_name` varchar(32) DEFAULT NULL COMMENT '昵称 昵称',
  `real_name` varchar(128) DEFAULT NULL COMMENT '真实姓名',
  `avatar` varchar(1024) NOT NULL COMMENT '头像',
  `mobile` varchar(32) DEFAULT NULL COMMENT '手机号 手机号',
  `email` varchar(32) DEFAULT NULL COMMENT '邮箱地址 邮箱地址',
  `gender` int(11) DEFAULT NULL COMMENT '性别 性别 1:男  0:女  2:保密',
  `birthday` date DEFAULT NULL COMMENT '生日 生日',
  `created_time` datetime NOT NULL COMMENT '创建时间 创建时间',
  `updated_time` datetime NOT NULL COMMENT '更新时间 更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

接下来为该表添加一条数据,执行

INSERT INTO `users` VALUES ('1908017YR51G1XWH', 'iossocket', 'Qpf0SxOVUjUkWySXOZ16kw==', 'imooc', NULL, 'http://122.152.205.72:88/group1/M00/00/05/CpoxxFw_8_qAIlFXAAAcIhVPdSg994.png', NULL, NULL, 2, '1900-01-01', '2019-08-14 23:44:30', '2019-08-14 23:44:30');

使用mybatis-generator,生成相应的entity, mapper以及配置文件,拷贝至相应目录,别忘了拷贝MyMapper哟。

之后就可以编写相应Service层的代码了:

package com.iossocket.service;

import com.iossocket.bo.LoginRequest;
import com.iossocket.bo.RegisterRequest;
import com.iossocket.pojo.Users;

public interface PassportService {
    Boolean isUserExisting(String username);
}
package com.iossocket.service.impl;

import com.iossocket.mapper.UsersMapper;
import com.iossocket.pojo.Users;
import com.iossocket.service.PassportService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

@Service
public class PassportServiceImpl implements PassportService {
    @Autowired
    private UsersMapper mapper;

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public Boolean isUserExisting(String username) {
        Example userExample = new Example(Users.class);
        Example.Criteria criteria = userExample.createCriteria();
        criteria.andEqualTo("username", username);

        Users users = mapper.selectOneByExample(userExample);

        return !(users == null);
    }

我们这里先写一个最简单的查看用户名是否可用的方法。有了service的支持,可用开始构建第一个endpoint啦,在controller层创建一个PassportController:

@RestController
@RequestMapping("/user")
@Slf4j
public class PassportController {

    @Autowired
    private PassportService passportService;

    @GetMapping("/isUserExisting")
    public JSONResult isUserExisting(@RequestParam(defaultValue = "") String username) {
        if (StringUtils.isBlank(username)) {
            return JSONResult.error("username can not be empty");
        }
        Boolean isExisting = passportService.isUserExisting(username);
        return JSONResult.success(isExisting);
    }
}

这里涉及到几个工具类,可用查阅源码

运行项目,便通过postman查看结果了。

相关文章

网友评论

      本文标题:iOS Developer的全栈之路 - 运行SpringBoo

      本文链接:https://www.haomeiwen.com/subject/sgvxictx.html