文章目录
前言
提示:这里可以添加本文要记录的大概内容:
我只知道在一个单表程序中可以加字段,但不知道还可以通过另一张表一起加
提示:以下是本篇文章正文内容,下面案例可供参考
一、单表
在Java Spring Boot后端和Vue前端的前后端分离项目中,为数据库表添加新字段并同步到前端展示与交互的步骤如下
步骤1:更新实体类
假设有一个名为User
的实体类,并且你想在这个实体类中添加新的字段。例如要添加一个address
字段:
java
@Entity
public class User {
@Data...各种注解
// 对应的getter和setter方法
private Long id;
// 已存在的字段...
private String username;
private String email;
// 新增地址字段
private String address;
}
步骤2:更新DAO层XML
你可能不需要直接修改DAO接口
但需要更新DAO层的XML文件中的SQL语句,其实就是在select
、insert
、update
方法中加上那个新增的字段
步骤3:更新Service实现类
在Service层中,可以考虑是否需要添加涉及新字段的业务逻辑方法。
比如导入功能等,这时候就需要把新增的字段加上去
java
@Service
public class UserService {
@Autowired
private UserRepository userRepository; // 或UserDao
// 新增一个根据地址查询用户的业务方法(如果需要)
public Optional<User> findUserByAddress(String address) {
return userRepository.findByAddress(address);
}
}
步骤4:更新Controller层
在Controller层 可以 提供API以返回包含新字段的数据给前端。
java
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
// 假设已有获取单个用户信息的API
@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
return ResponseEntity.of(userService.getUserById(id));
}
// 添加一个根据地址查询用户的API(如果前端需要)
@GetMapping("/by-address/{address}")
public ResponseEntity<User> getUserByAddress(@PathVariable String address) {
return ResponseEntity.of(userService.findUserByAddress(address));
}
}
也可以在模糊查询、排序、状态枚举中加上
步骤5:更新前端Vue模型和组件
如果前端或其他客户端需要访问这个新字段,记得在客户端代码中也相应地添加处理逻辑和展示新字段的内容。
在前端Vue应用中:
- 更新
user
模型以反映后端的新字段:
javascript
// 在store/modules/user.js或者类似的Vuex状态管理文件中
const state = {
// ...
user: {
id: null,
username: '',
email: '',
// 添加新字段
address: ''
},
// ...
};
- 更新获取用户信息的API调用,在
axios
请求中接收新字段:
javascript
// 在Vue组件内部或者其他负责获取用户信息的地方
axios.get(`/api/users/${userId}`).then(response => {
this.user = response.data;
});
// 或者根据新的API路径获取
axios.get(`/api/users/by-address/${address}`).then(response => {
this.user = response.data;
});
- 在Vue组件模板中显示新字段:
html
<template>
<div>
<!-- ...其他内容 -->
<p>{{ user.username }}</p>
<p>{{ user.email }}</p>
<!-- 显示新添加的地址字段 -->
<p>{{ user.address }}</p>
<!-- ...更多内容 -->
</div>
</template>
- 如果有相关的表单用于编辑用户信息,也需要在表单控件中添加对应的新字段输入。
html
<template>
<div>
<!-- ...其他组件内容 -->
<form @submit.prevent="onSubmit">
<!-- 已存在的用户名输入框 -->
<label for="username">用户名</label>
<input type="text" id="username" v-model="user.username">
<!-- 已存在的邮箱输入框 -->
<label for="email">邮箱</label>
<input type="email" id="email" v-model="user.email">
<!-- 新增地址输入框 -->
<label for="address">地址</label>
<input type="text" id="address" v-model="user.address">
<!-- 提交按钮 -->
<button type="submit">保存更改</button>
</form>
</div>
</template>
<script>
export default {
data() {
return {
user: {
// ... 其他已有属性
address: '', // 添加新字段
},
};
},
methods: {
onSubmit() {
// 发送更新用户的API请求
this.$axios.put(`/api/users/${this.user.id}`, this.user)
.then(response => {
// 更新成功后的处理...
})
.catch(error => {
// 处理错误...
});
},
},
};
</script>
这里,我们首先在模板中的表单里添加了一个新的<input>
元素,并将其v-model
绑定到user
对象的address
属性上。这样,当用户在表单中输入地址时,Vue会自动同步到组件的数据模型。
同时,在methods
部分的onSubmit
方法中,当表单提交时,前端会通过axios
向后端发送PUT请求,包含所有表单字段(包括新添加的address
字段),以便于在后端更新用户信息。
完成以上步骤后,重新构建并部署后端服务以及前端应用。这样,前端就能正常地展示、处理和保存后端添加的新字段了。
二、多表
在基于SSM(Spring、Spring MVC、MyBatis)和Struts 2的传统Java Web项目中,为User
实体类添加来自另一张表的字段并同步到前端展示与交互,步骤如下:
以某一支完整程序为基础,增加一张表,在那只完整程序内新增、修改、查看页面内增加新表字段,下面用【老程序/表】和【新程序/表】说明,用于区分
因为是在老程序中增加新的字段,这两个程序的表有关联关系一对一对应
思路: 新增的那张表也要有增删改查,因为一开始的老程序自己有一套完整的增删改查,是在老程序的新增、修改、查看页面加上新表中的字段
- 设计新程序
- 在老程序中加新字段,用于赋值给新程序
- 在老程序前端页面中加新字段,用于编辑页和查看页
- 在老程序的Mapper.xml 文件中映射新表中的字段,并修改ID查询
- 在老程序Spring框架的XML配置文件中(spring.xml)定义Bean(组件)Service 的配置注入新程序的Service ,因为这样老程序的 Service实现类就可以调用新程序的 Service实现类
有问题先排查是前端还是后端问题,在Action中Debug看前端数据有没有过来,没过来就是前端问题
在后在程序的修改中要注意,我是通过新程序的关联字段连接老程序的ID主键查询的
步骤1:新程序的增删改查
仿照老程写一套新程序后端的增删改查,其中要加一个ID,与老程序中主键ID对应。因为在老程序页面中的新增和修改要走新程序的代码,只有查看(根据ID查询)要在老程序的SQL中写
步骤2:老程序中新增实体类
在老程序的实体类中新增新表字段,用于后期实体类赋值
java
public class 老程序实体名 {
// 这是老程序
private Long id;
private String username;
private String email;
// 新增新表的地址字段
private String address;
private String state;
// 关联字段
private String strGuid;
// 对应的getter和setter方法
}
步骤3:更新前端页面
- 前端的编辑和新增页一般是同一个页面
javascript
<div>
<label>地址</label>
<div>
<input name="address" id="address" class="form-control" type="text"
maxlength="50" value="<s:property value="老程序实体名.address"/>">
</div>
</div>
address
:这是新表中的字段,需要加在老程序中的
name="address"
:设置输入框的名称
id="address"
:设置输入框的ID
type="text"
:指定这是一个文本输入类型
maxlength="50"
:限制用户最多可输入50个字符
value="<s:property value="老程序实体名.address"/>"
:这里是Struts2标签,用于从后端Java对象老程序实体类中获取并显示当前的地址到输入框中。如果【老程序实体名.address】有值,那么初始状态下该输入框会显示该值
- 前端的查看页要注意一下
如果有枚举类型字段要按下面格式:
javascript
<div>
// 状态明明是新加的字段,却要用老程序的实体名,因为要与后端参数保持一致
<s:if test="老程序实体名.state==1">
<div class="abc" title="同意">
同意
</div>
</s:if>
<s:if test="老程序实体名.state==2">
<div class="abc" title="不同意">
不同意
</div>
</s:if>
</div>
如果有系统代码字段要按下面格式:
javascript
// 这里要用Name
<s:property value="老程序实体名.系统字段名Name"/>
步骤4:更新Mapper接口及XML文件
先在Mapper.xml文件中映射新表中的字段,这个一定不要忘,否则后面功能不会实现
javascript
<!-- 假设你的Mapper接口名为NewTableMapper -->
<mapper namespace="com.example.mapper.NewTableMapper">
<resultMap id="newFieldResultMap" type="com.example.entity.NewTableEntity">
<!-- 已有字段映射... -->
<result property="newField" column="NEW_FIELD"/>
<!-- 新加的字段映射... -->
<result property="newExample" column="NEW_EXAMPLE"/>
</resultMap>
</mapper>
在XML文件中编写SQL语句(根据ID查询),确保通过LEFT JOIN
查询关联的关联字段信息。
对于字段中有系统代码的不要忘了系统代码表的系统代码名称字段
步骤5:更新Service实现类
在 Service里调用,不要在 Action里面调用,有事务影响;
只有insert、update开头的方法名才会开启事务。
在老程序的服务层(ServiceImpl)中注入新程序的Service实例,以便调用新程序的业务逻辑。
先在老程序Service的Bean实例中,新注入的新程序 Service,这样在老程序ServiceImpl类的业务逻辑中就可以直接使用新程序Service接口提供的服务了
xml
<bean id="userService" class="com.example.service.impl.UserService">
<property name="userDao" ref="userDao" />
<!--新注入的新程序 service -->
<property name="newTableService" ref="newTableService" />
</bean>
修改老程序服务层中添加和修改等方法,在保存或更新用户的同时处理新表记录的插入或更新。(在老程序的服务层实现类中的新增、修改方法内加上新程序的字段)
java
@Override
public User addUser(User user) {
// ... 省略验证和老表数据处理
// 通过UserDao接口将新用户保存到数据库
this.userDao.insertUser(user);
// 下面是调用新程序中的方法,老实体类的值赋值给新实体类
NewTable newRecord = new NewTable();
newRecord.setUserId(user.getId());
newRecord.setAddress(user.getAddress());
newRecord.setEmail(user.getEmail());
this.newTableService.insertNewTable(newRecord);
return user;
}
// 修改方法也是一样,但是修改有一个ID查询,我这里的ID查询是用的关联字段
@Override
public User updateUser(User user) {
// ... 省略验证和老表数据处理
userDao.updateUser(user);
// 下面是调用新程序中的方法
NewTable newRecord = new NewTable();
newRecord.setId(获取新表记录ID);
newRecord.setAddress(user.getAddress());
newRecord.setEmail(user.getEmail());
this.newTableService.updateNewTable(newRecord);
return user;
}
步骤6:关于Action层
查前后端问题先Debug
Action层,没有数据就说明前端数据没有传过来,是前端问题。
不要忘记Action
层内也有Setter、Getter(新增字段中可能有系统代码)
完成以上步骤后,重新编译部署项目,并确保前端JSP页面能够正确加载和展示新字段的信息。同时,注意如果在表单中有编辑功能,也需要相应地添加对新字段的处理逻辑。