
CREATE TABLE t_user (
uid INT AUTO_INCREMENT COMMENT '用户id',
username VARCHAR(20) NOT NULL UNIQUE COMMENT '用户名',
password CHAR(32) NOT NULL COMMENT '密码',
salt CHAR(36) COMMENT '盐值',
phone VARCHAR(20) COMMENT '电话号码',
email VARCHAR(30) COMMENT '电子邮箱',
gender INT COMMENT '性别:0-女,1-男',
avatar VARCHAR(50) COMMENT '头像',
is_delete INT COMMENT '是否删除:0-未删除,1-已删除',
created_user VARCHAR(20) COMMENT '日志-创建人',
created_time DATETIME COMMENT '日志-创建时间',
modified_user VARCHAR(20) COMMENT '日志-最后修改执行人',
modified_time DATETIME COMMENT '日志-最后修改时间',
PRIMARY KEY (uid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
public class BaseEntity implements Serializable {
private String createdUser ;
private Date cratedTime ;
private String modifiedUser ;
private Date modifiedTime ;
}
public class User extends BaseEntity implements Serializable {
private Integer uid;
private String username;
private String password;
private String salt;
private String phone;
private String email;
private Integer gender;
private String avatar;
private Integer isDelete;
}
通过MyBatis来操作数据库。在做mybatis开发的流程。
1.用户的法册功能,相当于在做数据的插入操作。
2.在用户的注册时首先要去查询当前的用户名是否存在,如果存在则不能进行注册。相当于是一 条查询语句
定义Mapper接口。在项目的目录结构下首先创建一个mapper包, 在这个包下再根据不同的功能模块来创建mapper接口。创建一个UserMapper的接口。 要在接口中定义这两个SQL语句抽象方法。
/*登录用户持久层*/
public interface UserMapper {
//插入
Integer insertUser(User user);
//查询
User findByUsername(String username);
}
ssm框架开发项目的时候需要在mapper接口上加@Mapper用于自动生成相应的接口实现类,在springboot也可以这样,但是后续会有很多mapper接口,每个接口分别加@Mapper太麻烦了,所以在启动类类里面指定当前项目的mapper接口在哪,然后项目启动的时候会自动加载所有的接口
@MapperScan("com.sdjzu.store.mapper")

定义xm|映射文件,与对应的接口进行关联。
1.定义xml映射文件,与对应的接口进行关联。所有的映射文件需要防止resources目录下,在这个目录下创建一
个mapper文件夹,然后在这个在这个文件夹在存放法Mapper的映射文件。
2.创建接口对应的映射文件,遵循和接口的名称保持一 致即可。创建一 个UserMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sdjzu.store.mapper.UserMapper">
mapper>
3.配置接口中的方法对应上SQL语句上。需要借助标签来完成,insert\update\deletelselect, 对应的是SQL语句
的增删改查操作。
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sdjzu.store.mapper.UserMapper">
<resultMap id="UserEntityMap" type="com.sdjzu.store.entity.User">
<id column="uid" property="uid">id>
resultMap>
<insert id="insertUser">
INSERT INTO t_user (
uid,username,password,salt, phone,email,gender,avatar,is_delete,
created_user,created_time,modified_user ,modified_time
)VALUES(
#{uid},#{username},#{password},#{salt}, #{phone},#{email},#{gender},#{avatar},
#{isDelete},#{createdUser},#{cratedTime},#{modifiedUser} ,#{modifiedTime}
)
insert>
<select id="findByUsername" resultMap="UserEntityMap" >
SELECT * FROM t_user WHERE username=#{username}
select>
mapper>
mybatis.mapper-locations=classpath:mapper/*.xml
package com.sdjzu.store.mapper;
import com.sdjzu.store.entity.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@SpringBootTest
@RunWith(SpringRunner.class)
public class UserMapperTests {
@Autowired
private UserMapper userMapper;
@Test
public void insert(){
User user = new User();
user.setUsername("lisi");
user.setPassword("123");
Integer rows = userMapper.insertUser(user);
System.out.println(rows);
}
@Test
public void findByUsername(){
User lisi = userMapper.findByUsername("lisi");
System.out.println(lisi);
}
}
业务层的核心功能:
接受前端从控制器流转过来的数据
结合真实的注册业务来完成功能业务逻辑的调转和流程
所以这里要考虑到真实的业务场景,如果只考虑业务场景的话不完整,因为在整个业务执行的过程中会产生很多问题,从java角度来讲这些都是属于异常,所以在业务开发的时候就要规划相关的异常,以便把项目的错误控制在一定范围内
service下的目录结构(建议这样):
service包下创建ex包用来写异常类
service包下创建impl包用来写接口的实现类
接口直接写在service包下,不再需要接口包
1.为什么会有异常:
比如,用户在进行注册时可能会产生用户名被占用的错误,这时需要抛出一个异常
2.怎么处理异常:
异常不能用RuntimeException,太笼统了,开发者没办法第一时间定位到具体的错误类型上,我们可以定义具体的异常类型来继承这个异常.
正常的开发中异常又要分等级,可能是在业务层产生异常,可能是在控制层产生异常,所以可以创建一个业务层异常的基类,起名ServiceException异常,并使其继承RuntimeException异常
后期开发业务层时具体的异常可以再继承业务层的异常ServiceException
3.处理异常的具体步骤:
①在ex包下创建ServiceException类作为业务层异常的基类:
package com.sdjzu.store.service.ex;
public class ServiceException extends RuntimeException{
public ServiceException() {
super();
}
public ServiceException(String message) {
super(message);
}
public ServiceException(String message, Throwable cause) {
super(message, cause);
}
public ServiceException(Throwable cause) {
super(cause);
}
protected ServiceException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
根据业务层不同的功能来详细定义 具体的异常的类型,统-的去继承ServiceException异常类。
②用户在进行注册时候可能会产生用户名被占用的错误,抛出一个异常: UsernameDuplicatedException异常
package com.sdjzu.store.service.ex;
public class UsernameDuplicatedException extends ServiceException{
public UsernameDuplicatedException() {
super();
}
public UsernameDuplicatedException(String message) {
super(message);
}
public UsernameDuplicatedException(String message, Throwable cause) {
super(message, cause);
}
public UsernameDuplicatedException(Throwable cause) {
super(cause);
}
protected UsernameDuplicatedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
③.正在执行数据插入操作的时候,服务器、数据库宕机。处于正在执行插入的过程中所产生的异常
InsertException异常
package com.sdjzu.store.service.ex;
public class InsertException extends ServiceException{
public InsertException() {
super();
}
public InsertException(String message) {
super(message);
}
public InsertException(String message, Throwable cause) {
super(message, cause);
}
public InsertException(Throwable cause) {
super(cause);
}
protected InsertException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
1.在service包下创建一个IUserService接口。
package com.sdjzu.store.service;
import com.sdjzu.store.entity.User;
public interface IUserService {
void reg(User user);
}
2.创建一个实现类UserServicelmpl类, 需要实现这个接口,并且实现抽象方法。
package com.sdjzu.store.service.impl;
import com.sdjzu.store.entity.User;
import com.sdjzu.store.mapper.UserMapper;
import com.sdjzu.store.service.IUserService;
import com.sdjzu.store.service.ex.InsertException;
import com.sdjzu.store.service.ex.UsernameDuplicatedException;
import org.springframework.beans.factory.annotation.Autowired;
import javax.xml.crypto.Data;
import java.util.Date;
public class UserServiceImpl implements IUserService {
@Autowired
private UserMapper userMapper;
@Override
public void reg(User user) {
String username = user.getUsername();
User result= userMapper.findByUsername(username);
if(result != null){
throw new UsernameDuplicatedException("用户名占用");
}
user.setIsDelete(0);
user.setCreatedUser(user.getUsername());
user.setModifiedUser(user.getUsername());
Date date = new Date();
user.setCratedTime(date);
Integer rows = userMapper.insertUser(user);
if(rows!=1){
throw new InsertException("服务器宕机");
}
}
}
package com.sdjzu.store.service;
import com.sdjzu.store.entity.User;
import com.sdjzu.store.mapper.UserMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@SpringBootTest
@RunWith(SpringRunner.class)
public class UserServiceTests {
@Autowired
private IUserService iUserService;
@Test
public void reg(){
User user = new User();
user.setUsername("zyj");
user.setPassword("123");
iUserService.reg(user);
System.out.println("ok");
}
}
状态码、状态描述信息、数据。这部分功能封装一个类中, 将这类作为方法返回值,返回给前端浏览器。
package com.sdjzu.store.util;
import java.io.Serializable;
public class JsonResult<E> implements Serializable {
private Integer state;
private String message;
private E data;
public JsonResult() {
}
public JsonResult(Integer state) {
this.state = state;
}
public JsonResult(Throwable e) {
this.message = e.getMessage();
}
public JsonResult(Integer state, E data) {
this.state = state;
this.data = data;
}
public Integer getState() {
return state;
}
public void setState(Integer state) {
this.state = state;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public E getData() {
return data;
}
public void setData(E data) {
this.data = data;
}
}
依据当前的业务功能模块进行请求的设计。
请求路径: /users/reg
请求参数: User user
请求类型: POST
响应结果: JsonResult
1.创建一个控制层对应的类UserController类。依赖于业务层的接口。
package com.sdjzu.store.controller;
import com.sdjzu.store.entity.User;
import com.sdjzu.store.service.IUserService;
import com.sdjzu.store.service.ex.InsertException;
import com.sdjzu.store.service.ex.UsernameDuplicatedException;
import com.sdjzu.store.util.JsonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("user")
public class UserController {
@Autowired
private IUserService iuserService;
@RequestMapping("reg")
public JsonResult<Void> reg(User user){
JsonResult jsonResult = new JsonResult<>();
try {
iuserService.reg(user);
jsonResult.setState(200);
jsonResult.setMessage("用户注册成功");
} catch (UsernameDuplicatedException e) {
jsonResult.setState(4000);
jsonResult.setMessage("用户名已经存在");
}catch (InsertException e){
jsonResult.setState(5000);
jsonResult.setMessage("插入失败");
}
return jsonResult;
}
}
1.将项目进行启动起来

2.浏览器输入url地址
http://localhost:8080/user/reg?username=tom&password=1223

3.数据库的检查

因为控制层的方法要处理异常,所以用一个BaseController类作为父类
package com.sdjzu.store.controller;
import com.sdjzu.store.service.ex.InsertException;
import com.sdjzu.store.service.ex.UsernameDuplicatedException;
import com.sdjzu.store.util.JsonResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
public class BaseController {
public static final int ok=200;
@ExceptionHandler
public JsonResult<Void> handleException(Throwable e){
JsonResult<Void> objectJsonResult = new JsonResult<>(e);
if(e instanceof UsernameDuplicatedException){
objectJsonResult.setState(4000);
objectJsonResult.setMessage("用户重名");
}else if(e instanceof InsertException){
objectJsonResult.setState(5000);
objectJsonResult.setMessage("插入失败");
}
return objectJsonResult;
}
}
继承之后的注册的控制层
@RequestMapping("reg")
public JsonResult<Void> reg(User user){
iuserService.reg(user);
return new JsonResult<>(ok);
}
<script>
$("#btn-reg").click(function(){
$.ajax({
url:"/user/reg",
type:"POST",
data:$("#form-reg").serialize(),
dataType:"JSON",
success:function(json){
if(json.state=200){
alert("注册成功")
}else {
alert("注册失败")
}
},
error:function(xhr){
alert("未知错误"+xhr.status)
}
})
})
</script>
