Idea+Maven+springboot+Mybatis 创建web项目教程(4):创建MVC各分层,完成数据贯穿流程

前三篇:

Idea+Maven+springboot+Mybatis 创建web项目教程(1):环境搭建与配置

Idea+Maven+springboot+Mybatis 创建web项目教程(2):集成Mybatis

Idea+Maven+springboot+Mybatis 创建web项目教程(3):使用Mybatis自动生成器接通数据库

一般的web开发都会用到MVC(Mode,View和Controller)三层来进行构建项目。

前三篇文章已经借用springboot走通了一个简单的流程,但是后台的逻辑不清晰,只是能够连通向前台输出内容,现在开始构建完整的一个标准结构。

一、组织SpringMVC层级结构

在com.miaoshaproject目录下,平行于dao层和dataobject层,创建controller和service目录。

在这里插入图片描述
可以看到,除了serveice和controller,我们在这两个包的路径下面分别又创建了impl,model和viewobject。

解释一下:

  1. service是提供服务的,

    1. 直接在service下的是接口,

    2. impl包里专门存放对应service接口的实现类,

    3. model里面存放的是数据模型,是业务逻辑层面需要的数据模型

      (这里的体会,感觉MVC的分层在很多时候有些模棱两可,比如model层怎么就放到service下面了呢?)

  2. controller层就是控制层,

    1. 下面的viewojbect是提供给前端展示的数据类,因为后端的业务数据直接送给前端是不合适的,要经过挑选重新封装。
    2. dataobject就是纯数据,后端封装的对应于数据库里数据的对象;
  3. dao层就是数据访问,是mapper类,因为对数据访问的操作,我们写出mapper,映射到mapping目录下面的xml文件,从那里面根据对应的属性来获取元素,而那些文件里面有sql代码,有这种模式代码的快速生成是依赖于mybatis。

现在搞不清楚没关系,继续往下看,等到代码有了之后,可以看到他们的依赖关系.

二、以用户为例,创建对应的controller



//指定一个user的标记,这样才能被spring扫描到
@Controller("user")
//指定在url上面需要通过/userf访问到他
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping("/get")
    @ResponseBody
    public UserModel getUser(@RequestParam(name = "id")Integer id){
        //调用service服务获取对应的用户id对象并返回给前台
        UserModel userModel=userService.getUserById(id);
        return userModel;
    }
}

controller 调用了userService的服务。(1)

那我们来看 userService(2)

//用service标记指定这就是对应的service
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDOMapper userDOMapper;
    @Autowired
    private UserPasswordDOMapper userPasswordDOMapper;
    @Override
    public UserModel getUserById(Integer id) {
        //调用userDOMapper获取到,而不能将获取到的userdo给前端,需要改为用model
        UserDO userDO = userDOMapper.selectByPrimaryKey(id);
        if(userDO==null){
            return null;
        }
        //对于password,mybatis自动生成的select方法是没有需要的,所以对应的select方法是我们自己在mapper.xml文件里增加的
        UserPasswordDO userPasswordDO=userPasswordDOMapper.selectByUserId(userDO.getId());
        return convertFromDataObject(userDO,userPasswordDO);
    }

    //通过两个数据do组成一个需要的model数据类型
    private UserModel convertFromDataObject(UserDO userDO, UserPasswordDO userPasswordDO){
        if(userDO ==null){
            return  null;
        }
        UserModel userModel=new UserModel();
        BeanUtils.copyProperties(userDO,userModel);//将userDo的属性都copy
        if (userPasswordDO !=null){
            userModel.setEcrptPassword(userPasswordDO.getEncrptPassword());//因为有重复名,只能set一个
        }
        return  userModel;
    }
}

上面的代码,除了注解的内容,其他都不属于spring的新知识,应该可以看懂。

userService 的返回值是一个 userModel(3) ,这是我们自己在业务逻辑层生成的对象类型,他是由 userDo 和 userPasswordDo 组成的,那么 userMOdel 这个类怎么实现的?

private Integer id;
private String name;
private Byte gender;
private Integer age;
private String telephone;
private String registerMode;
private String thirdPartyId;


//虽然这个字段不是数据库访问出来的直接object里含有的,但是在业务层面我们就是视为同一个用户应该有的属性
private String ecrptPassword;

就是一堆属性,注意,这里面的字段必须和 userDo 和 userPasswordDo 的保持一致(至少类型肯定要一致,名称肯定一致会方便,也不会出现别的问题)。

那么在service里面,userDO 和 userPasswordDo 获取的方式是利用他们两个对应的userDoMapper 和 userpasswordDOmapper 执行对应的查询方法。

而这两个文件里面只是接口,他们真正实现是靠映射到 userpomapper.xml 和userPasswordDOmapper.xml 文件里的 sql 语句。(这是之前的内容)

现在是不是有些明白这几个层目录之间的调用关系了!!!!

我个人的理解就是,controller层离得和浏览器最近,控制在最前。controller会调用service,service是核心的业务逻辑,service使用的数据则是来自于dataobject,而dataobject的获取需要dao层和数据库进行交互。

三、测试

在controller的直接业务逻辑里面,我们指定了访问用/user和/get

这种简便方式,我们现在可以在浏览器进行尝试访问。

http://localhost:8090/user/get?id=1

直接会返回 id = 1 (实际数据库对应的是user_id)的那个用户的所有信息,作为一个userModel展示了条数据在网页里。

在这里插入图片描述

四、修改controller层

后端的处理显然是不合理的,因为我们自己业务用来操作的model,直接返给前端。

而且那条信息里还包含了用户的密码。

在前面我们已经新建出来了viewobject,这个时候就可以用它。

再viewobjec创建userVo类,创建属性和对应的getset方法,这里的属性也就是从userModel复制过来的,但是进行筛选,也就是希望在前台展示的部分只有这几个。

private Integer id;
private String name;
private Byte gender;
private Integer age;
private String telephone;

然后在controller主方法里面做对应的修改。

@RequestMapping("/get")
@ResponseBody
public UserVO getUser(@RequestParam(name = "id")Integer id){
    //调用service服务获取对应的用户id对象并返回给前台
    UserModel userModel=userService.getUserById(id);
    //用下面的方法将领域对象处理为给用户展示的模型数据
    return convertFromModel(userModel);
}

public UserVO convertFromModel(UserModel userModel){
    if(userModel==null){
        return  null;
    }
    UserVO userVO=new UserVO();
    BeanUtils.copyProperties(userModel,userVO);
    return userVO;
}

也就是说,在这里多了一个步骤,经过下层的所有操作之后,得到的数据经过简单的copy直接放到了另一个我们定义好的userVO模型里面,返回给前端。

到这里,数据访问,经过MVC三层的处理已经结束,这个练习是对数据库中的数据访问操作、直接读取给前端。

如果接受到前端的数据,读取处理之后再封装成下层的dataobject类,通过dao层再调用对应mapper.xml里的sql去重新写回数据库也是一样的流程。

接下来的业务操作只是在其中进行添加,我也要开始继续学习啦,因此这个主题的博客更新到此为止,完结撒花

猜你喜欢

转载自blog.csdn.net/weixin_42092787/article/details/107008802