Java中Vo类的理解

365app下载安装官方免费下载 📅 2025-08-17 18:30:18 👤 admin 👁️ 5878 ❤️ 829
Java中Vo类的理解

先来解释两个概念

实体类(持久对象)=PO

值对象(新的对象)=VO

代码语言:javascript代码运行次数:0运行复制一、PO:persistant?object?持久对象

可以看成是与数据库中的表相映射的java对象。使用Hibernate来生成PO是不错的选择。

二、VO:value object值对象。

通常用于业务层之间的数据传递,和PO一样也是仅仅包含数据而已。但应是抽象出的业务对象

可以和表对应,也可以不,这根据业务的需要.

有一种观点就是:PO只能用在数据层,VO用在商业逻辑层和表示层。各层操作属于该层自己的数据对象

这样就可以降低各层之间的耦合,便于以后系统的维护和扩展。

如果将PO用在各个层中就相当于我们使用全局变量,我们知道在OO设计非常不赞成使用全局变量。

但是每次都得进行VO-PO的转换,也确实很烦。我觉得有时候也可以在某个商业逻辑或者表示层使用PO

此时在这个商业逻辑的过程中PO的状态是不发生变化的,比如显示一条商品详细信息的商业逻辑。

在开发过的项目中,规模都很小,我一直都把PO当VO用,因为PO确实很方便,结合Hibernate的DAO

我使用JAVA的集合对象作为值传递的载体,当然Struts也是我的不二之选。

我认为:在一些直观的,简单的,不易发生变化的,不需要涉及多个PO时,传递值还是使用PO好

这样可以减少大量的工作量(也就意味着减少bug,减少风险),也不需要担心未来的维护工作!

vo:value object,值对象

一般在java中用的多的是pojo:plain oriented java object

原始java对象,pojo一般和数据库中的表是一一对应的。

vo一般是来做值的存储与传递。

既然有了实体类与数据库中的字段一一对应了 那为什么还要VO呢

答案是因为在复杂的业务逻辑中,往往单一实体类无法满足我们的需求,就举个简单的例子,一个课程系统中有一级分类和二级分类,那么一个一级分类应该会对应多个二级分类,如果我们使用二级菜单的话,就应该可以实现这种联动的效果,一旦一级菜单确定下来了,那么二级菜单的下拉项中的选项只能是一级菜单下的二级菜单,也许有点绕 发证大意就是需要做到 一对多

一个一级菜单对应多个二级菜单

下面就来一个例子吧,首先有一个在线课堂的项目中有一个分类表

我们先看一下表结构

id就是主键

titie是名称

那么parentId就是上级分类的ID 如果值为0则为一级分类 如果为其他

Springboot中的实体类PO:

代码语言:javascript代码运行次数:0运行复制package cn.tompro.eduservice.entity;

import com.baomidou.mybatisplus.annotation.FieldFill;

import com.baomidou.mybatisplus.annotation.IdType;

import java.util.Date;

import com.baomidou.mybatisplus.annotation.TableField;

import com.baomidou.mybatisplus.annotation.TableId;

import java.io.Serializable;

import io.swagger.annotations.ApiModel;

import io.swagger.annotations.ApiModelProperty;

import lombok.Data;

import lombok.EqualsAndHashCode;

import lombok.experimental.Accessors;

/**

*

* 课程科目

*

*

* @author testjava

* @since 2022-07-12

*/

@Data

@EqualsAndHashCode(callSuper = false)

@Accessors(chain = true)

@ApiModel(value="EduSubject对象", description="课程科目")

public class EduSubject implements Serializable {

private static final long serialVersionUID = 1L;

@ApiModelProperty(value = "课程类别ID")

@TableId(value = "id", type = IdType.ID_WORKER_STR)

private String id;

@ApiModelProperty(value = "类别名称")

private String title;

@ApiModelProperty(value = "父ID")

private String parentId;

@ApiModelProperty(value = "排序字段")

private Integer sort;

@ApiModelProperty(value = "创建时间")

@TableField(fill = FieldFill.INSERT)

private Date gmtCreate;

@ApiModelProperty(value = "更新时间")

@TableField(fill = FieldFill.INSERT_UPDATE)

private Date gmtModified;

}

但是 正如我在前面说到过的 这种单一实体类 是满足不了我们的需求的

因为例如下图中的需求

我们选中一个一级分类之后 那么下一个下拉列表中的选项只能是 已选中的一节分类下的对应的二级分类

是会有一个联动的反应,所以我们的单一实体类就不能做到了。

这时候,引入我们的Vo类

首先新建一级分类Vo类

代码语言:javascript代码运行次数:0运行复制package cn.tompro.eduservice.entity.subject;

import lombok.Data;

import java.util.ArrayList;

import java.util.List;

/**

* 2 * @Author: AkaTom

* 3 * @Date: 2022/7/12 21:43

* 4 一级分类

*/

@Data

public class OneSubject {

private String id;

private String title;

//一个一级分类有多个二级分类

private List children=new ArrayList<>();

}

然后是二级分类Vo类

代码语言:javascript代码运行次数:0运行复制package cn.tompro.eduservice.entity.subject;

import lombok.Data;

/**

* 2 * @Author: AkaTom

* 3 * @Date: 2022/7/12 21:43

* 4 二级分类

*/

@Data

public class twoSubject {

private String id;

private String title;

}

然后在前端的时候我们则需要获取我们的vo类

vue中的methods:

代码语言:javascript代码运行次数:0运行复制 //点击某个一级分类,触发change,显示对应二级分类

subjectLevelOneChanged(value) {

//value就是一级分类id值

//遍历所有的分类,包含一级和二级

for(var i=0;i

//每个一级分类

var oneSubject = this.subjectOneList[i]

//判断:所有一级分类id 和 点击一级分类id是否一样

if(value === oneSubject.id) {

//从一级分类获取里面所有的二级分类

this.subjectTwoList = oneSubject.children

//把二级分类id值清空

this.courseInfo.subjectId = ''

}

}

},

//查询所有的一级分类

getOneSubject() {

subject.getSubjectList()

.then(response => {

this.subjectOneList = response.data.list

})

},data:

代码语言:javascript代码运行次数:0运行复制subjectOneList:[],//一级分类

subjectTwoList:[]//二级分类页面:

代码语言:javascript代码运行次数:0运行复制

v-model="courseInfo.subjectParentId"

placeholder="一级分类" @change="subjectLevelOneChanged">

v-for="subject in subjectOneList"

:key="subject.id"

:label="subject.title"

:value="subject.id"/>

v-for="subject in subjectTwoList"

:key="subject.id"

:label="subject.title"

:value="subject.id"/>

后端service层中的主要方法:

代码语言:javascript代码运行次数:0运行复制public List getAllOneTwoSubject() {

//1 查询所有1级分类

QueryWrapper wrapperOne=new QueryWrapper<>();

wrapperOne.eq("parent_id","0");

List oneSubjectList = baseMapper.selectList(wrapperOne);

//2 查询所有二级分类

QueryWrapper wrapperTwo=new QueryWrapper<>();

wrapperTwo.ne("parent_id","0");

List twoSubjectList = baseMapper.selectList(wrapperTwo);

//创建list集合 存储最终封装数据

List finalSubjectList=new ArrayList<>();

//封装一级分类

//查询出来所有的一级分类list集合遍历,得到每个一级分类对象,获取每个以及分类对象值

//封装到要求的list集合里面

for (int i = 0; i < oneSubjectList.size(); i++) {

//得到oneSubject每个对象

EduSubject eduSubject = oneSubjectList.get(i);

//把edusubject的值获取出来 放到onesubject中

OneSubject oneSubject=new OneSubject();

// oneSubject.setId(eduSubject.getId());

// oneSubject.setTitle(eduSubject.getTitle());

BeanUtils.copyProperties(eduSubject,oneSubject);

finalSubjectList.add(oneSubject);

// 在一级分类循环遍历查询所有的二级分类

// 创建list集合封装每一个一级分类的二级分类

List twoFinalSubjectList=new ArrayList<>();

for (int m = 0; m < twoSubjectList.size(); m++) {

EduSubject eduSubject1=twoSubjectList.get(m);

if (eduSubject1.getParentId().equals(oneSubject.getId())){

//把eduSubject1复制到twosubject中 放到twofinalsubjectlist中

twoSubject twosubject=new twoSubject();

BeanUtils.copyProperties(eduSubject1,twosubject);

twoFinalSubjectList.add(twosubject);

}

}

oneSubject.setChildren(twoFinalSubjectList);

}

//封装二级分类

return finalSubjectList;

}END

相关推荐

OEM Warranty Statements
Best365官网登录

OEM Warranty Statements

📅 07-04 👁️ 714
中信小白卡审核要多久?网申会快很多
365bet体育开户官网

中信小白卡审核要多久?网申会快很多

📅 08-15 👁️ 4269
桅(桅)是什么意思
365bet体育开户官网

桅(桅)是什么意思

📅 07-16 👁️ 7153