Java学习之SpringBoot

什么是SpringBoot

SpringBoot是Spring项目中的一个子工程,与我们所熟知的Spring-framework 同属于spring的产品:

 

 

把Spring Boot称为搭建程序的脚手架。其最主要作用就是帮我们快速的构建庞大的spring项目,并且尽可能的减少一切xml配置,做到开箱即用,迅速上手,让我们关注于业务而非配置。

我们可以使用SpringBoot创建java应用,并使用"java –jar"命令启动,就能得到一个生产级别的web工程。

特点:

  • 创建独立的spring应用程序

  • 直接内嵌tomcat、jetty和undertow(不需要打包成war包部署)

  • 提供了固定化的“starter”配置,以简化构建配置

  • 尽可能的自动配置spring和第三方库

  • 提供产品级的功能,如:安全指标、运行状况监测和外部化配置等

  • 绝对不会生成代码,并且不需要XML配置

项目Demo

 

 

 

 

 

 

 

添加启动器:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.5.RELEASE</version>
</dependency>

添加测试:

@RestController
@EnableAutoConfiguration
public class MyController {

    @GetMapping("hello")
    public String test(){
        return "HelloWorld!";
    }

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

运行后,在浏览器输入地址:http://localhost:8080/hello

结果:

注意:SpringBoot启动需要先关闭上一个再启动!

上述demo只有一个controller,可以进行优化:

启动类:

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

测试类:

@RestController
public class MyController {

    @GetMapping("hello")
    public String test(){
        return "First SpringBoot";
    }
}
@RestController
public class MyController2 {

    @GetMapping("hello2")
    public String test(){
        return "Second SpringBoot";
    }
}

结果:

 补充:

@EnableAutoConfiguration

开启spring应用程序的自动配置,SpringBoot基于你所添加的依赖和你自己定义的bean,试图去猜测并配置你想要的配置。比如我们引入了`spring-boot-starter-web`,而这个启动器中帮我们添加了`tomcat`、`SpringMVC`的依赖。此时自动配置就知道你是要开发一个web应用,所以就帮你完成了web及SpringMVC的默认配置了!

总结,SpringBoot内部对大量的第三方库或Spring内部库进行了默认配置,这些配置是否生效,取决于我们是否引入了对应库所需的依赖,如果有那么默认配置就会生效。所以,我们使用SpringBoot构建一个项目,只需要引入所需依赖,配置就可以交给SpringBoot处理了。

 

 @SpringBootApplication

@SpringBootApplication其实是一个组合注解,这里重点的注解有3个:

  • @SpringBootConfiguration(来声明当前类是SpringBoot应用的配置类,项目中只能有一个,所以一般我们无需自己添加。)

  • @EnableAutoConfiguration:开启自动配置

  • @ComponentScan:开启注解扫描

配置文件

SpringBoot使用一个全局的配置文件,配置文件名是固定的,文件命名主要分为以下两种(任选其一):

•application.properties

•application.yml

完整项目

(Springboot+HikariCP连接池+MyBatis+Thymeleaf,实现数据查询)

 项目结构:

 

 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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.demo.myspringboot</groupId>
    <artifactId>myspringboot</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.1.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.28</version>
        </dependency>
        <!--默认使用HikariCP连接池-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
            <version>2.1.5.RELEASE</version>
        </dependency>
        <!--不要忘记数据库驱动,因为springboot不知道我们使用的什么数据库,这里选择mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>
        <!--mybatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!-- thymeleaf -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
            <version>2.1.4.RELEASE</version>
        </dependency>
    </dependencies>
</project>
pom.xml

application.properties:

# 连接四大参数
spring.datasource.url=jdbc:mysql://localhost:3306/bgblog
spring.datasource.username=root
spring.datasource.password=root
# 可省略,SpringBoot自动推断
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.hikari.idle-timeout=60000
spring.datasource.hikari.maximum-pool-size=30
spring.datasource.hikari.minimum-idle=10

# mybatis 别名扫描
mybatis.type-aliases-package=com.demo.bean.User
# mapper.xml文件位置,如果没有映射文件,请注释掉
mybatis.mapper-locations=classpath:mappers/*.xml

#thymeleaf
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.mode=HTML
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.suffix=.html
spring.thymeleaf.cache=false
application.properties

index.html(首页):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>HelloWorld!</h1>
<form method="post" action="/user">
    <button type="submit">查询用户</button>
</form>
</body>
</html>
index.html

User.html(Thymeleaf 静态页面):

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
    <style type="text/css">
        table {border-collapse: collapse; font-size: 14px; width: 80%; margin: auto}
        table, th, td {border: 1px solid darkslategray;padding: 10px}
    </style>
</head>
<body>
<div style="text-align: center">
    <span style="color: darkslategray; font-size: 30px">欢迎光临!</span>
    <hr/>
    <table class="list">
        <tr>
            <th>id</th>
            <th>姓名</th>
            <th>电话</th>
            <th>密码</th>
        </tr>
        <tr th:each="user : ${users}">
            <td th:text="${user.userId}">1</td>
            <td th:text="${user.userName}">张三</td>
            <td th:text="${user.phoneNum}">110</td>
            <td th:text="${user.passWorld}">888</td>
        </tr>
    </table>
</div>
</body>
</html>
User.html

UserMapper.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:名称空间,由于映射文件有多个,为了防止crud语句的唯一标识被重复,可以设置空间名称。
 -->
<mapper namespace="com.demo.Mapper.UserMapper">
    <!--
    select:查询的statement(声明),用来编写查询语句
    id:语句的唯一标识
    resultType:配置返回的结果集类型
    parameterType:传递的参数类型,可以省略
    -->
    <select id="queryUserById" resultType="com.demo.bean.User">
        select * from user where userId = #{id}
    </select>
    <select id="queryUserList" resultType="com.demo.bean.User">
        select * from user
    </select>
    <!--
          insert:插入的statement,编写插入语句
          id:插入语句的唯一标识
          parameterType:插入语句的参数,可以省略
       -->
    <insert id="insertUser">
        insert into user VALUES (
        #{userId},
        #{userName},
        #{phoneNum},
        #{passWorld}
        );
    </insert>
    <!--
    update:更新的statement,用来编写更新语句
    id:语句的唯一标识
    parameterType:语句的参数,可以省略
 -->
    <update id="updateUser">
        update user set userName =   #{userName} where userId = #{userId};
    </update>
    <!--
    delete:删除的statement,用来编写删除语句
    id:语句的唯一标识
    parameterType:语句的参数,可以省略
 -->
    <delete id="deleteUserById">
        delete from user where userId = #{id};
    </delete>

</mapper>
UserMapper.xml

TestApplication:

/**
 * 启动器
 * */
@SpringBootApplication
public class TestApplication {
    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }
}
TestApplication

User:

@Component
public class User {
    private String userId;
    private String userName;
    private String phoneNum;
    private String passWorld;

    public User() {
    }

    public User(String userId, String userName, String phoneNum, String passWorld) {
        this.userId = userId;
        this.userName = userName;
        this.phoneNum = phoneNum;
        this.passWorld = passWorld;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public void setPhoneNum(String phoneNum) {
        this.phoneNum = phoneNum;
    }

    public void setPassWorld(String passWorld) {
        this.passWorld = passWorld;
    }

    public String getUserId() {
        return userId;
    }

    public String getUserName() {
        return userName;
    }

    public String getPhoneNum() {
        return phoneNum;
    }

    public String getPassWorld() {
        return passWorld;
    }

    @Override
    public String toString() {
        return "User{" +
                "userId='" + userId + '\'' +
                ", userName='" + userName + '\'' +
                ", phoneNum='" + phoneNum + '\'' +
                ", passWorld='" + passWorld + '\'' +
                '}';
    }
}
User

DefaultPage(设置默认页面):

/**
 * 设置默认页面
 * */
@Configuration
public class DefaultPage extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers( ViewControllerRegistry registry )
    {
        registry.addViewController( "/" ).setViewName( "forward:/index.html" );
        registry.setOrder( Ordered.HIGHEST_PRECEDENCE );
        super.addViewControllers( registry );
    }
}
DefaultPage

JdbcConfiguration(获取数据源):

/**
 * 获取数据源
 * */
@Configuration
public class JdbcConfiguration {

    // 声明要注入的属性前缀,SpringBoot会自动把相关属性通过set方法注入到DataSource中
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        return dataSource;
    }
}
JdbcConfiguration

MVCConfiguration(设置拦截器):

/**
 * 设置拦截器
 * */
@Configuration
public class MVCConfiguration implements WebMvcConfigurer{

    @Autowired
    private MyInterceptor myInterceptor;
    /**
     * 重写接口中的addInterceptors方法,添加自定义拦截器
     * @param registry
     */
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor).addPathPatterns("/**");
    }
}
MVCConfiguration

MyInterceptor(拦截器对象):

/**
 * 拦截器
 * */
@Component
public class MyInterceptor implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle method is running!");
        return true;
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle method is running!");
    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion method is running!");
    }
}
MyInterceptor

JdbcProperties(数据源属性对象):

/**
 * 数据源属性获取
 * */
@ConfigurationProperties(prefix = "spring.datasource")
public class JdbcProperties {
    private String url;
    private String driverClassName;
    private String username;
    private String password;

    public String getUrl() {
        return url;
    }

    public String getDriverClassName() {
        return driverClassName;
    }

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }

    public void setUrl(String url) {

        this.url = url;
    }

    public void setDriverClassName(String driverClassName) {
        this.driverClassName = driverClassName;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public JdbcProperties(String url, String driverClassName, String username, String password) {

        this.url = url;
        this.driverClassName = driverClassName;
        this.username = username;
        this.password = password;
    }

    public JdbcProperties() {

    }
}
JdbcProperties

MyController:

/**
 * 测试Controller
 * */
@Controller
public class MyController {

    @Autowired
    private DataSource dataSource;
    @Autowired
    private UserService userService;

    @RequestMapping("/user")
    public String all(ModelMap model) {
        // 查询用户
        List<User> users = this.userService.queryUserList();
        // 放入模型
        model.addAttribute("users", users);
        // 返回模板名称(就是classpath:/templates/目录下的html文件名)
        return "User";
    }
}
MyController

UserService:

@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    public User queryUserById(String id){
        User user = userMapper.queryUserById(id);
        return user;
    }
    public List<User> queryUserList(){
        List<User> users = userMapper.queryUserList();
        return users;
    }

    public void insertUser(User user){
        userMapper.insertUser(user);
    }
    public void updateUser(User user){
        userMapper.updateUser(user);
    }

    public void deleteUserById(String id){
        userMapper.deleteUserById(id);
    }
}
UserService

UserMapper:

@Mapper
@Component
public interface UserMapper {
    /**
     * 通过id查询user对象
     * @param id
     * @return
     */
    User queryUserById(String id);
    /**
     * 查询所有用户
     * @return
     */
    List<User> queryUserList();

    /**
     * 插入用户
     * @param user
     */
    void insertUser(User user);

    /**
     * 更新用户
     * @param user
     */
    void updateUser(User user);
    /**
     * 通过id删除用户
     * @param id
     */
    void deleteUserById(String id);
}
UserMapper

 数据库(Mysql):

新建库:bgblog

表数据:

CREATE TABLE `user` (
  `userId` varchar(100) DEFAULT NULL,
  `userName` varchar(100) DEFAULT NULL,
  `phoneNum` varchar(100) DEFAULT NULL,
  `passWorld` varchar(100) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `user` VALUES ('001', '张三', '13888888888', '123');
INSERT INTO `user` VALUES ('002', '李四', '13888888888', '456');
INSERT INTO `user` VALUES ('003', '王五', '13888888888', '789');
INSERT INTO `user` VALUES ('004', '赵六', '13888888888', '000');

页面展示:

浏览器输入:localhost:8080,进入默认页面:

点击“查询用户”,展示thymeleaf页面:

 补充Thymeleaf页面标签报错/红色波浪线解决方法:

打开IDE的file->setting->左上角搜索inspections,然后在右边的搜索栏输入thy,就会显示如下页面,将Expression variables validation的√去掉,然后点击确定。

 

posted @ 2020-12-13 16:09  请别耽误我写BUG  阅读(4769)  评论(0编辑  收藏  举报