说在前头:
(1)GitHub下面有,但是请自行切换分支【GitHub里面或许有无关的注释的代码,请自行忽略】
(2)此作品,纯粹使用SpringBoot整合了SSM,博主有些细节,没有弄上去,可能不会类似于之前的手把手教的样子还请自行理解 ,不过大部分是有的~
(3)此作品,前台交互什么的是很粗糙的(因为博主纯粹是想整合SSM以及与数据库打交道),然后,欢迎大佬指点emmm~~~
OK,项目创建成功,当然,为了后面与数据库打交道,那么,需要添加数据库连接的Jar包 以及Junit单元测试等Jar,见下面Pom文件
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.8.RELEASE
org.yun
ssm
0.0.1-SNAPSHOT
ssm
Demo project for Spring Boot
1.8
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-aop
org.springframework.boot
spring-boot-starter-jdbc
org.springframework.boot
spring-boot-starter-web
mysql
mysql-connector-java
runtime
org.springframework.boot
spring-boot-starter-test
test
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.1.0
org.mybatis
mybatis
3.4.2
org.mybatis
mybatis-spring
1.3.1
org.springframework.boot
spring-boot-starter-data-jpa
junit
junit
4.12
org.springframework.boot
spring-boot-starter-thymeleaf
org.springframework.boot
spring-boot-starter-jdbc
org.springframework.boot
spring-boot-devtools
true
org.springframework.boot
spring-boot-maven-plugin
emmm~~不知道的可自行百度,是在懒的话,就这么理解吧
Lombox(小辣椒),是一个插件,可以省略自行手写get/set/toString/构造器等方法,只需要在实体类上面加上对应注解即可。提高开发效率。下面是Idea添加组件
@Data相当于@Getter @Setter @RequiredArgsContructor @ToString @EqualsAndHashCode 的合集。
功能介绍
其余的代码简写:
@Setter/@Getter : 自动生成set和get方法
@ToString : 自动生成toString方法
@EqualsAndHashcode : 从对象的字段中生成hashCode和equals的实现
@NoArgsConstructor/@RequiredArgsConstructor/@AllArgsConstructor
自动生成构造方法
@Data : 自动生成set/get方法,toString方法,equals方法,hashCode方法,不带参数的构造方法
@Value : 用于注解final类
@Builder : 产生复杂的构建器api类
@SneakyThrows : 异常处理(谨慎使用)
@Synchronized : 同步方法安全的转化
@Getter(lazy=true) : 开启懒加载
@Log : 支持各种logger对象,使用时用对应的注解,如:@Log4j
@NonNull : 让你不在担忧并且爱上NullPointerException
@CleanUp : 自动资源管理:不用再在finally中添加资源的close方法
CREATE TABLE user (
id varchar(228) NOT NULL,
name varchar(50) DEFAULT NULL,
password varchar(50) DEFAULT NULL,
age int(11) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='SSM测试用户表'
创建完成之后,数据自行添加
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/my_springboot_ssm?serverTimezone=UTC
username: root
password: 1234
# druid连接池
druid:
initial-size: 1 #初始化连接数
min-idle: 1 #最小空闲连接
max-active: 20 #最大活动连接
test-on-borrow: true #获取连接时测试是否可用
stat-view-servlet.allow: true #监控页面启动
#热部署:修改后台文件保存后自动重启
devtools:
restart:
enabled: true
spring-boot-devtools: src/main/java #监听目录
#thymeleag 配置视图解析器
thymeleaf:
prefix: classpath:/templates/
suffix: .html
model: HTML5
encoding: UTF-8
#开发时关闭缓存,不然没法看到实时页面
cache: false
servlet:
content-type: text/html
表示方法比较多,读者,可以,自行测试每个方法
package org.yun.ssm.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.ModelAndView;
import org.yun.ssm.service.UserService;
import org.yun.ssm.vo.UserVO;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @ClassName UserController
* @Description TODO
* @Autor 落笔丶
* @Date 2019/9/7 22:34
*/
/**
* 倘若正式开发(公司),自己不是全栈式,那么,此处@Controller 应该改为 @RestController 或者不变,但是在每个方法上面加上注解@ResposeBody表示返回Json数据给前台
* */
//4、@RestController注解的功能等同于@controller和@responsebody
//responsebody就是标识方法只返回字符串不进行视图跳转
//如果,公司,自己只负责后台 那么,可以使用此注解
//像这个 因为是自己玩 前后台交互 下面的 login ,加上@RestControlletr会报400 URL错误
//@RestController
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired(required=true)
private UserService userService;
/**
*
* @Author 落笔丶
* @Description HelloWord http://localhost:8080/user/test
* @Date 2019/9/8 21:55
* @Param
* @return
**/
@RequestMapping("/hello")
public String hello() {
return "Hello World !";
}
/**
*
* @Author 落笔丶
* @Description 测试
* @Date 2019/9/8 22:24
* @Param
* @returnv
* http://localhost:8080/user/map
**/
@RequestMapping("/map")
public Map<String, String> map1() {
Map<String, String> map = new HashMap<String, String>();
map.put("name", "张三");
map.put("age", "28");
return map;
}
/**
*
* @Author 落笔丶
* @Description 测试是否连接到数据库方法
* @Date 2019/9/8 21:32
* @Param
* @return
* http://localhost:8080/user/test
**/
@RequestMapping("/test")
public void test(){
List<UserVO> list = userService.findAll();
if (list != null && list.size() !=0){
for (UserVO userVO : list) {
System.out.println(userVO.getName());
System.out.println("连接数据库成功,查看控制台信息");
}
}else {
System.out.println("连接数据库失败");
}
}
/**
*
* @Author 落笔丶
* @Description 首页
* @Date 2019/9/8 21:56
* @Param * @param null
* @return
* http://localhost:8080/user/index
**/
@RequestMapping("/index")
public ModelAndView index(){
return new ModelAndView("index");
}
/**
*
* @Author 落笔丶
* @Description 前后台交互 跳转至login页面
* 1)参看https://blog.csdn.net/qq_40391559/article/details/82856868 -->当required 不为 false时 会报错 required string parameter 'XXX'is not present
* 2)如果,非要true 检查前台页面 与 此处的 name是否相同 emmm此处相同还是如此,所以我改为了false
* 3)此处,非要true,解决方法就是 加上默认值 defaultValue="123" 上面报错,可以理解 是因为自己,是第一次跳转此页面,所以一直拿不到值 是正常的
* @Date 2019/9/8 22:54
* @Param
* @return
* http://localhost:8080/user/login
**/
/*
*每次都有值 ----------->正式开发 应该此方法
* 登录名:年轻人
密码:1234
登录名:11
密码:11
* */
@GetMapping("/login")
public String login(
@RequestParam(value = "name" ,required = true, defaultValue = "年轻人") String name,
//如果要求请求参数里面有password这个参数,默认就是必须的
@RequestParam(value = "password" , required = true ,defaultValue = "1234") String password
) {
System.out.println("登录名:" + name);
System.out.println("密码:" + password);
return "login";
}
/*
* 登录名:null
密码:null
登录名:111
密码:111
*
* */
@GetMapping("/login3")
public String login3(
@RequestParam(value = "name" ,required = false) String name,
//如果要求请求参数里面有password这个参数,默认就是必须的
@RequestParam(value = "password" , required = false) String password,
HttpServletRequest request
) {
System.out.println("登录名:" + request.getParameter("name"));
System.out.println("密码:" + request.getParameter("password"));
return "login";
}
/*
* 第一次没值(这里没有值,很正常,以为调用的是从 request中获取,请求参数,所以没有值,是正常的【第一次无值】 而login方法一开始就有值,是因为一开始就没有使用request方法)
* 登录名:null
密码:null
//输入改变
登录名:123
密码:123
* */
@GetMapping("/login2")
public String login2(
@RequestParam(value = "name" ,required = true, defaultValue = "年轻人") String name,
//如果要求请求参数里面有password这个参数,默认就是必须的
@RequestParam(value = "password" , required = true ,defaultValue = "1234") String password,
HttpServletRequest request
) {
System.out.println("登录名:" + request.getParameter("name"));
System.out.println("密码:" + request.getParameter("password"));
return "login";
}
/**
*
* @Author 落笔丶
* @Description 注册
* @Date 2019/9/9 22:52
* @Param * @param null
* @return
**/
@RequestMapping(value = "/register",method = RequestMethod.POST)
@ResponseBody//此处算是,正常的前后台交互,前台传数据,后台接收,且业务处理 需要加上此注解,否则报错org.thymeleaf.exceptions.TemplateInputException: 需要返回Json数据 而不是@Controller的Spring视图了
public String register(HttpServletRequest request){
String name = request.getParameter("name");
String password = request.getParameter("password");
if (StringUtils.isEmpty(name) || StringUtils.isEmpty(password)){
return "用户名,或者密码为空";
}
if(userService.findByName(name) == true){
return "该用户名已被注册";
}
userService.add(name,password);
return "注册成功";
}
@PostMapping("/register2")
public ModelAndView register2(HttpServletRequest request){
String name = request.getParameter("name");
String password = request.getParameter("password");
ModelAndView modelAndView = new ModelAndView();
if (StringUtils.isEmpty(name) || StringUtils.isEmpty(password)){
modelAndView.addObject("message","注册用户名与密码不可为空");
modelAndView.setViewName("failed");
return modelAndView;
}
if(userService.findByName(name) == true){
modelAndView.addObject("message","该用户名已被注册");
modelAndView.setViewName("failed");
return modelAndView;
}
userService.add(name,password);
System.out.println("注册成功,跳转至登录页");
modelAndView.setViewName("login");
return modelAndView;
}
/**
*
* @Author 落笔丶
* @Description 真正意义上的,登录----(1)一开始,未登录过,所以,拿不到任何用回信息(2)加上用户是不可以重复的(3)所以,此处登录完全不做任何,关于findById的处理
* @Date 2019/9/9 23:21
* @Param * @param null
* @return
**/
@RequestMapping("/loginEnd")
public String loginEnd(WebRequest request){//request也可以这么拿 SpringMvc中
String name = request.getParameter("name");
String password = request.getParameter("password");
if (StringUtils.isEmpty(name) || StringUtils.isEmpty(password) ){
System.out.println("登录失败");
return "failed";
}
List<UserVO> all = userService.findAll();
for (UserVO userVO : all) {
if (userVO.getName().equals(name) && userVO.getPassword().equals(password)) {
//登录成功
return "index";
}
}
//登录失败
return "用户名 密码未注册";
}
/* @RequestMapping("/listPage")
public ResultVO> listPage(@RequestBody FactoryDTO dto){
try {
PageInfo pageInfo =factoryService.listPage(dto);
dto.setTotal(pageInfo.getTotal());
dto.setPages(pageInfo.getPages());
return ResultSupport.successfy(pageInfo.getList(),dto);
}catch (Exception e){
log.error("查询失败");
return ResultSupport.fail("查询失败");
}
}*/
}
package org.yun.ssm.service;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.yun.ssm.vo.UserVO;
import java.util.List;
public interface UserService {
@RequestMapping("/user/login")
List<UserVO> findAll();
@RequestMapping("/user/findByName")
boolean findByName(@RequestParam("name") String name);
@RequestMapping("/user/add")
void add(@RequestParam("name") String name,@RequestParam("password") String password);
/*
//条件查询
@RequestMapping("/factory/listPage")
PageInfo listPage(@RequestBody FactoryDTO dto);
*/
}
package org.yun.ssm.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.yun.ssm.mapper.UserMapper;
import org.yun.ssm.service.UserService;
import org.yun.ssm.vo.UserVO;
import java.util.List;
import java.util.UUID;
/**
* @ClassName UserServiceImpl
* @Description TODO
* @Autor 落笔丶
* @Date 2019/9/7 22:40
*/
@Service
public class UserServiceImpl implements UserService {
@Autowired(required=true)
UserMapper userMapper;
//此处不是 修改 插入 删除 所以无需加上 事物注解 @Transactional
@Override
public List<UserVO> findAll() {
return userMapper.findAll();
}
@Override
public boolean findByName(String name) {
String userName = userMapper.findByName(name);
if (StringUtils.isEmpty(userName)){
return false;
}
return true;
}
@Override
@Transactional//开始事物注解
public void add(String name, String password){
String uuid = UUID.randomUUID().toString().replace("-", "");
userMapper.add(uuid , name,password);
}
/*
@Override
public PageInfo listPage(@RequestBody FactoryDTO dto) {
PageHelper.startPage(dto.getPageNum(),dto.getPageSize());
List list = factoryMapper.listPage(dto);
return new PageInfo<>(list);
}
*/
}
package org.yun.ssm.mapper;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.SelectProvider;
import org.springframework.stereotype.Repository;
import org.yun.ssm.mapper.prodiver.UserProvider;
import org.yun.ssm.vo.UserVO;
import java.util.List;
@Repository
public interface UserMapper {
/* @Select("SELECT factory_name \n" +
"FROM factory \n" +
"WHERE is_delete = 0 \n" +
"AND factory_name LIKE '%${name}%' \n" +
"ORDER BY updated_time DESC ; ") */
// @SelectProvider(method = "listPage",type = FactoryProvider.class)
// List listPage(@Param("dto") FactoryDTO dto);
// @Select("select * from user")
@SelectProvider(method = "findAll" , type = UserProvider.class)
List<UserVO> findAll();
@Select("SELECT name FROM user WHERE name = #{name} ")
String findByName(@Param("name") String name);
// @Insert("INSERT INTO `moxi`.`news_category` (`id`, `name`, `description`, `image`, `addDate`, `state`) VALUES (null, #{name}, #{description}, #{image}, now(), 0)")
//INSERT INTO `user` VALUES(5,'555','888',666);
@Insert("INSERT INTO `user` VALUES( #{uuid} ,#{name},#{password},666)")
void add(@Param("uuid") String uuid,@Param("name") String name,@Param("password") String password);
// @Update("UPDATE ad_space SET copy_id = #{copyId} WHERE id = #{id}")
}
表示,此处是一个小例子,Github,此文件还有一堆注释的例子,可自行忽略
package org.yun.ssm.mapper.prodiver;
/**
* @ClassName UserProvider
* @Description TODO
* @Autor 落笔丶
* @Date 2019/9/7 22:40
*/
public class UserProvider {
public String findAll(){
StringBuffer sql = new StringBuffer("SELECT * from user ");
return sql.toString();
}
}
(1)index.html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>首页title>
head>
<body>
<h1>~~~落笔丶h1>
<div>
<form action="/user/register" method="post">
用户名:<input type="text" name="name" /> <br/>
密码:<input type="password" name="password" /> <br/>
<button type="submit">注册button>
form>
<br>
<form action="/user/loginEnd" method="post"><br/>
用户名:<input type="text" name="name" /><br/>
密码:<input type="password" name="password" />
<button type="submit" >登录button>
form>
<form action="/user/register2" method="post">
用户名:<input type="text" name="name" /> <br/>
密码:<input type="password" name="password" /> <br/>
<button type="submit">注册2222button>
form>
div>
body>
html>
(2)login,html
<html>
<head>
<meta charset="utf-8">
<title>登录title>
head>
<body>
<form action="" method="get">
登录名:<input type="text" name="name" /> br>
密码:<input type="password" name="password" /> br>
<button type="submit">提交button>
form>
body>
html>
(3)failed.html
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>失败页面title>
head>
<body>
<div>
<span>信息 ModelAndView:span><span th:text="${message}">span>
div>
<form action="/user/index" method="post">
<button type="submit">返回首页button>
form>
body>
html>
解决方法
输入http://localhost:8080/user/index
(1)
因为,数据库已经有此数据了,所以,提示信息是这个
(2)
GitHub源码,请自行切换分支
(一)的基础加上@Slf4J日志输出文件配置
SpringBoot整合SSM+日志配置(@Slf4J)(二)