本篇是在上一篇“SpringBoot快速集成MyBatis+MySQL”的基础上,视图层通过集成Thymeleaf,数据持久层通过集成MyBatis从而完成数据的增删改查。
Thymeleaf是什么
简单说, Thymeleaf 是一个跟 Velocity、FreeMarker 类似的模板引擎,它可以完全替代 JSP 。
它的优点:
- 开箱即用,它提供标准和spring标准两种方言,可以直接套用模板实现JSTL、 OGNL表达式效果,避免每天套模板、改jstl、改标签的困扰。同时开发人员也可以扩展和创建自定义的方言;
- Thymeleaf 提供spring标准方言和一个与 SpringMVC 完美集成的可选模块,可以快速的实现表单绑定、属性编辑器、国际化等功能。
使用之前需在pom.xml中先引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
还需要在springboot项目的application.properties做如下配置
#Thymeleaf配置
spring.thymeleaf.cache=false
spring.thymeleaf.encoding=utf-8
spring.thymeleaf.mode=HTML5
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
以下就是我的项目目录:
接下来就是我做的简单的增删改查:
//封装的头部header.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div data-th-fragment="header">
<a href="/users">首页</a>
</div>
</body>
</html>
//首页index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="utf-8">
<title th:text="${userModel.title}"></title>
</head>
<body>
<div th:replace="~{fragments/header :: header}">...</div>
<div th:text="${userModel.title}"></div>
<div>
<a href="/users/form">添加用户</a>
</div>
<table border="1">
<thead>
<tr>
<td>ID</td>
<td>名字</td>
<td>电话</td>
<td>性别</td>
</tr>
</thead>
<tbody>
<tr th:if="${userModel.userList.size()} eq 0">
<td colspan="3">没有用户信息!</td>
</tr>
<tr th:each="user : ${userModel.userList}">
<td th:text="${user.userId}"></td>
<td th:text="${user.userName}"></td>
<td th:text="${user.phone}"></td>
<td th:text="${user.sex}"></td>
</tr>
</tbody>
</table>
</body>
</html>
//添加用户add.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<title th:text="${userModel.title}"></title>
</head>
<body>
<div th:replace="~{fragments/header :: header}">...</div>
<div th:text="${userModel.title}"></div>
<form action="/users/add" method="post" th:object="${userModel.user}">
<input type="hidden" name="userId" th:value="*{userId}">
名字:
<input type="text" name="userName" th:value="*{userName}">
电话:
<input type="text" name="phone" th:value="*{phone}">
性别:
<input type="text" name="sex" th:value="*{sex}">
<br>
<input type="submit" value="提交">
</form>
</body>
</html>
controller层
package com.example.springboot.controller;
import com.example.springboot.pojo.UserInfo;
import com.example.springboot.service.ExportService;
import com.example.springboot.util.Log4j2Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
@RestController
@RequestMapping("/users")
public class UserInfoController {
@Autowired
private ExportService userservice;
/**
*获取用户列表
* @author qqg
* @date
* @param * @param model
* @return
*/
private List<UserInfo> getUserList(){
List<UserInfo> lists = userservice.getUserList();
Log4j2Util.logger.info("查询到的用户信息:\n"+lists);
return lists;
}
@GetMapping
public ModelAndView userList(Model model){
model.addAttribute("userList",getUserList());
model.addAttribute("title","用户管理");
return new ModelAndView("index","userModel",model);
}
/**
*创建表单
* @author qqg
* @date
* @param * @param model
* @return
*/
@GetMapping("/form")
public ModelAndView createForm(Model model){
model.addAttribute("user",new UserInfo());
model.addAttribute("title","添加用户");
return new ModelAndView("add","userModel",model);
}
/**
*功能描述 添加用户
* @author qqg
* @date
* @param * @param user
* @return
*/
@PostMapping("/add")
public ModelAndView addUser(UserInfo user){
int result = userservice.saveUserInfo(user);
Log4j2Util.logger.info("添加结果:\n"+result);
return new ModelAndView("redirect:/users");
}
}
服务层service
package com.example.springboot.service;
import com.example.springboot.pojo.UserInfo;
import java.util.List;
public interface ExportService {
List<UserInfo> getUserList();
Integer saveUserInfo(UserInfo user);
}
//服务实现impl
package com.example.springboot.service.impl;
import com.example.springboot.dao.UserInfoMapper;
import com.example.springboot.pojo.UserInfo;
import com.example.springboot.service.ExportService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class ExportServiceImpl implements ExportService{
@Autowired
private UserInfoMapper userinfomapper;
@Override
public List<UserInfo> getUserList() {
List<UserInfo> lists = userinfomapper.getAllUserInfo();
return lists;
}
@Override
public Integer saveUserInfo(UserInfo user) {
return userinfomapper.saveUserInfo(user);
}
}
数据持久层dao
package com.example.springboot.dao;
import com.example.springboot.pojo.UserInfo;
import java.util.List;
@Mapper
public interface UserInfoMapper {
List<UserInfo> getAllUserInfo();
Integer saveUserInfo(UserInfo user);
}
UserInfoMapper.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.springboot.dao.UserInfoMapper" >
<resultMap id="BaseResultMap" type="UserInfo" >
<id column="USER_ID" property="userId" jdbcType="INTEGER" />
<result column="USER_NAME" property="userName" jdbcType="VARCHAR" />
<result column="PHONE" property="phone" jdbcType="VARCHAR" />
<result column="SEX" property="sex" jdbcType="VARCHAR" />
</resultMap>
<sql id="Base_Column_List" >
USER_ID, USER_NAME, PHONE, SEX
</sql>
<!--查询所有用户信息-->
<select id="getAll" resultMap="BaseResultMap" parameterType="String" >
select
<include refid="Base_Column_List" />
from user_info
limit (#{page} - 1)* #{limit} ,#{limit}
</select>
<insert id="saveUserInfo" parameterType="UserInfo">
INSERT INTO user_info(USER_ID,USER_NAME,PHONE,SEX)
VALUES (#{userId},#{userName},#{phone},#{sex})
</insert>
<select id="findByphone" resultMap="BaseResultMap" parameterType="String" >
select *
from user_info
where PHONE = #{phone}
</select>
<select id="getAllUserInfo" resultMap="BaseResultMap">
select *
from user_info
</select>
</mapper>
实体类pojo
package com.example.springboot.pojo;
public class UserInfo {
private Integer userId;
private String userName;
private String phone;
private String sex;
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 getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public UserInfo() {
}
public UserInfo(Integer userId, String userName, String phone, String sex) {
this.userId = userId;
this.userName = userName;
this.phone = phone;
this.sex = sex;
}
@Override
public String toString() {
return "UserInfo{" +
"userId=" + userId +
", userName='" + userName + '\'' +
", phone='" + phone + '\'' +
", sex='" + sex + '\'' +
'}';
}
}
启动类SpringbootApplication
package com.example.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@SpringBootApplication
@EnableTransactionManagement
public class SpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
System.out.println("启动成功");
}
}
此时,运行springboot项目,结果如下:
除了上面这些基本的操作之外,springboot项目还要做些配置,程序才能够正常运行起来,
package com.example.springboot.config;
import org.apache.ibatis.type.TypeAliasRegistry;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
import javax.sql.DataSource;
import java.io.IOException;
/**
*配置与连接池的会话
* @author Lrd
* @date 2018/10/30
* @param * @param null
* @return
*/
@Configuration
public class MyBatisConfig {
@Resource
private DataSource dataSource;
@Bean(name = "sqlSessionFactory")
public SqlSessionFactoryBean sqlSessionFactoryBean(ApplicationContext applicationContext)throws IOException{
SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
sqlSessionFactory.setDataSource(dataSource);
sqlSessionFactory.setMapperLocations(applicationContext.getResources("classpath*:mapping/*.xml"));
sqlSessionFactory.setTypeAliasesPackage("com.example.springboot.pojo");
//别名注册器
TypeAliasRegistry typeAliasRegistry = new TypeAliasRegistry();
typeAliasRegistry.registerAlias("STDOUT_LOGGING", MyBatisConfig.class);
return sqlSessionFactory;
}
}
application.properties
server.port=8080
# 数据库访问配置
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/shop?useUnicode=true&characterEncoding=gbk&zeroDateTimeBehavior=convertToNull&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
# 下面为连接池的补充设置,应用到上面所有数据源中
spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=20
# 配置获取连接等待超时的时间
spring.datasource.maxWait=60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
spring.datasource.timeBetweenEvictionRunsMillis=60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=SELECT 1 FROM DUAL
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
#Thymeleaf配置
spring.thymeleaf.cache=false
spring.thymeleaf.encoding=utf-8
spring.thymeleaf.mode=HTML5
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
日志log4j2的配置
先引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
然后,创建log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="OFF" monitorInterval="30">
<Properties>
<Property name="LOG_PATTERN">
%d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${hostName} --- [%15.15t] %-40.40c{1.} : %m%n%ex
</Property>
<Property name="LOG_FILE_PATH">logs</Property>
</Properties>
<appenders>
<Console name="Console" target="SYSTEM_OUT" follow="true">
<PatternLayout pattern="${LOG_PATTERN}" />
</Console>
<RollingFile name="RollingFile" fileName="${LOG_FILE_PATH}/spring-boot-log4j2-demo.log" filePattern="${LOG_FILE_PATH}/spring-boot-log4j2-demo-%d{yyyy-MM-dd}-%i.log">
<PatternLayout>
<Pattern>${LOG_PATTERN}</Pattern>
</PatternLayout>
<Filters>
<!-- 只记录ERROR级别日志信息,程序打印的其他信息不会被记录 -->
<!-- 此level设置的日志级别,是过滤日志文件中打印出的日志信息,和Root的level有所区别 -->
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY" />
</Filters>
<Policies>
<SizeBasedTriggeringPolicy size="10MB" />
<!-- 每天创建一个日志文件 -->
<TimeBasedTriggeringPolicy interval="1" />
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
</appenders>
<loggers>
<root level="INFO">
<appender-ref ref="RollingFile" />
<appender-ref ref="Console" />
</root>
</loggers>
</configuration>
最后,在util中创建工具类Log4j2Util
package com.example.springboot.util;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Log4j2Util {
public static final Logger logger = LogManager.getLogger(Log4j2Util.class);
}