实现登录和注册功能【springboot mybatis学习与开发(三)】

来源:互联网 发布:淘宝售后服务怎么做 编辑:程序博客网 时间:2024/05/23 07:23

前面两篇文章,我写了如何建立一个简单的Web项目,现在我们开始一点点地添加功能

1、功能说明

添加一个登录的功能和用户注册的功能,用户来到登录界面,输入账号密码,输入正确则登录成功,否则登录失败。简单吧!登录可以使用到ajax技术,即做到页面不刷新的情况下,与后台交互。账号一开始是没有的,可以通过注册来申请个,同时数据库的用户名采用了唯一键约束,可以用此来判断是否已经存在的用户。

2、业务模型层Model

2.1、UserDao

在UserDao接口中增加方法selectById和insert

public interface UserDao {    //省略部分代码    /**     * 根据用户名查询,用作检查注册     * @param user     * @return     */    User selectByUsername(User user);    /**     * 根据用户名和密码查询用户,用作检查登录     * @return 用户     */    User selectByUsernameAndPassword(User user);    /**     * 插入一个用户     * @param user     */    void insert(User user);    /**     * 根据删除用户     * @param id     */    void deleteById(Integer id);}

2.2、UserService以及实现

给出服务实现类部分代码即可:

@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT)@Service("userService")public class UserServiceImpl implements UserService{    @Autowired    UserDao userDao;    @Override    public void deleteUserById(Integer id) {        userDao.deleteById(id);    }    @Transactional(readOnly=true)    @Override    public User checkLogin(User user) {        return userDao.selectByUsernameAndPassword(user);    }    @Override    public User checkRegist(User user) {        return userDao.selectByUsername(user);    }}

这里加入了@Transactional注解,propagation表示事务的传播级别,如果有事务就处于当前事务,没有就创建一个;isolation表示隔离级别,采用默认级别。

2.3、UserMapper.xml映射文件

    <select id="selectByUsername" parameterType="User" resultType="User">        select * from t_user where username = #{username}    </select>    <select id="selectByUsernameAndPassword" parameterType="User" resultType="User">        select * from t_user where username = #{username} and password = #{password}    </select>    <insert id="insert" parameterType="User" useGeneratedKeys="true"        keyProperty="id">        insert into        t_user(username,password,email) values        (#{username},#{password},#{email})    </insert>    <delete id="deleteById" parameterType="int">        delete from        t_user        where id = #{id}    </delete>

userGeneratedKeys和keyProperties属性用来和自动生成的主键相互对应,
string和int是别名,和javaType类型的String和Integer相互对应,参考mybatis的typeAliases,然后再由typeHandler映射对应的jdbcType。

3、测试UserService

在写控制器之前,现在入口的测试类中测试UserService是否能完成服务

public class MyblogApplicationTests {    @Autowired    UserService userService;    //省略了部分代码    @Test    public void testInsert(){        User user = new User("test","test","test");        userService.addUser(user);        System.out.println(userService.checkLogin(user));        userService.deleteUserById(user.getId());    }}

在testInsert()方法中,先添加后,再检查登录,最后再删除记录,一举三得。
可见测试无异常
image

4、控制层Controller

在控制层中,只需要处理请求,完成服务,不应该有底层的dao,所以才需要service。
在UserController中添加请求处理

4.1登录请求

    @RequestMapping("/user/login")    @ResponseBody    public Boolean loginUser(@RequestBody User user, Model model) {        Boolean result = false;        if (userService.checkLogin(user) != null) {            model.addAttribute("user", user);            result = true;        }        return result;    }

这里使用了@ResponseBody注解表示返回数据,而不返回界面,将数据存储在response中。@RequestBody表示获取前端存储在request中的数据。为什么使用这两个注解呢?因为前端需要使用ajax技术,使用JSON数据格式来传送参数,那么就必须使用这两个注解。

4.2、注册请求

    @RequestMapping("/user/regist")    @ResponseBody    public Boolean registUser(@RequestBody User user, Model model) {        Boolean result = false;        if (userService.checkRegist(user) == null) {            userService.addUser(user);            model.addAttribute("user", user);            result = true;        }        return result;    }

这里需要先用checkRegist判断,即判断用户名是否存在。

5、视图层View

首先在template文件夹下建立loginForm,registForm。这两个页面代码就不贴了,很简单的输入表单。在static文件夹下放入jQuery文件,以及自己写的user.js

5.1、user.js

这个脚本文件,主要是发送ajax请求,很关键,代码如下

function checkLogin() {    var username = $("#username").val();    var password = $("#password").val();    var param = {        "username" : username,        "password" : password    }    $.ajax({        url : "/user/login",        type : "POST",        contentType : "application/json",        dataType : "json",        data : JSON.stringify(param),        async : true,        success : function(data) {            if (data) {                alert("恭喜你 " + username + " 登录成功");                location.href = "/user/showAllUser";            } else {                alert("用户名或密码错误!");            }        }    });}function checkRegist() {    var username = $("#username").val();    var password = $("#password").val();    var email = $("#email").val();    var param = {        "username" : username,        "password" : password,        "email" : email    }    $.ajax({        url : "/user/regist",        type : "POST",        contentType : "application/json",        dataType : "json",        data : JSON.stringify(param),        async : true,        success : function(data) {            if (data) {                alert("恭喜你 " + username + " 注册成功");                location.href = "/user/toLoginForm";            } else {                alert("用户名存在:注册失败!");            }        }    });}

5.1.1、细节1

这里需要注意的是contentType : “application/json”和dataType : “json”和控制器的@ResponseBody,@RequestBody对应。data : JSON.stringify(param),这条语句很关键,也很坑爹,这是传递的参数,需要将param使用此方法,param是JSON对象,使用此方法之后,会变为json对象字符串。参考博客JSON.stringify详解

5.1.2、细节2

url : “/user/login”和
location.href = “/user/showAllUser”这两个都要和控制器中的访问路径对应,这样能够确保不会出现404错误,这都正好对应了,就不可能有错,一定要注意。另外,我们并没有直接的路径访问loginForm和registForm,这里就需要添加如下配置

5.2、添加WebMvcConfig

虽然Spring Boot为我们自动配置了默认的视图解析器,但有的时候还是不够用的,这里我们需要直接访问表单页面,我们需要加入如下配置类WebMvcConfig继承WebMvcConfigurerAdapter类。

@Configurationpublic class WebMvcConfig extends WebMvcConfigurerAdapter {    @Override    public void addViewControllers(ViewControllerRegistry registry) {        registry.addViewController("/user/toLoginForm").setViewName("loginForm");        registry.addViewController("/user/toRegistForm").setViewName("registForm");    }}

这样我们就可以访问登录页面啦,这里不要使用@EnableWebMvc,若使用了,则会覆盖boot提供的自动配置。

5.3、结果展示

5.3.1、注册

image

5.3.2、登录

image

5.3.3、登录之后

image
你会发现神奇的事情,为什么编号是3,因为在这之前可能从数据库删除了编号为2的数据,但是主键增长不会倒退,这是需要自己手动在数据库中设置增长键的初始值

alter table t_user auto_increment = 2;

这条语句的规则很有意思,如果这个值是倒退的,即后面编号还有数据存在数据库中,那么设置是无效的。这也是我所考虑的问题,并没有解决,先记着吧。

6、心得体会

结合前两篇文章,理解这篇的操作,还是没有什么问题的,主要就是细节的处理。特别是采用了ajax技术,要注意参数的传递,以及@RequestBody和@ResponseBody的用法。最后,完成了登录和注册功能。

1 0