IDEA2019版本创建Spring boot项目:搭建纯Java进程服务,去掉web依赖

1.前言

本文主要介绍基于Springboot搭建和web无关的纯Java进程服务,提供mybatis、日志、单元测试等一系列的集成方法,为初学者提供完整集成方案。

2.使用Spring Initializer【官方推荐】搭建环境

2.1创建项目:按照图中的步骤进行搭建,建议使用IDEA2019版,非常好用并且炫。

在这里插入图片描述
File->New->Project,进行新建项目:
在这里插入图片描述
选择“Spring Initializer”,java的版本号尽量用1.8版本,Default选项打钩,点击Next
在这里插入图片描述
组织名称(一般就是项目的包名前缀,这个根据具体公司自己修改)和工程名填写后,点击Next
在这里插入图片描述
这一步比较重要,左边默认选择的是“developer Tools”开发工具,右边的三相,选中前两项,如图所示,图中介绍了两个工具的作用。
如果是web开发,记着再选择左边的“web”,然后在右侧选择Spring web选项即可,这样idea会我们引入默认的web相关启动器配置,不是web开发的人员此处可以忽略
在这里插入图片描述
点击FInish完成项目创建,初始创建时,maven需要下载相关依赖,因此较慢,请耐心等待。

2.2默认目录介绍

在这里插入图片描述
pom默认文件部分代码: 在本周最后附上全部文件代码

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

从默认生成的pom文件我们可以看出:为我们默认生成了spring-boot-starter、spring-boot-devtools、lombok、spring-boot-starter-test这四个启动器及插件
注:测试代码一定要放在测试目录,养成良好的习惯。

3.修改pom文件,引入框架用到的工具包依赖

常用的工具类引入

guava:这个工具包非常的强大,必须用。
fastjson:阿里巴巴的json处理工具,非常快速,也必须用。

在pom文件中增加如下代码

 <!--集成工具库 start-->
  <dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
      <version>${guava.version}</version>
  </dependency>
  <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>${fastjson.version}</version>
  </dependency>
<!--集成工具库 end-->

4.介绍pom文件常用的启动器介绍

这一章节,在我另一篇文章有详细介绍,请查阅。https://blog.csdn.net/houpeibin2012/article/details/104309150

5.集成mybatis及mybatis-plus

用到mybatis必然要用到他的增加软件mybatis-plus,这一章节详细介绍Springboot怎么集成这两种框架。

5.1 pom文件增加对mybatis及mybatis-plus的集成

<!--集成mybatis start-->
<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-jdbc</artifactId>
 </dependency>
 <dependency>
     <groupId>mysql</groupId>
     <artifactId>mysql-connector-java</artifactId>
 </dependency>
 <dependency>
     <groupId>org.mybatis.spring.boot</groupId>
     <artifactId>mybatis-spring-boot-starter</artifactId>
 </dependency>
 <!-- druid 数据库连接池 -->
 <dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>druid-spring-boot-starter</artifactId>
 </dependency>
 <!-- mybatis plus -->
 <dependency>
     <groupId>com.baomidou</groupId>
     <artifactId>mybatis-plus-boot-starter</artifactId>
     <version>3.1.0</version>
 </dependency>
 <!--集成mybatis end-->

从配置文件可以看出,我们使用了druid 数据库连接池,这是阿里巴巴提供的,内置web监控界面,可以监控数据库访问情况及语句执行信息。

5.2 配置文件增加mybatis及mybatis-plus相关参数配置

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
    driver-class-name: com.mysql.jdbc.Driver

mybatis:
  mapper-locations: classpath:mapping/*Mapper.xml
  type-aliases-package: com.ieslab.powergrid.entity
  
mybatis-plus:
  mapper-locations: classpath:mapper/*.xml
  global-config:
    # 关闭MP3.0自带的banner
    banner: false
    db-config:
      # 默认数据库表下划线命名
      table-underline: true

配置文件中的用户名和密码、数据库名等需要根据实际情况而设置;

5.3 增加分页插件配置类

新建MybatisPlusConfig.java类

package com.ieslab.powergrid.demosvr.config;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

//实现分页插件
@EnableTransactionManagement(proxyTargetClass = true)
@Configuration
@MapperScan("mapper")
public class MybatisPlusConfig {
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
}

这个类主要就是让分页插件功能生效。
这样mybatis和mybatis-plus就集成完毕了,后续会编写代码进行测试

6.集成日志框架,简化日志编码

6.1 pom文件增加日志相关依赖

<!-- set/get方法免写,需要安装idea的插件 -->
 <dependency>
     <groupId>org.projectlombok</groupId>
     <artifactId>lombok</artifactId>
     <optional>true</optional>
 </dependency>

6.2 使用注解进行日志使用

在测试目录创建测试类DemosvrApplicationTests.java,代码如下:

package com.ieslab.powergrid.demosvr;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
@Slf4j
class DemosvrApplicationTests {
    @Test
    void contextLoads() {
        log.info("contextLoads is running");
    }
}

代码中在类是前面添加:@Slf4j 注解后,就可以在本类中直接用log.info 进行打印日志。

7.demo实例编写

7.1 编写mapper接口及实现文件

7.1.1 首先创建Person.java类:

package com.ieslab.powergrid.demosvr.entity;

import lombok.Data;
import org.springframework.stereotype.Component;

@Data
public class Person {
    int id;
    String lastName;
    String firstName;
    String address ;
    String city;

    public Person() {
    }

    public Person(String lastName, String firstName, String address, String city) {
        this.lastName = lastName;
        this.firstName = firstName;
        this.address = address;
        this.city = city;
    }

    public int getId() {
        return id;
    }

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

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", lastName='" + lastName + '\'' +
                ", firstName='" + firstName + '\'' +
                ", address='" + address + '\'' +
                ", city='" + city + '\'' +
                '}';
    }
}

7.1.2 编写PersonMapper.java接口类:

package com.ieslab.powergrid.demosvr.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ieslab.powergrid.demosvr.entity.Person;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;
import java.util.Map;

@Mapper
public interface PersonMapper extends BaseMapper<Person> {
    //根据过滤条件获取用户
    List<Person> getPersonByFilter(Map<String, String> param);
}

7.1.3 在resources目录下创建mapper目录,并在此目录下创建PersonMapper.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.ieslab.powergrid.demosvr.mapper.PersonMapper">

	<select id="getPersonByFilter" resultType="com.ieslab.powergrid.demosvr.entity.Person">
		select  * from person
		<where>
			<if test="id != null">
				id=#{id}
			</if>
			<if test="name != null and name != ''">
				and last_name like CONCAT('%','${name}','%' )
			</if>
		</where>
	</select>


</mapper>

关于mapper文件的写法,有几个重点需要注意:

  1. namespace=“com.ieslab.powergrid.demosvr.mapper.PersonMapper” 这是一定要写对应的接口类
  2. resultType=“com.ieslab.powergrid.demosvr.entity.Person” 这是返回的数据类型,一定要正确,还有别的写法,可以查阅相关资料学习。
  3. 对于sql语句,尽量要用标签的方法编写,比如: 标签,ognl的写法一定不能缺少。

7.1.4 创建数据库、表

mysql数据库的安装,请查阅:https://blog.csdn.net/houpeibin2012/article/details/104224168

创建数据库:springboot
创建person表,建表语句如下:

建表语句:
CREATE TABLE Person
(
	id int,
	Last_Name varchar(255),
	First_Name varchar(255),
	Address varchar(255),
	City varchar(255)
)

注意表字段和person类的变量要对应,java实体类中采取驼峰方式进行命名时,数据要用下划线方式进行分开,比如:java类中lastName 变量对应数据库表中last_name的名称。
这样数据库表、数据库层的代码已经编写完毕。

7.2 编写service类

编写业务层代码,创建PersonService.java类:

package com.ieslab.powergrid.demosvr.service;

import com.ieslab.powergrid.demosvr.entity.Person;
import com.ieslab.powergrid.demosvr.mapper.PersonMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;

/** <p>Title: PersonService </p>
 * <p>Description: 用户业务类,测试demo使用</p>
 *
 * @author houpeibin
 * @date 2020-2-20 下午7:15:30
 * @version V1.0
 */
@Service
public class PersonService {
    @Autowired
    PersonMapper personMapper;

    /**
     * 获取所有用户
     * @return
     */
    public List<Person> getPersons(){
        return personMapper.selectList(null);
    }

    /**
     * 插入用户
     * @param person 用户信息类
     * @return 插入几条数据
     */
    public int insertPersons(Person person){
        return personMapper.insert(person);
    }
}

8.集成Junit单元测试

8.1 编写测试代码

在PersonService.java类上点击右键,选择Generate,再选择Test…
在这里插入图片描述
弹出框中的测试类,一般不用改名,他就是service类加了后缀Test,方便找。
开发这个测试类,编写如下代码:

package com.ieslab.powergrid.demosvr.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ieslab.powergrid.demosvr.entity.Person;
import com.ieslab.powergrid.demosvr.mapper.PersonMapper;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/** <p>Title: PersonServiceTest </p>
 * <p>Description: PersonService测试类</p>
 *
 * @author houpeibin
 * @date 2020-2-20 下午7:15:30
 * @version V1.0
 */
@SpringBootTest
@Slf4j
class PersonServiceTest {
    @Autowired
    PersonService personService;
    @Autowired
    PersonMapper personMapper;

    /**
     * 插入用户
     */
    @Test
    void insertPersons(){
        for (int i=0;i<10;++i){
            Person person = new Person();
            person.setId(i);
            person.setFirstName("zhang");
            person.setLastName(""+i);
            person.setCity("jinan");
            person.setAddress("huayang");
            log.info("insert person:" + personService.insertPersons(person));
        }
    }

    /**
     * 根据id获取用户
     */
    @Test
    void getPersonsById(){
        Map<String, String> mapParam = new HashMap<>();
        mapParam.put("id","1");
        List<Person> persons = personMapper.getPersonByFilter(mapParam);
        log.info(persons.toString());
    }

    /**
     * 根据名称模糊查询
     */
    @Test
    void getPersonsByName(){
        Map<String, String> mapParam = new HashMap<>();
        mapParam.put("name","3");
        List<Person> persons = personMapper.getPersonByFilter(mapParam);
        log.info(persons.toString());
    }

    /**
     * 分页查询测试
     */
    @Test
    void getPersonsPage(){
        IPage<Person> page = new Page<Person>(0,5);
        IPage<Map<String, Object>> pageData = personMapper.selectMapsPage(page,null);
        List list = pageData.getRecords();
        for (Object obj:list){
            System.out.println(obj.toString());
        }
    }
}

上面写了四个测试方法,一个是插入10条数据,一个是按照id查询,一个是按照name模糊查询,最后一个是分页查询,下面我们来运行测试用例。

8.2 使用单元测试进行测试

在这里插入图片描述
查看执行结果:
在这里插入图片描述
用类似的方法,去执行其他方法进行测试。
怎么样,这样测试是不是很方便,Springboot集成mybatis也就成功了,简单吧,后续你只要好好学习sql的写法就可以了。

如果测试出现问题,请查看这篇文章
https://blog.csdn.net/houpeibin2012/article/details/104382360

9.总结

本文由于是去掉tomcat的纯java进程,因此,主类启动一次之后就会退掉,因此需要在主类上添加如下代码:

package com.ieslab.powergrid.demosvr;

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

@SpringBootApplication
public class DemosvrApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemosvrApplication.class, args);

        //保持进程不退出
        DemosvrApplication DemosvrApplication = new DemosvrApplication();
        synchronized (DemosvrApplication) {
            try {
                DemosvrApplication.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

这样运行此程序就不会退出了。

10.启动一个线程的实例

因为此程序不是web程序,因此没有针对前端的API层。但是线程和定时任务必不可少,不然,此程序还能干什么呢?下面介绍一下线程池的配置及如何在springboot启动之后去运行程序。

10.1 配置线程池

package com.ieslab.powergrid.demosvr.thread;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;

/** <p>Title: PersonService </p>
 * <p>Description: 线程池配置</p>
 *
 * @author houpeibin
 * @date 2020-2-20 下午7:15:30
 * @version V1.0
 */
@Configuration
@EnableAsync  // 启用异步任务
public class AsyncConfiguration {

    // 声明一个线程池(并指定线程池的名字)
    @Bean("taskExecutor")
    public Executor asyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //核心线程数5:线程池创建时候初始化的线程数
        executor.setCorePoolSize(5);
        //最大线程数5:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
        executor.setMaxPoolSize(5);
        //缓冲队列500:用来缓冲执行任务的队列
        executor.setQueueCapacity(500);
        //允许线程的空闲时间60秒:当超过了核心线程出之外的线程在空闲时间到达之后会被销毁
        executor.setKeepAliveSeconds(60);
        //线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池
        executor.setThreadNamePrefix("DailyAsync-");
        executor.initialize();
        return executor;
    }
}

10.2 编写线程类

package com.ieslab.powergrid.demosvr.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ieslab.powergrid.demosvr.entity.Person;
import com.ieslab.powergrid.demosvr.mapper.PersonMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class ThreadServiceDemo {
        @Autowired
        private PersonMapper personMapper;
        public static boolean runFlag = false;

        // 这里进行标注为异步任务,在执行此方法的时候,会单独开启线程来执行(并指定线程池的名字)
        @Async("taskExecutor")
        public void findPersonTest() throws InterruptedException {
            while (runFlag){
                log.info("访问数据库开始");
                IPage<Person> page = new Page<Person>(0,5);
                IPage<Map<String, Object>> pageData = personMapper.selectMapsPage(page,null);
                List list = pageData.getRecords();
                for (Object obj:list){
                    log.info(obj.toString());
                }
                log.info("访问数据库结束");

                //线程等待,在接收数据时,经常使用,此处我们就直接访问数据进行测试
                try {
                    Thread.sleep(5*1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }
    }


注意文中的注释:// 这里进行标注为异步任务,在执行此方法的时候,会单独开启线程来执行(并指定线程池的名字)。说明运行此方法时,会启动一个程序进行运行。

10.3 在springboot启动之后启动线程

package com.ieslab.powergrid.demosvr.thread;

import com.ieslab.powergrid.demosvr.service.ThreadServiceDemo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class ApplicationRunnerImpl implements ApplicationRunner {
    @Autowired
    ThreadServiceDemo threadServiceDemo;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        log.info("通过实现ApplicationRunner接口,在spring boot项目启动后打印参数");
        //可以在这里启动你的业务线程
        if(!ThreadServiceDemo.runFlag){
            ThreadServiceDemo.runFlag = true;
            threadServiceDemo.findPersonTest();
        }

    }
}

在此类,调用刚刚定义的多线程方法即可,实现多线程调用,此处我们用一个标志位来控制,本线程只启动一次,并且会循环执行。此种场景比较适用于循环接收数据的情景。

这样线程集成就已经完成了,可以运行主类进行测试一下。

11.后续

到此,一个简单的基于Springboot的java后台开发框架就搭建完毕了,是不是很简单。
入门简单,精通难,后续开发你还会遇到如下问题,比如:

  1. 集成多线程
  2. 集成定时任务
  3. 集成kafka
  4. 集成mongodb
  5. 集成dubbo

等等等等的知识点,后续会有专门的文章进行描述。

12. 附录

pom文件:

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.ieslab.powergrid</groupId>
    <artifactId>demosvr</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demosvr</name>
    <description>Demo project for Spring Boot</description>

    <properties>
    <java.version>1.8</java.version>
    <mybatisplus.version>3.1.0</mybatisplus.version>
    <druid.version>1.1.13</druid.version>
    <mybatis.version>2.1.1</mybatis.version>
    <fastjson.version>1.2.47</fastjson.version>
    <guava.version>28.2-jre</guava.version>
</properties>

    <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>-->

        <!--集成mybatis start-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>${mybatis.version}</version>
        </dependency>
        <!-- druid 数据库连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>${druid.version}</version>
        </dependency>
        <!-- mybatis plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatisplus.version}</version>
        </dependency>
        <!--集成mybatis end-->

        <!--集成工具库 start-->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>${guava.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>${fastjson.version}</version>
        </dependency>
        <!--集成工具库 end-->

        <!-- 热部署时使用 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <!-- set/get方法免写,需要安装idea的插件 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!--单元测试-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

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

</project>

发布了21 篇原创文章 · 获赞 4 · 访问量 401

猜你喜欢

转载自blog.csdn.net/houpeibin2012/article/details/104422392