Ok,现在开始做一个入门的登录注册demo,还没有创建springboot项目的同学可以看下我的这篇文章
https://blog.csdn.net/weixin_43408112/article/details/106316274
在开始之前,需要明白几个概念:
Web层:也叫做应用层,存放控制器controller,应用层是后台的最外层,也是直接与前端交互的地方。
Service层:服务层也是我们的业务层,处理业务逻辑。
Dao层:也叫Mapper层,用于和数据库打交道的。
Bean层:实体层,用于存放各种类型的实体。
那么先创建一下package,大致结构如下:
这里有两个service包,一个存放服务层代码的接口(service),一个存放接口实现类(serviceImpl)。
先写一个简单的html页面看看效果,命名为index.html放到recourses的templates里面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hello</title>
</head>
<body>
Hello springboot!
</body>
</html>
创建一个控制器IndexController放到controller包下面,并且添加注解@Controller
package com.example.login.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class IndexController {
@RequestMapping("/index")
public String index(){
return "index";
}
}
@RequestMapping代表请求路径是"/index",所有请求方法都允许时,访问这个controller,return的就是刚刚写的html视图
然后启动
浏览器访问成功!
本地新建一个表user,设置id为自增主键。(记得修改application.yml中的datasource配置信息)
新建一个实体,对应表user
package com.example.login.bean;
public class User {
private int id;
private String username;
private String password;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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开始,因为上层要对下层进行依赖注入
新建LoginDao,添加注解@Mapper和@Repository
登录注册的数据库接口如下:
package com.example.login.dao;
import com.example.login.bean.User;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface LoginDao {
/**
* 注册
* @param user
*/
@Insert("insert into user(username,password) values(#{username},#{password})")
@Options(useGeneratedKeys = true, keyProperty = "id")
void register(User user);
/**
* 登录
* @param username
* @param password
* @return
*/
@Select("select * from user where username=#{username} and password=#{password}")
User login(@Param("username")String username,@Param("password")String password);
}
我们把SQL语句写到注解里面如@Insert和@Select,其中参数用#{username},这种方式可以有效的防止SQL注入。mybatis有两种插入参数的方式,一种是Bean,如上面register方法的形参User,这种方式要求username和password都必须是User的属性,并且已经实现了get和set方法;第二种就如login方法是用@Parma来定义,小括号里面的username代表上面sql语句中#{username},即要插入的实参,外面的username是形参名称。
register方法还有一个注解@Options,第一个属性useGeneratedKeys是指使用数据表定义好的自增主键(也就是我上面的id),keyColumn用于指定数据库table中的主键(如果我们已经在数据库表中指定了主键,那么keyColumn属性可以缺省),keyProperty用于指定传入对象user的成员变量。也就是说,使用数据库自动增长的主键,并从table中id字段里面把数据放到传入对象user的成员变量id里面。
好了,Dao层就到这里,接下来配置Service层,先定义接口LoginService
在这儿我们再创建一个专门用于返回的实体Result,因为业务中多要求采用json数据格式来传送,所以一般返回一个对象会好一些
package com.example.login.bean;
public class Result {
private String status; //状态码
private String msg; //返回信息
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
现在定义一下登录注册接口,方法的返回值就是上面的Result实体
package com.example.login.service;
import com.example.login.bean.Result;
public interface LoginService {
Result register(String username,String password);
Result login(String username,String password);
}
然后我们需要实现接口
package com.example.login.serviceImpl;
import com.example.login.bean.Result;
import com.example.login.bean.User;
import com.example.login.dao.LoginDao;
import com.example.login.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Transactional(rollbackFor = RuntimeException.class)
@Service
public class LoginServiceImpl implements LoginService {
@Autowired
private LoginDao loginDao;
@Override
public Result register(String username, String password) {
Result result = new Result();
User user= new User();
user.setUsername(username);
user.setPassword(password);
try{
//先检查该用户是否被注册过
User user2 = loginDao.login(username,password);
if(user2 != null){
result.setMsg("该用户已被创建");
result.setStatus("400");
return result;
}
//没被创建过就注册
loginDao.register(user);
result.setMsg("注册成功");
result.setStatus("200");
} catch (Exception e) {
e.printStackTrace();
result.setMsg(e.getMessage());
result.setStatus("400");
}
return result;
}
@Override
public Result login(String username, String password) {
Result result = new Result();
User user;
try{
user = loginDao.login(username,password);
if(user == null){
result.setMsg("用户名或者密码错误");
result.setStatus("400");
return result;
}
result.setMsg("登录成功");
result.setStatus("200");
} catch (Exception e) {
e.printStackTrace();
result.setMsg(e.getMessage());
result.setStatus("400");
}
return result;
}
}
这里就可以看到,我们对下层的LoginDao进行了自动依赖注入@Autowired,并且为了能让系统识别我们需要在实现类上面加上@Service告诉它这是service层;@Transactional(rollbackFor = RuntimeException.class)这个注释是指发生运行时异常时事务要进行回滚。
然后就开始创建控制器了,加上@RestController的目的就是为了满足能够返回json数据格式
package com.example.login.controller;
import com.example.login.bean.Result;
import com.example.login.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class LoginController {
//将Service注入Web层
@Autowired
LoginService loginService;
@PostMapping("/register")
Result register(String username,String password){
return loginService.register(username,password);
}
@PostMapping("/login")
Result login(String username,String password){
return loginService.login(username,password);
}
}
这里同样可以看到,controller对下层的service进行了自动依赖注入,而@PostMapping可以根据实际请求方式来替换,比如@PutMapping,@GetMapping…,里面写的是请求路径,而返回结果呢?当然就交给业务层loginService去处理了呗。
后台就搭建完成了,我们还需要两个简单的视图
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>login</title>
</head>
<body>
<form role="form" action = "/login" method="post">
账号:<input type="text" id="username" name = "username"> <br>
密码:<input type="password" id = "password" name = "password"> <br>
<input type="submit" id = "login" value = "login">
</form>
</body>
</html>
register.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>register</title>
</head>
<body>
<form role="form" action = "/register" method="post">
账号:<input type="text" id="username" name = "username"> <br>
密码:<input type="password" id = "password" name = "password"> <br>
<input type="submit" id = "register" value = "register">
</form>
</body>
</html>
在访问页面之前,正如前面访问index.html那样,我们还需要配置视图解析器。这是因为springboot项目默认是不允许直接访问templates下的文件的,是受保护的。
还是在之前这个IndexController里面配置,这里为了不和后台的接口路径冲突,我把访问路径设置成了userLogin和userRegister
package com.example.login.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class IndexController {
@RequestMapping("/index")
public String index(){
return "index";
}
@GetMapping("/userLogin")
public String login(){
return "login";
}
@GetMapping("/userRegister")
public String register(){
return "register";
}
}
运行测试一下
注册:
结果:
表里面有新增的记录
登录:
OK。到这里登录注册就成功了,是不是很简单?会了登录注册,其他的业务逻辑大体上也都差不多哟。