一、打开IDEA,创建SpringBoot项目
点击 new project ,如果是已进入项目,在左上角选择。
填写项目相关信息
选择你需要的依赖,点击下一步。
选择项目的存储路径,点击Finish
等待资源下载完成即可,随后启动项目,查看是否成功创建项目。
如果项目没有报错,就是启动成功了。
二、编写Controller,实现简单的服务。
在浏览器地址栏输入:
因为没做其他的配置,默认是 : ip地址+端口号+请求映射地址访问
三、Spring Boot集成MySQL
如果之前没有勾选依赖,可以手动添加依赖
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
修改配置文件:
这里以yml文件配置,实际开发中会有N个配置文件。
配置文件位置可以自定义,但是记得修改配置的路径。
application.yml
# 服务启动端口
server:
port: 8080
servlet:
#Context path of the application. 应用的上下文路径,也可以称为项目路径,是构成url地址的一部分。
context-path: /api
# 一般项目中会有多个配置文件,用于选择加载哪个配置文件
spring:
profiles:
active: dev
# mybatis
mybatis:
mapperLocations: classpath:mybatis/mapper/*.xml
config-location: classpath:mybatis/mybatis-config.xml
typeAliasesPackage: com.lzw.springbootdemo.entity
# 日志输出配置
# resources classpath
logging:
config: classpath:logback-spring.xml
level:
com.lzw.springbootdemo.mapper: debug
application-dev.yml
# 配置数据库信息
spring:
datasource:
url: jdbc:mysql://localhost:3306/mybatis_test_db?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&allowMultiQueries=true&serverTimezone=GMT%2B8
username: root
password: root123
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--以下已经在application.yml中配置过了-->
<!--<typeAliases>-->
<!--<package name="com.example.domain"/>-->
<!--</typeAliases>-->
<!--<mappers>-->
<!--<mapper resource="mapper/UserMapper.xml"/>-->
<!--</mappers>-->
</configuration>
logback-spring.xml
记得修改路径
<property name="log.path" value="G:/logs/spring-boot-demo-logs"/>G:/logs/spring-boot-demo-logs 这里一定是 “/” 不能是"\",识别不了就默认存在项目目录中。
<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
<!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true -->
<!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<configuration scan="true" scanPeriod="10 seconds">
<contextName>logback</contextName>
<!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 -->
<!-- <property name="log.path" value="${user.dir}/logs" />-->
<property name="log.path" value="G:/logs/spring-boot-demo-logs"/>
<!-- 彩色日志 -->
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
<conversionRule conversionWord="wex"
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
<conversionRule conversionWord="wEx"
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!--输出到控制台-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!--输出到文件-->
<!-- 时间滚动输出 level为 DEBUG 日志 -->
<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/log_debug.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志归档 -->
<fileNamePattern>${log.path}/debug/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录debug级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>debug</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 INFO 日志 -->
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/log_info.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天日志归档路径以及格式 -->
<fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录info级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>info</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 WARN 日志 -->
<appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/log_warn.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录warn级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>warn</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 ERROR 日志 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/log_error.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录ERROR级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!--
<logger>用来设置某一个包或者具体的某一个类的日志打印级别、
以及指定<appender>。<logger>仅有一个name属性,
一个可选的level和一个可选的addtivity属性。
name:用来指定受此logger约束的某一个包或者具体的某一个类。
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。
如果未设置此属性,那么当前logger将会继承上级的级别。
addtivity:是否向上级logger传递打印信息。默认是true。
-->
<!--<logger name="org.springframework.web" level="info"/>-->
<!--<logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="INFO"/>-->
<!--开发环境:打印控制台-->
<springProfile name="dev">
<logger name="com.yidu" level="debug"/>
</springProfile>
<root level="info">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="DEBUG_FILE"/>
<appender-ref ref="INFO_FILE"/>
<appender-ref ref="WARN_FILE"/>
<appender-ref ref="ERROR_FILE"/>
</root>
<!--生产环境:输出到文件-->
<!--<springProfile name="pro">-->
<!--<root level="info">-->
<!--<appender-ref ref="CONSOLE" />-->
<!--<appender-ref ref="DEBUG_FILE" />-->
<!--<appender-ref ref="INFO_FILE" />-->
<!--<appender-ref ref="ERROR_FILE" />-->
<!--<appender-ref ref="WARN_FILE" />-->
<!--</root>-->
<!--</springProfile>-->
</configuration>
创建数据库、表,插入数据
CREATE TABLE `employee` (
`empid` INT NOT NULL AUTO_INCREMENT,
`ename` VARCHAR ( 255 ) NOT NULL,
`job` VARCHAR ( 255 ) NOT NULL,
`mgr` INT DEFAULT NULL,
`hiredate` date DEFAULT NULL,
`sal` DOUBLE ( 255, 0 ) DEFAULT NULL,
`comm` DOUBLE ( 255, 0 ) DEFAULT NULL,
`deptno` INT NOT NULL,
PRIMARY KEY ( `empid` )
) ENGINE = INNODB AUTO_INCREMENT = 6 DEFAULT CHARSET = utf8mb3;
启动项目,看看配置文件是否正确。
四、从数据库中获取数据
在项目pom.xml中引入lombok依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
编写实体类(pojo、domain、entity)
Employee.java
@Data 注解可以帮助我们生成构造方法、set()、get()、toString()方法等,代码看起来更简洁。
package com.lzw.springbootdemo.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.util.Date;
/**
* @Author LZW
* @Description
* @Date 2022-04-08 22:40
* @Version 1.0
*/
@Data
public class Employee {
private int empid;
private String ename;
private String job;
private int mgr;
@JsonFormat(locale = "zh",pattern = "yyyy-MM-dd HH:mm:ss" , timezone = "GMT+8")
private Date hiredate;
private double sal;
private double comm;
private int deptno;
}
编写EmployeeMappr.interface EmployeeMappr.xml
EmployeeMappr.interface
package com.lzw.springbootdemo.mapper;
import com.lzw.springbootdemo.entity.Employee;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* @Author LZW
* @Description
* @Date 2022-04-09 20:46
* @Version 1.0
*/
@Mapper
public interface EmployeeMapper {
/**
* 查询员工信息列表
* @return
*/
List<Employee> queryEmpList();
}
EmployeeMappr.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.lzw.springbootdemo.mapper.EmployeeMapper">
<!-- id 自己指定,便于后面引用。-->
<resultMap id="BaseResultMap" type="com.lzw.springbootdemo.entity.Employee">
<id column="empid" jdbcType="INTEGER" property="empid"/>
<result column="ename" jdbcType="VARCHAR" property="ename"/>
<result column="job" jdbcType="VARCHAR" property="job"/>
<result column="mgr" jdbcType="INTEGER" property="mgr"/>
<result column="hiredate" jdbcType="DATE" property="hiredate"/>
<result column="sal" jdbcType="DOUBLE" property="sal"/>
<result column="comm" jdbcType="DOUBLE" property="comm"/>
<result column="deptno" jdbcType="INTEGER" property="deptno"/>
</resultMap>
<sql id="BASE_LIST_CLOUMN">
empid
,ename,job,hiredate,sal,comm,deptno
</sql>
<select id="queryEmpList" resultMap="BaseResultMap">
select <include refid="BASE_LIST_CLOUMN"/>
from employee
</select>
</mapper>
编写 EmployeeService.interface EmployeeServiceImpl.java
EmployeeService.interface
public interface EmployeeService {
/**
* 查询员工信息列表
* @return
*/
List<Employee> queryEmpList();
}
EmployeeServiceImpl.java
@Service // 一定要加上注解
public class EmployeeServiceImpl implements EmployeeService {
@Autowired
private EmployeeMapper employeeMapper;
@Override
public List<Employee> queryEmpList() {
List<Employee> employeeList = employeeMapper.queryEmpList();
if(employeeList != null && !employeeList.isEmpty()){
return employeeList;
}
return null;
}
}
编写 EmployeeController.java
@RestController
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
@GetMapping("queryEmpList")
public List<Employee> queryEmpList() {
List<Employee> employees = employeeService.queryEmpList();
return employees;
}
}
启动项目,Postman或者浏览器访问: http://localhost:8080/api/queryEmpList
至此,一个简单的springboot项目搭建完成。
项目地址:https://github.com/Li-zw/springboot-repositories.git
最后,附上一个Mapper增删改查的样例
<?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.lzw.zoographyserver.mapper.PlantsMapper">
<resultMap id="BaseResultMap" type="com.lzw.zoographyserver.entity.Plants">
<id column="tid" jdbcType="VARCHAR" property="tid"/>
<result column="name" jdbcType="VARCHAR" property="name"/>
<result column="alias" jdbcType="VARCHAR" property="alias"/>
<result column="family" jdbcType="VARCHAR" property="family"/>
<result column="origin" jdbcType="VARCHAR" property="origin"/>
<result column="characteristics" jdbcType="VARCHAR" property="characteristics"/>
<result column="distribution" jdbcType="VARCHAR" property="distribution"/>
<result column="collection" jdbcType="VARCHAR" property="collection"/>
<result column="medicine" jdbcType="VARCHAR" property="medicine"/>
<result column="functions" jdbcType="VARCHAR" property="functions"/>
<result column="application" jdbcType="VARCHAR" property="application"/>
<result column="composition" jdbcType="VARCHAR" property="composition"/>
<result column="path" jdbcType="VARCHAR" property="path"/>
<result column="created_time" jdbcType="VARCHAR" property="created_time"/>
<result column="updated_time" jdbcType="VARCHAR" property="updated_time"/>
</resultMap>
<sql id="Base_Column_List">
tid
,name,alias,family,origin,characteristics,distribution,
collection,medicine,functions,application,composition,path,created_time,updated_time
</sql>
<!--查询所有的数据信息-->
<select id="queryPlantsData" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from plants_tb
limit 100
</select>
<!--动态插入数据信息-->
<insert id="insertInfoSelective" parameterType="com.lzw.zoographyserver.entity.Plants">
insert into plants_tb
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="tid != null">
tid,
</if>
<if test="name != null">
name,
</if>
<if test="alias != null">
alias,
</if>
<if test="family != null">
family,
</if>
<if test="origin != null">
origin,
</if>
<if test="characteristics != null">
characteristics,
</if>
<if test="distribution != null">
distribution,
</if>
<if test="collection != null">
collection,
</if>
<if test="medicine != null">
medicine,
</if>
<if test="functions != null">
functions,
</if>
<if test="application != null">
application,
</if>
<if test="composition != null">
composition,
</if>
<if test="path != null">
path,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="tid != null">
#{tid,jdbcType=VARCHAR},
</if>
<if test="name != null">
#{name,jdbcType=VARCHAR},
</if>
<if test="alias != null">
#{alias,jdbcType=VARCHAR},
</if>
<if test="family != null">
#{family,jdbcType=VARCHAR},
</if>
<if test="origin != null">
#{origin,jdbcType=VARCHAR},
</if>
<if test="characteristics != null">
#{characteristics,jdbcType=VARCHAR},
</if>
<if test="distribution != null">
#{distribution,jdbcType=VARCHAR},
</if>
<if test="collection != null">
#{collection,jdbcType=VARCHAR},
</if>
<if test="medicine != null">
#{medicine,jdbcType=VARCHAR},
</if>
<if test="functions != null">
#{functions,jdbcType=VARCHAR},
</if>
<if test="application != null">
#{application,jdbcType=VARCHAR},
</if>
<if test="composition != null">
#{composition,jdbcType=VARCHAR},
</if>
<if test="path != null">
#{path,jdbcType=VARCHAR},
</if>
</trim>
</insert>
<!--动态更新数据信息-->
<update id="updateSelectiveByTid" parameterType="com.lzw.zoographyserver.entity.Plants">
UPDATE plants_tb
<trim prefix="set" suffixOverrides=",">
<if test="tid != null">
tid = #{tid},
</if>
<if test="name != null">
name = #{name},
</if>
<if test="alias != null">
alias = #{alias},
</if>
<if test="family != null">
family = #{family},
</if>
<if test="origin != null">
origin = #{origin},
</if>
<if test="characteristics != null">
characteristics = #{characteristics},
</if>
<if test="distribution != null">
distribution = #{distribution},
</if>
<if test="collection != null">
collection = #{collection},
</if>
<if test="medicine != null">
medicine = #{medicine},
</if>
<if test="functions != null">
functions = #{functions},
</if>
<if test="application != null">
application =#{application},
</if>
<if test="composition != null">
composition = #{composition},
</if>
<if test="path != null">
path = #{path},
</if>
</trim>
WHERE tid=#{tid}
</update>
<delete id="deleteByTid">
delete from plants_tb
where tid = #{tid}
</delete>
</mapper>