SpringMVC與分層領域模型設計

本文將與大家一起使用SpringMVC開發獲取前端查詢用戶id查詢用戶信息的功能,其中不僅僅是把數據傳給前端,也會包括一些分層領域設計。

本文接着上一篇文章《SpringBoot快速整合Mybatis以及mybatis-generator的使用》繼續進行設計,爲避免產生疑惑,請先根據上一篇文章配置。本文按照DAO–>service–>Controller順序講解,實際開發可能有所不同。

1 DAO層

上一篇文章中,我們通過mybatis-generator分別生成了6個文件,分別是3對DO數據庫對象類、Mapper接口以及XML配置文件(例如,UserDO–UserDOMapper–UserDOMapper.xml)。

UserDO

public class UserDO {
    private Integer id;
    private String name;
    private Byte gender;
    private Byte age;
    private String telephone;
    private String registerMode;
    private String thirdPartyId;
    // getter and setter
}

UserPasswordDO

public class UserPasswordDO {
    private Integer id;
    private String encrptPassword;
    private Integer userId;
    // getter and setter
}

之前的數據庫設計中,出於安全等考慮,將用戶信息和用戶密碼分成了兩個表來存儲。其實兩者均爲用戶數據,因此我們會返回所有的數據給Service層做業務處理。

單純對於查詢用戶信息這個業務來說,我們分別根據用戶id從兩個表查出用戶基本信息和密碼。UserDO和UserPasswordDO在上一篇文章中創建好,本文沒有改變,僅需對Mapper接口和Mapper.xml做一些配置。

UserMapper接口和XML配置,mybatis-generator已經自動生成。

UserDO selectByPrimaryKey(Integer id);
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
	select 
	<include refid="Base_Column_List" />
	from seckill_user
	where id = #{id,jdbcType=INTEGER}
</select>

UserPasswordMapper接口和XML配置

UserPasswordDO selectByUserId(Integer userId);
<select id="selectByUserId" parameterType="java.lang.Integer" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List"/>
    from seckill_password
    where id = #{userId,jdbcType=INTEGER}
</select>

2 Service層

上節DAO層完成了數據庫數據映射的一些操作。Service層對DAO層數據封裝成Model模型。Model層面纔是真正意義上處理業務的核心模型,而Dataobject僅僅作爲數據庫的映射。

UserModel

public class UserModel {
    private Integer id;
    private String name;
    private Byte gender;
    private Byte age;
    private String telephone;
    private String registerMode;
    private String thirdPartyId;
    private String encrptPassword;
    // getter and setter
}

Service接口–UserService

public interface UserService {
    UserModel getUserById(Integer id);
}

Service接口實現–UserServiceImpl

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDOMapper userDOMapper;

    @Autowired
    private UserPasswordDOMapper userPasswordDOMapper;

    @Override
    public UserModel getUserById(Integer id) {
        UserDO userDO = userDOMapper.selectByPrimaryKey(id);
        if (userDO == null) {
            return null;
        }
        UserPasswordDO userPasswordDO = userPasswordDOMapper.selectByUserId(userDO.getId());
        if (userPasswordDO == null) {
            return null;
        }
        return convertFromDataObject(userDO, userPasswordDO);
    }

    private UserModel convertFromDataObject(UserDO userDO, UserPasswordDO userPasswordDO) {
        UserModel userModel = new UserModel();
        BeanUtils.copyProperties(userDO, userModel);
        // 此處不能用copyProperties()方法,兩個dataobject對象中重複字段id
        userModel.setEncrptPassword(userPasswordDO.getEncrptPassword());

        return userModel;
    }
}

3 Controller層

上節中Service層已經對DAO層數據根據業務需求做了加工,並返回了Model。直接通過Controller層輸出UserModel模型對象,我們會得到下面結果。

啓動SpringBoot服務,訪問http://localhost:8080/user/get?id=1。

{
    "id": 1,
    "name": "首位用戶",
    "gender": 1,
    "age": 18,
    "telephone": "18611001100",
    "registerMode": "bywechat",
    "thirdPartyId": "wechatnum",
    "encrptPassword": "encrptpassword1234"
}

首先,根據用戶id獲取用戶信息的業務需求已經滿足了。但是,這樣做會不規範的,會把不必要或者不安全的數據返回給前端,例如後三個字段:登錄方式、用戶第三方ID、用戶密碼,既沒有必要,還可能帶來風險。因此,我們需要在Controler層在Service層返回Model對象的基礎上再封裝一層對象VO。

UserVO

public class UserVO {
    private Integer id;
    private String name;
    private Byte gender;
    private Byte age;
    private String telephone;
    // getter and setter
}

UserController 代碼實現

@Controller("user")
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping("/get")
    @ResponseBody
    public UserVO getUser(@RequestParam(name = "id") Integer id) {
        // 調用service服務獲取對應id的用戶對象並返回給前端
        UserModel userModel = userService.getUserById(id);

        // 將核心領域模型用戶對象轉化爲可供UI使用的viewObject
        return convertFromModel(userModel);
    }

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

4 測試運行

此時,我們已經完成了DAO層、Service層、Controller層代碼開發,代碼目錄結構如下。
在這裏插入圖片描述
啓動SpringBoot服務,訪問http://localhost:8080/user/get?id=1 ,得到如下對象。

{
    "id": 1,
    "name": "首位用戶",
    "gender": 1,
    "age": 18,
    "telephone": "18611001100"
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章