Java学习之SpringBoot
什么是SpringBoot
SpringBoot是Spring项目中的一个子工程,与我们所熟知的Spring-framework 同属于spring的产品:
把Spring Boot称为搭建程序的脚手架。其最主要作用就是帮我们快速的构建庞大的spring项目,并且尽可能的减少一切xml配置,做到开箱即用,迅速上手,让我们关注于业务而非配置。
我们可以使用SpringBoot创建java应用,并使用"java –jar"命令启动,就能得到一个生产级别的web工程。
特点:
-
-
直接内嵌tomcat、jetty和undertow(不需要打包成war包部署)
-
提供了固定化的“starter”配置,以简化构建配置
-
尽可能的自动配置spring和第三方库
-
提供产品级的功能,如:安全指标、运行状况监测和外部化配置等
-
项目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启动需要先关闭上一个再启动!
@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"; } }
结果:
补充:
@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>
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
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>
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>
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>
TestApplication:
/** * 启动器 * */ @SpringBootApplication public class TestApplication { public static void main(String[] args) { SpringApplication.run(TestApplication.class, args); } }
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 + '\'' + '}'; } }
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 ); } }
JdbcConfiguration(获取数据源):
/** * 获取数据源 * */ @Configuration public class JdbcConfiguration { // 声明要注入的属性前缀,SpringBoot会自动把相关属性通过set方法注入到DataSource中 @Bean @ConfigurationProperties(prefix = "spring.datasource") public DataSource dataSource() { DruidDataSource dataSource = new DruidDataSource(); return dataSource; } }
MVCConfiguration(设置拦截器):
/** * 设置拦截器 * */ @Configuration public class MVCConfiguration implements WebMvcConfigurer{ @Autowired private MyInterceptor myInterceptor; /** * 重写接口中的addInterceptors方法,添加自定义拦截器 * @param registry */ public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(myInterceptor).addPathPatterns("/**"); } }
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!"); } }
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() { } }
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"; } }
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); } }
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); }
数据库(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的√去掉,然后点击确定。