Spring boot 框架部署
概述
从SSM(spring spring MVC mybatis)到spring boot
本文前置知识点,spring, mybatis, tomcat等,这部分细节不在细讲
spring是一个大家族,spring MVC, spring boot都是其中的一部分
其中spring 提供了著名的IOC 和 AOP
IOC就是所谓控制反转,我要一个类,我不去自己new,而去拿一个,这样我们就可以中框架的自动装配或者是xml配置降低耦合,提高效率。
AOP是面向切面编程,一种编程思路,我们需要修改没写逻辑不去修改代码,而是添加执行该函数前做什么。减少对原代码的修改需求。
spring MVC是一个web模块,在原来的SSM框架中,用户浏览器请求,交给spring MVC处理,返回页面。而如何处理,我们单独出来一个业务层。这部分来写我们的逻辑代码。
而业务层又希望不用管数据库相关的问题,就多出了一个dao层,也就是数据可持久化层。
而spring boot视乎只是代替了原SSM层中 spring MVC的作用。他们对业务的抽象是一样的。
准备工作
首先我需要准备
打开网站后填写信息,在右侧依赖添加
Web, DevTools, Aspects, Thymeleaf, Mysql, MyBatis
DevTools:热部署
Thymeleaf: 一种控制器数据交互方式
Mysql,MyBatis 数据库依赖
点击创建后,会自动下载一个包,用IDEA打开包里面的pom.xml即可打开项目
等待项目加载。。。
初始目录如下
cwl@cwl-PC:~/web/spring boot init$ tree
.
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── example
│ │ └── demo
│ │ └── DemoApplication.java
│ └── resources
│ ├── application.properties
│ ├── static
│ └── templates
└── test
└── java
└── com
└── example
└── demo
└── DemoApplicationTests.java
14 directories, 6 files
wenda数据库下的test表
+----------+----------+
| username | password |
+----------+----------+
| cwl | cwl |
+----------+----------+
最终我们需要实现一个页面访问数据库的过程
Controller部分
用户发起浏览器请求页面,被我们交给控制器处理
我们添加项目结构文件夹
我们在main.java.com.example.demo目录下创建四个文件夹
controller
dao
model
service
在main.resources下创建文件夹mapper后面放我们的映射文件
controller是我们的控制器,我们在controller目录下创建一个类
MainController代表我们的主页控制器
一个普通的类,我们需要在类上面添加注解@Controller
然后编写一个方法,getMainWeb如下
MainController.java
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MainController {
@RequestMapping(path = "/", method = RequestMethod.GET)
@ResponseBody
public String getMainWeb() {
return "main";
}
}
@Controller代表我们这是一个控制器
@RequestMapping(path = "/", method = RequestMethod.GET)
代表我们浏览器访问“/"路径会被交给这个方法
@ResponseBody 表示返回的是字符串。也就是页面的字符串,
到这里我们已经配置完页面了,都是由于我们引入了数据库模块,但是我们没有配置数据库,依旧跑步起来。所以我们做先在appilcation.properties下填上一下内容,具体需要配置成你本地的参数
# mysql 配置
# 数据库配置 wenda是数据库的名字
spring.datasource.url=jdbc:mysql://localhost/wenda
spring.datasource.username=root
spring.datasource.password=1143316492
## Mybatis 配置
# model要改成模型的包
# 映射的包
mybatis.typeAliasesPackage=com.webdemo.demo.model
mybatis.mapperLocations=classpath:mapper/*.xml
数据库部分我们先放一边,这么做只是为了框架不报错
这样运行项目输入localhost:8080 就能访问到一个只有”main“字符串的页面,我们可以吧main换成html代码的字符串,当时这样未免太麻烦了。
于是:
我们在resources目录下templates创建home.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Home</title>
</head>
<body>
<h1>This is home pages</h1>
</body>
</html>
MainController.java
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MainController {
@RequestMapping(path = "/", method = RequestMethod.GET)
//@ResponseBody
public String getMainWeb() {
return "home";
}
}
注意上面我们注释掉的部分,那部分的注释我们是告诉框架我们返回的是字符串,去掉后,框架就会去templates下面去找home文件。前缀后缀的具体细节可以在application.properties里面配置。
到这里我们解决了Controller层的问题。
另外还有一些Controller层的细节
如何交互数据,这里我们用的是thymeleaf模板的内容
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MainController {
@RequestMapping(path = "/", method = RequestMethod.GET)
//@ResponseBody
public String getMainWeb(Model model) {
model.addAttribute("message", "this is main page");
return "home";
}
}
我们修改MainController的内容,注意我们添加了一个参数列表,调用了一个addAttribute.这个意思是我们加入了一个映射,在页面中我们去message的值会编程后面那个字符串。具体怎么取,就是thymeleaf的定义了,我们在html页面中修改
<h1 th:text="${message}"></h1>
这样控制层和页面的数据交互解决了。更多细节我们去查那个框架即可。
Dao层
数据访问层,dao层,有人人用mapper层,其实是一个意思,为了方便,我们演示的时候直接从控制层调用数据库部分
我们添加模型类User数据,放在model文件夹下,类型根据我们的数据库来,这部分是Mybatis的知识,这里不在赘述。
package com.example.demo.model;
public class User {
private String username;
private String password;
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;
}
}
在dao目录下我们创建UserDao的接口
package com.example.demo.dao;
import com.example.demo.model.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface UserDao {
@Select({"select username, password from test where username = #{name}"})
User getUserByUsername(String name);
}
一些注解的说明
@Component ——表示一个自动扫描 component
@Repository ——表示持久化层的 DAO component
@Service ——表示业务逻辑层的 Service component
@Controller ——表示表示层的 Controller component
@Mapper经过我的测试无效,不知道什么回事,如果只这样写会加载不到这个bean
另一种解决方法是在入口处手动配置
package com.example.demo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.example.demo.dao")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
上面的@MapperScan
然后在Controller层
package com.example.demo.controller;
import com.example.demo.dao.UserDao;
import com.example.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MainController {
@Autowired
UserDao userDao;
@RequestMapping(path = "/", method = RequestMethod.GET)
public String getMainWeb(Model model) {
User user = userDao.getUserByUsername("cwl");
System.out.println(user.getUsername() + " " + user.getPassword());
return "home";
}
}
上面的userDao是一个接口,但是我们的框架会给我们自动装载为bean
@Selcet替我们实现方法,但是更复杂的部分需要用mapper手动写
我们注释掉刚刚的@select
在mapper下添加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.example.demo.dao.UserDao">
<resultMap id="userResultMap" type="com.example.demo.model.User">
<result column="username" property="username" />
<result column="password" property="password" />
</resultMap>
<select id="getUserByUsername" parameterType="com.example.demo.model.User" resultMap="userResultMap">
select *
from test
where username = #{name}
</select>
</mapper>
到这里我们核心问题都解决了,上面我们虽然通过controller调用dao层,但是核心已经出来了,添加业务中间层已经不是框架的问题了,不在细讲了。
最后项目结构
.
├── demo.iml
├── mvnw
├── mvnw.cmd
├── pom.xml
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── example
│ │ │ └── demo
│ │ │ ├── controller
│ │ │ │ └── MainController.java
│ │ │ ├── dao
│ │ │ │ └── UserDao.java
│ │ │ ├── DemoApplication.java
│ │ │ ├── model
│ │ │ │ └── User.java
│ │ │ └── service
│ │ └── resources
│ │ ├── application.properties
│ │ ├── mapper
│ │ │ └── UserMapper.xml
│ │ ├── static
│ │ └── templates
│ │ └── home.html
│ └── test
│ └── java
│ └── com
│ └── example
│ └── demo
│ └── DemoApplicationTests.java
└── target
├── classes
│ ├── application.properties
│ ├── com
│ │ └── example
│ │ └── demo
│ │ ├── controller
│ │ │ └── MainController.class
│ │ ├── dao
│ │ │ └── UserDao.class
│ │ ├── DemoApplication.class
│ │ └── model
│ │ └── User.class
│ ├── mapper
│ │ └── UserMapper.xml
│ └── templates
│ └── home.html
├── generated-sources
│ └── annotations
├── generated-test-sources
│ └── test-annotations
└── test-classes
└── com
└── example
└── demo
└── DemoApplicationTests.class