SpringBoot实践(SSM整合SpringBoot版)
SpringBoot实践
接下来,我们来看看如何用SpringBoot来玩转以前的SSM
首先创建SpringBoot项目,详情参考SpringBoot快速入门
导入坐标
<?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">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>day01Springboot01</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<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>
<!-- web的起步依赖springMVC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--spring-test-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
<!--maven插件Spring Boot应用提供了执行Maven操作的可能-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
整合SpringMVC
虽然默认配置已经可以使用SpringMVC了,不过我们有时候需要进行自定义配置。
通过查看自动配置中的HttpMessageConvertersAutoConfiguration,了解默认支持Jackson
修改端口
查看SpringBoot的全局属性可知,端口通过以下方式配置:
# 映射端口
server:
port: 80
重启服务后测试:
访问静态资源
现在,我们的项目是一个jar工程,那么就没有webapp,我们的静态资源该放哪里呢?
回顾我们之前看的源码SpringBoot自动配置原理,有一个叫做ResourceProperties的类,里面就定义了静态资源的默认查找路径:
默认的静态资源路径为:
- classpath:/META-INF/resources/
- classpath:/resources/
- classpath:/static/
- classpath:/public
只要静态资源放在这些目录中任何一个,SpringMVC都会帮我们处理。
我们习惯会把静态资源放在classpath:/static/
目录下。我们创建目录,并且添加一些静态资源:
整合jdbc和事务
spring中的jdbc连接和事务是配置中的重要一环,在SpringBoot中该如何处理呢?
答案是不需要处理,我们只要找到SpringBoot提供的启动器即可:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
至于事务,SpringBoot中通过注解来控制。就是我们熟知的@Transactional
@Service
@Transactional
public class UserServiceImpl implements UserService {
}
整合连接池
其实,在刚才引入jdbc启动器的时候,SpringBoot已经自动帮我们引入了一个连接池:
HikariCP应该是目前速度最快的连接池了,我们看看它与c3p0的对比:
因此,我们只需要指定连接池参数即可:
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/saas-export?characterEncoding=utf-8
username: root
password: root
5.4.MyBatisPlus
5.4.1 pom坐标
<!--jdbc-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--springboot支持的是jpa,mybatisplus自己做了启动器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.2</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
5.4.2 创建mapper接口类继承BaseMapper
package com.ordinov.mapper;
import com.baomidou.mybatisplus.core.mapper.Mapper;
public interface UserMapper extends Mapper {
//BaseMapper中有各种方式可供调用
}
常用注解
@TableName("数据库表名") //指定对应表名
@TableId(type = IdType.AUTO) //指定主键生成策略
/**
* AUTO : AUTO(0, “数据库ID自增”),
* INPUT : INPUT(1, “用户输入ID”),
* ID_WORKER : ID_WORKER(2, “全局唯一ID”),默认值如果不设置会在用该策略
* UUID : UUID(3, “全局唯一ID”),
* NONE : NONE(4, “该类型为未设置主键类型”),
* ID_WORKER_STR : ID_WORKER_STR(5, “字符串全局唯一ID”);
*/
@TableField("字段名") //字段注解(非主键)
源码分析,可以通过在测试类中打断点进入方法进行查看,进入到MybatisMapperProxy->execute
测试类
package com.ordinov.test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class MybatisTest {
}
完成整合项目
项目结构
创建数据库及数据表
CREATE DATABASE `springbootdemo`;
USE `springbootdemo`;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`userId` int(20) NOT NULL AUTO_INCREMENT,
`userName` varchar(20) DEFAULT NULL,
`password` varchar(20) DEFAULT NULL,
`status` int(1) DEFAULT NULL,
PRIMARY KEY (`userId`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
insert into `user`(`userId`,`userName`,`password`,`status`) values (1,'张三','123',0),(2,'李四','234',1);
导入坐标
<?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">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>day01Springboot01</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<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>
<!-- web的起步依赖springMVC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--spring-test-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!--jdbc-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--springboot支持的是jpa,mybatisplus自己做了启动器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.2</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
</dependencies>
<!--maven插件Spring Boot应用提供了执行Maven操作的可能-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
导入yaml文件
logging:
level:
com.ordinov: debug #指定目录的日志级别
org.springframework: debug #Spring框架日志级别 debug info warn error fatal
# 映射端口
server:
port: 80
#HikariCP数据源设置
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/springbootdemo?characterEncoding=utf-8&useSSL=false
username: root
password: root
#mybatis-plus设置
mybatis-plus:
mapper-locations: mapper/*.xml # mapper.xml文件位置,如果没有映射文件,请注释掉
注:&useSSL=false,MySQL在高版本需要指明是否进行SSL连接。不指明会报以下警告:
Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
另外,Mapper接口的位置在application.yml中并不能配置,Mapper接口的扫描有两种实现方式:
方式一
我们需要给每一个Mapper接口添加@Mapper
注解,由Spring来扫描这些注解,完成Mapper的动态代理。
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
方式二
在启动类上添加扫描包注解(推荐):
package com.ordinov;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.ordinov.mapper")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
这种方式的好处是,不用给每一个Mapper都添加注解。
编写实体类
package com.ordinov.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
@TableName("user")
public class User implements Serializable {
@TableId(type = IdType.AUTO, value = "userId")
private Integer userId;
@TableField(value = "userName")
private String userName;
@TableField(value = "password")
private String password;
@TableField(value = "status")
private int status;
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}
编写Mapper(Dao)
接下来就是Dao层设置步骤:
1)继承BaseMapper接口
package com.ordinov.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ordinov.pojo.User;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface UserMapper extends BaseMapper<User> {
@Select("SELECT userId,userName,STATUS FROM USER")
List<User> findAll(); //注解方式
List<User> findList(); //xml映射文件方式
}
2)xml配置文件(当需要自定义方法,可以考虑用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.ordinov.mapper.UserMapper">
<resultMap id="BaseResultMap" type="com.ordinov.pojo.User" >
<id column="userId" property="userId" jdbcType="INTEGER" />
<result column="userName" property="userName" jdbcType="VARCHAR" />
<result column="status" property="status" jdbcType="INTEGER" />
</resultMap>
<select id="findList" resultMap="BaseResultMap">
select userId,userName,status FROM user
</select>
</mapper>
Service&实现
package com.ordinov.service;
import com.ordinov.pojo.User;
import java.util.List;
public interface UserService {
/**
* 查询全部--xml
*/
List<User> findList();
/**
* 查询全部--注解
*/
List<User> findAll();
/**
* 查询一个用户--mapper
*/
User findOue(String id);
}
以及,UserService接口的实现类
package com.ordinov.service.impl;
import com.ordinov.mapper.UserMapper;
import com.ordinov.pojo.User;
import com.ordinov.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@Transactional
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
/**
* 查询全部--使用注解
* @return
*/
@Override
public List<User> findAll() {
return userMapper.findAll();
}
/**
* 查询一个用户--使用Mapper
*/
@Override
public User findOue(String id) {
return userMapper.selectById(id);
}
/**
* 查询全部--使用xml
* @return
*/
@Override
public List<User> findList() {
return userMapper.findList();
}
}
Controller
package com.ordinov.controller;
import com.ordinov.pojo.User;
import com.ordinov.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping
public List<User> findAll() {
return userService.findAll();
}
@GetMapping("/findList")
public List<User> findList() {
return userService.findList();
}
@GetMapping("/{id}")
public User findOne(@PathVariable String id) {
return userService.findOue(id);
}
}
测试
访问http://localhost/user 查询全部用户(注解方式)
访问http://localhost/user/1 根据ID查询用户 (mapper)
访问http://localhost/user/findList 查询全部用户(xml方式)
注:json格式化显示,使用了谷歌浏览器插件。