目录
一、两表的增删改查
1、配置文件
1.1 pom文件
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--连接mysql-->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--mybatis-plus持久层操作-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
<!-- MybatisPlus根据数据库表生成文件 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.2</version>
</dependency>
<!--实体类注解-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
1.2 properties文件
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/vuetest?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=lwl@123
# ??
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
spring.jackson.serialization.write-date-keys-as-timestamps=false
#logging.level.com.baomidou.ant.test.dao=debug
#mybatis-plus _ U
mybatis-plus.configuration.map-underscore-to-camel-case=true
# ?????
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# ??mapper?????
mybatis-plus.mapper-locations=classpath:/mapper/*.xml
#MybatisPlus????
# 1 1??????????
mybatis-plus.global-config.db-config.logic-not-delete-value=1
# 2 2??????????
mybatis-plus.global-config.db-config.logic-delete-value=2
server.port=8888
1.3 根据数据库表生成代码
package com.example.multablequery;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class GenerateTest {
/**
* <p>
* 读取控制台内容
* </p>
*/
public static String scanner(String tip) {
Scanner scanner = new Scanner(System.in);
StringBuilder help = new StringBuilder();
help.append("请输入" + tip + ":");
System.out.println(help.toString());
if (scanner.hasNext()) {
String ipt = scanner.next();
if (StringUtils.isNotBlank(ipt)) {
return ipt;
}
}
throw new MybatisPlusException("请输入正确的" + tip + "!");
}
public static void main(String[] args) {
// 代码生成器
AutoGenerator mpg = new AutoGenerator();
// 全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/src/main/java");
gc.setAuthor("L");
gc.setOpen(false);
// gc.setSwagger2(true); 实体属性 Swagger2 注解
mpg.setGlobalConfig(gc);
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/vuetest?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true");
// dsc.setSchemaName("public");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("密码");
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
//pc.setModuleName(scanner("模块名"));
pc.setParent("com.example.multablequery");
//pc.setXml("");
pc.setEntity("entity");//实体的包
pc.setMapper("dao");//dao的包
pc.setService("service");//service的包
pc.setServiceImpl("service.impl");//实现类的包
mpg.setPackageInfo(pc);
// 自定义配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
// to do nothing
}
};
// 如果模板引擎是 freemarker
// String templatePath = "/templates/mapper.xml.ftl";
// 如果模板引擎是 velocity
String templatePath = "/templates/mapper.xml.vm";
// 自定义输出配置
List<FileOutConfig> focList = new ArrayList<>();
// 自定义配置会被优先输出
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
return projectPath + "/src/main/resources/mapper/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
}
});
cfg.setFileOutConfigList(focList);
mpg.setCfg(cfg);
// 配置模板
//不在java文件夹下面写入mapper文件
TemplateConfig templateConfig = new TemplateConfig();
templateConfig.setXml(null);
mpg.setTemplate(templateConfig);
// 策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);// _ tab_user tabUser
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setEntityLombokModel(true);
strategy.setRestControllerStyle(true);
// 公共父类
// 写于父类中的公共字段
//strategy.setSuperEntityColumns("id");// id @TabId
strategy.setInclude(scanner("表名,多个英文逗号分割").split(","));
strategy.setControllerMappingHyphenStyle(true);
strategy.setTablePrefix(pc.getModuleName() + "_");
mpg.setStrategy(strategy);
mpg.execute();
}
}
1.4 启动类代码
@SpringBootApplication
@MapperScan("com.example.multablequery.dao")
public class MulTableQueryApplication {
public static void main(String[] args) {
SpringApplication.run(MulTableQueryApplication.class, args);
}
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration corsConfiguration = new CorsConfiguration();
// corsConfiguration.setAllowCredentials(true);
corsConfiguration.addAllowedHeader("*");// 允许所有的头
corsConfiguration.addAllowedOrigin("*");// 允许所有源发出的请求
corsConfiguration.addAllowedMethod("*");// 允许所有的方法 如果不写的话默认是允许GET POST
source.registerCorsConfiguration("/**", corsConfiguration);// 所有的路径,这里写完就不用再Controller中写跨域请求
return new CorsFilter(source);
}
/**
* 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
@Bean
public ConfigurationCustomizer configurationCustomizer() {
return configuration -> configuration.setUseDeprecatedExecutor(false);
}
}
2、简单查询
查询时,可以有两种接收查询结果的格式
2.1 后端代码
controller层:
@RestController
@RequestMapping("/t-user")
public class TUserController {
@Resource
private ITUserService itUserService;
/**
* 查询之后放在Map里面进行接收
* @return
*/
@GetMapping
public Result findAll(){
List<Map> list = itUserService.findAll();
return new Result(list);
}
/**
* 查询之后用实体类进行接收
* @return
*/
@GetMapping("getAll")
public Result getAll(){
List<TUser> list = itUserService.getAll();
return new Result(list);
}
}
service层:
public interface ITUserService extends IService<TUser> {
List<Map> findAll();
List<TUser> getAll();
}
service实现层:
@Service
public class TUserServiceImpl extends ServiceImpl<TUserMapper, TUser> implements ITUserService {
@Resource
private TUserMapper tUserMapper;
/**
* 查询结构用Map进行接收
* @return
*/
@Override
public List<Map> findAll() {
List<Map> list = tUserMapper.findAll();
return list;
}
/**
* 查询结果用实体类进行接收
* @return
*/
@Override
public List<TUser> getAll() {
List<TUser> list = tUserMapper.getAll();
return list;
}
}
dao层:
public interface TUserMapper extends BaseMapper<TUser> {
List<Map> findAll();
List<TUser> getAll();
}
dao层sql:
<!-- 查询后用Map进行接收 -->
<select id="findAll" resultType="java.util.Map">
select * from t_user u,t_role r where r.id = u.rid;
</select>
<!-- 查询后用实体类进行接收 -->
<select id="getAll" resultMap="getUser">
select * from t_user u,t_role r where r.id = u.rid;
</select>
<!-- 多对一关系 -->
<resultMap id="getUser" type="com.example.multablequery.entity.TUser" autoMapping="true">
<id column="id" property="id"></id>
<!-- 这里的property指代的是 在多的那一方创建的一的实体类 -->
<association property="TRole" javaType="com.example.multablequery.entity.TRole" autoMapping="true">
<id column="id" property="id"></id>
</association>
</resultMap>
实体类接收数据时需要改写实体类:
@Data
@EqualsAndHashCode(callSuper = false)
public class TUser implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* 用户名
*/
private String username;
/**
* 用户密码
*/
private String password;
/**
* 用户生日
* 转换时间格式与前台保持一致
*/
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate birthday;
/**
* 用户性别
*/
private String sex;
private Integer rid;
/**
* 状态
*/
// @TableLogic
private Integer status;
/**
* 多对一的关系,放的是实体类
*/
@TableField(exist = false)
private TRole tRole;
}
Map接收数据格式:
{
"code": 200,
"msg": "操作成功",
"t": [
{
"birthday": "2023-01-18",
"password": "123456",
"role": "admin",
"sex": "男",
"id": 1,
"rid": 1,
"status": 1,
"username": "zs"
},
{
"birthday": "2023-01-18",
"password": "1",
"role": "user",
"sex": "男",
"id": 2,
"rid": 2,
"status": 1,
"username": "1"
},
{
"birthday": "2023-01-19",
"password": "2",
"role": "user",
"sex": "女",
"id": 2,
"rid": 2,
"status": 1,
"username": "2"
}
]
}
实体类接收数据格式:
{
"code": 200,
"msg": "操作成功",
"t": [
{
"id": 1,
"username": "zs",
"password": "123456",
"birthday": "2023-01-18",
"sex": "男",
"rid": 1,
"status": 1,
"trole": {
"id": 1,
"role": "admin",
"status": 1
}
},
{
"id": 2,
"username": "1",
"password": "1",
"birthday": "2023-01-18",
"sex": "男",
"rid": 2,
"status": 1,
"trole": {
"id": 2,
"role": "user",
"status": 1
}
}
]
}
2.2 前端代码
实体类接收方式:
<!-- 表格内容 -->
<el-table :data="tableData" border style="width: 100%">
<el-table-column prop="username" label="姓名">
</el-table-column>
<el-table-column prop="sex" label="性别">
</el-table-column>
<!-- 因为接收的数据在对象.对象中,所以这里进行取值时要用对象.属性 -->
<el-table-column prop="trole.role" label="角色">
</el-table-column>
<el-table-column fixed prop="birthday" label="生日">
</el-table-column>
<el-table-column prop="status" label="状态">
</el-table-column>
<el-table-column fixed="right" label="操作" width="100">
<template slot-scope="scope">
<el-button @click="delStu(scope.row)" type="text" size="small">删除</el-button>
<el-button @click="updStu(scope.row)" type="text" size="small">修改</el-button>
</template>
</el-table-column>
</el-table>
queryData() { //初始化表格数据
this.$axios.get(`t-user/getAll`).then(r=>{
this.tableData=r.data.t;
})
}
定义变量
return {
tableData: [],
}
函数调用
created() {
this.queryData();
}
Map接收方式:
<!-- 表格内容 -->
<el-table :data="tableData" border style="width: 100%">
<el-table-column prop="username" label="姓名">
</el-table-column>
<el-table-column prop="sex" label="性别">
</el-table-column>
<el-table-column prop="role" label="角色">
</el-table-column>
<el-table-column fixed prop="birthday" label="生日">
</el-table-column>
<el-table-column prop="status" label="状态">
</el-table-column>
<el-table-column fixed="right" label="操作" width="100">
<template slot-scope="scope">
<el-button @click="delStu(scope.row)" type="text" size="small">删除</el-button>
<el-button @click="updStu(scope.row)" type="text" size="small">修改</el-button>
</template>
</el-table-column>
</el-table>
编写函数:
queryData() { //初始化表格数据
this.$axios.get(`t-user`).then(r=>{
this.tableData=r.data.t;
})
}
定义变量:
return {
tableData: [],
}
函数调用:
created() {
this.queryData();
}
3、分页查询
3.1 后端代码
controller层:
@RestController
@RequestMapping("/t-user")
public class TUserController {
@Resource
private ITUserService itUserService;
/**
* 查询之后放在Map里面进行接收
* @return
*/
@GetMapping
public Result findAll(Page page){
Page list = itUserService.findAll(page);
return new Result(list);
}
/**
* 查询之后用实体类进行接收
* @return
*/
@GetMapping("getAll")
public Result getAll(Page page){
Page list = itUserService.getAll(page);
return new Result(list);
}
}
service层:
public interface ITUserService extends IService<TUser> {
Page findAll(Page page);
Page getAll(Page page);
}
service实现层:
@Service
public class TUserServiceImpl extends ServiceImpl<TUserMapper, TUser> implements ITUserService {
@Resource
private TUserMapper tUserMapper;
/**
* 查询结构用Map进行接收
* @return
* @param page
*/
@Override
public Page findAll(Page page) {
Page list = tUserMapper.findAll(page);
return list;
}
/**
* 查询结果用实体类进行接收
* @return
* @param page
*/
@Override
public Page getAll(Page page) {
Page list = tUserMapper.getAll(page);
return list;
}
}
dao层:
/**
* @SuppressWarnings("all") 抑制左右警告
*/
@SuppressWarnings("all")
public interface TUserMapper extends BaseMapper<TUser> {
Page findAll(Page page);
Page getAll(Page page);
}
dao层代码:(和简单查询比没有变化)
<!-- 查询后用Map进行接收 -->
<select id="findAll" resultType="java.util.Map">
select * from t_user u,t_role r where r.id = u.rid
</select>
<!-- 查询后用实体类进行接收 -->
<select id="getAll" resultMap="getUser">
select * from t_user u,t_role r where r.id = u.rid
</select>
<!-- 多对一关系 -->
<resultMap id="getUser" type="com.example.multablequery.entity.TUser" autoMapping="true">
<id column="id" property="id"></id>
<!-- 这里的property指代的是 在多的那一方创建的一的实体类 -->
<association property="TRole" javaType="com.example.multablequery.entity.TRole" autoMapping="true">
<id column="id" property="id"></id>
</association>
</resultMap>
3.2 前端代码
前端代码:与简单查询相比变化的只有编写的函数和定义的变量
实体类格式接收:
分页组件:
<!-- 分页组件 -->
<div class="block">
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
:current-page="page.current" :page-sizes="[2, 4, 6, 8]" :page-size="page.size"
layout="total, sizes, prev, pager, next, jumper" :total="page.total">
</el-pagination>
</div>
编写函数
handleSizeChange(val) { //分页组件每页条数触发事件
console.log(`每页 ${val} 条`);
this.page.size = val;
this.queryData();
},
handleCurrentChange(val) { //分页组件当前页触发事件
console.log(`当前页: ${val}`);
this.page.current = val;
this.queryData();
},
queryData() { //初始化表格数据
this.$axios.get(`t-user/getAll`, {
params: this.page
}).then(r => {
this.tableData = r.data.t.records;
//把查询到的数据总条数赋值给表格的条数
this.page.total = r.data.t.total;
})
},
定义变量
return{
tableData: [],
page: {
current: 1,
size: 2,
total: 10
},
}
Map格式接收
分页组件:
<!-- 分页组件 -->
<div class="block">
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
:current-page="page.current" :page-sizes="[2, 4, 6, 8]" :page-size="page.size"
layout="total, sizes, prev, pager, next, jumper" :total="page.total">
</el-pagination>
</div>
编写函数:
handleSizeChange(val) { //分页组件每页条数触发事件
console.log(`每页 ${val} 条`);
this.page.size = val;
this.queryData();
},
handleCurrentChange(val) { //分页组件当前页触发事件
console.log(`当前页: ${val}`);
this.page.current = val;
this.queryData();
},
queryData() { //初始化表格数据
this.$axios.get(`t-user`, {
params: this.page
}).then(r => {
this.tableData = r.data.t.records;
//把查询到的数据总条数赋值给表格的条数
this.page.total = r.data.t.total;
})
},
定义变量
return{
tableData: [],
page: {
current: 1,
size: 2,
total: 10
},
}
4、模糊查询
4.1 后端代码
controller层:
@RestController
@RequestMapping("/t-user")
public class TUserController {
@Resource
private ITUserService itUserService;
/**
* 查询之后放在Map里面进行接收
* @return
*/
@GetMapping
public Result findAll(Page page,String username,Integer rid){
Page list = itUserService.findAll(page,username,rid);
return new Result(list);
}
/**
* 查询之后用实体类进行接收
* @return
*/
@GetMapping("getAll")
public Result getAll(Page page,String username,Integer rid){
Page list = itUserService.getAll(page,username,rid);
return new Result(list);
}
}
service层:
public interface ITUserService extends IService<TUser> {
Page findAll(Page page, String username, Integer rid);
Page getAll(Page page, String username, Integer rid);
}
service实现层:
@Service
public class TUserServiceImpl extends ServiceImpl<TUserMapper, TUser> implements ITUserService {
@Resource
private TUserMapper tUserMapper;
/**
* 查询结构用Map进行接收
* @return
*/
@Override
public Page findAll(Page page, String username, Integer rid) {
Page list = tUserMapper.findAll(page,username,rid);
return list;
}
/**
* 查询结果用实体类进行接收
* @return
*/
@Override
public Page getAll(Page page, String username, Integer rid) {
Page list = tUserMapper.getAll(page,username,rid);
return list;
}
}
dao层:
@SuppressWarnings("all")
public interface TUserMapper extends BaseMapper<TUser> {
// 如果这里使用实体类user接收username和rid两个数据 那么在sql中进行取值时,要使用user.usernam或者是user.rid
Page findAll(Page page, @Param("username") String username,@Param("rid") Integer rid);
Page getAll(Page page, @Param("username") String username,@Param("rid") Integer rid);
}
dao代码:
<!-- 查询后用Map进行接收 -->
<select id="findAll" resultType="java.util.Map">
select * from t_user u,t_role r where r.id = u.rid
<if test="username!=null and username!=''">
and username like concat("%",#{username},"%")
</if>
<if test="rid!=null and rid!=''">
and rid like concat("%",#{rid},"%")
</if>
</select>
<!-- 查询后用实体类进行接收 -->
<select id="getAll" resultMap="getUser">
select * from t_user u,t_role r where r.id = u.rid
<if test="username!=null and username!=''">
and username like concat("%",#{username},"%")
</if>
<if test="rid!=null and rid!=''">
and rid like concat("%",#{rid},"%")
</if>
</select>
<!-- 多对一关系 -->
<resultMap id="getUser" type="com.example.multablequery.entity.TUser" autoMapping="true">
<id column="id" property="id"></id>
<!-- 这里的property指代的是 在多的那一方创建的一的实体类 -->
<association property="TRole" javaType="com.example.multablequery.entity.TRole" autoMapping="true">
<id column="id" property="id"></id>
</association>
</resultMap>
查询所有角色信息的后端代码
@RestController
@RequestMapping("/t-role")
public class TRoleController {
@Resource
private ITRoleService itRoleService;
/**
* 查询所有角色的数据
*/
@GetMapping
public Result queryAll(){
List<TRole> list = itRoleService.list();
return new Result(list);
}
}
4.2 前端代码
Map格式接收:
模糊查询组件及按钮:
<!-- 模糊查询 -->
<el-input v-model="search.username" placeholder="请输入名字" style="width: 100px; float: left; margin-right: 10px;">
</el-input>
<!-- 下拉框 -->
<!-- v-model="search.rid" : 代表绑定的是 -->
<el-select v-model="search.rid" placeholder="请选择角色" style="width: 200px; float: left; margin-right: 10px;">
<el-option v-for="item in roleList" :key="item.id" :label="item.role" :value="item.id">
</el-option>
</el-select>
<!--
<el-option
v-for="item in roleList"
key:表名唯一性
:key="item.value"
lable:页面上显示的值
:label="item.label"
value:应用的值
:value="item.value">
</el-option>
-->
<el-button type="primary" plain @click="hasSearchData" style="float: left;">查询</el-button>
<el-button type="info" plain @click="resetSearchData" style="float: left;">清空查询条件</el-button>
定义变量:
// 模糊查询
search: {},
// 下拉框
roleList: [],
下拉框中的信息在另外一张表:
所以需要在页面初始化时就查询信息
created() {
this.queryData();
// 调用查询所有角色信息的函数
this.queryRole();
}
编写加载角色信息函数
queryRole(){//查询所有角色信息,填充到模糊查询的下拉框中
this.$axios.get(`t-role`).then(r=>{
this.roleList = r.data.t;
})
}
编写查询信息函数:
hasSearchData() { // 模糊查询:每次查询完之后返回第一页
this.page.current = 1;
this.queryData();
},
resetSearchData() { // 重置模糊查询条件
this.search = {};
this.queryData();
},
queryData() { //初始化表格数据
//扩展运算符: 拼接
let newobj = {
...this.search,
...this.page
}
this.$axios.get(`t-user`, {
params: newobj
}).then(r => {
this.tableData = r.data.t.records;
//把查询到的数据总条数赋值给表格的条数
this.page.total = r.data.t.total;
})
},
实体类格式接收:
模糊查询组件及按钮:
<!-- 模糊查询 -->
<el-input v-model="search.username" placeholder="请输入名字" style="width: 100px; float: left; margin-right: 10px;">
</el-input>
<!-- 下拉框 -->
<!-- v-model="search.rid" : 代表绑定的是 -->
<el-select v-model="search.rid" placeholder="请选择角色" style="width: 200px; float: left; margin-right: 10px;">
<el-option
v-for="item in roleList"
:key="item.id"
:label="item.role"
:value="item.id">
</el-option>
</el-select>
<!--
<el-option
v-for="item in roleList"
key:表名唯一性
:key="item.value"
lable:页面上显示的值
:label="item.label"
value:应用的值,也就是传到后台的值
:value="item.value">
</el-option>
-->
<el-button type="primary" plain @click="hasSearchData" style="float: left;">查询</el-button>
<el-button type="info" plain @click="resetSearchData" style="float: left;">清空查询条件</el-button>
定义变量:
// 模糊查询
search: {},
// 下拉框
roleList: [],
页面初始化加载角色信息:
created() {
this.queryData();
// 调用查询所有角色信息的函数
this.queryRole();
}
编写加载角色信息函数
queryRole(){//查询所有角色信息,填充到模糊查询的下拉框中
this.$axios.get(`t-role`).then(r=>{
this.roleList = r.data.t;
})
}
编写角色查询信息函数:
hasSearchData() { // 模糊查询:每次查询完之后返回第一页
this.page.current = 1;
this.queryData();
},
resetSearchData() { // 重置模糊查询条件
this.search = {};
this.queryData();
},
queryData() { //初始化表格数据
//扩展运算符: 拼接
let newobj = {
...this.search,
...this.page
}
this.$axios.get(`t-user/getAll`, {
params: newobj
}).then(r => {
this.tableData = r.data.t.records;
//把查询到的数据总条数赋值给表格的条数
this.page.total = r.data.t.total;
})
},
5、删除
5.1 后端代码
controller层:
/**
* 根据用户id删除用户
*/
@DeleteMapping("{id}")
public Result delUser(@PathVariable Integer id){
return new Result(itUserService.removeById(id));
}
5.2 前端代码
定义删除按钮及函数:
<el-table-column fixed="right" label="操作" width="100">
<template slot-scope="scope">
<el-button @click="delStu(scope.row)" type="text" size="small">删除</el-button>
<el-button @click="updStu(scope.row)" type="text" size="small">修改</el-button>
</template>
</el-table-column>
编写删除函数
delStu(row) { //表格删除按钮触发事件
console.log(row.id);
//根绝学生的唯一属性进行删除
let id = row.id
this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => { //点击确认按钮触发的事件
this.$axios.delete(`t-user/` + id).then(r => {
if (r.data.t == true) {
this.$message({
showClose: true,
type: 'success',
message: '删除成功!'
});
this.hasSearchData();
}
})
}).catch(() => { //点击取消按钮触发的事件
this.$message({
showClose: true,
type: 'info',
message: '已取消删除'
});
});
},
6、添加
6.1后端代码
controller层:
/**
* 添加/修改用户
*/
@PostMapping
public Result addOrUpd(TUser tUser){
boolean b = itUserService.saveOrUpdate(tUser);
return new Result(b);
}
6.2 前端代码
Map和实体格式一样接收数据
定义添加/修改表单
<!-- 添加/修改对话框 -->
<el-dialog title="提示" :visible.sync="dialogVisible" width="30%" :before-close="handleClose">
<!-- :before-close="handleClose" 对话框关闭之前的操作函数-->
<span>
<!-- 添加/修改表单 -->
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="用户名字">
<el-input v-model="form.username"></el-input>
</el-form-item>
<el-form-item label="角色">
<el-select v-model="form.rid" placeholder="请选择角色"
style="width: 200px; float: left; margin-right: 10px;">
<el-option v-for="item in roleList" :key="item.id" :label="item.role" :value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="生日">
<el-col :span="11">
<!-- format:代表着前端显示时间的格式 value-format:代表的是前端向后台传递数据的格式 -->
<el-date-picker type="date" placeholder="选择日期" v-model="form.birthday" style="width: 100%;"
value-format="yyyy-MM-dd"></el-date-picker>
</el-col>
</el-form-item>
<el-form-item label="性别">
<el-radio v-model="form.sex" label="男">男</el-radio>
<el-radio v-model="form.sex" label="女">女</el-radio>
</el-form-item>
<el-form-item label="状态">
<el-switch v-model="form.status" active-color="#13ce66" inactive-color="#ff4949"
:active-value="1" :inactive-value="2" disabled>
</el-switch>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">确定</el-button>
<el-button @click="dialogVisible=false">取消</el-button>
</el-form-item>
</el-form>
</span>
</el-dialog>
定义添加按钮
<!-- 添加按钮 -->
<el-button type="success" icon="el-icon-circle-plus" circle style="float: right;" @click="addStu"></el-button>
定义对话框控制量和表单对象
// 对话框的控制值,初始为false
dialogVisible: false,
form: {},
编写添加按钮触发函数
addStu() { // 添加按钮触发事件
// 性别初始值为 男 状态初始值为 1
this.form ={
sex:"男",
status:1
}
// 打开对话框
this.dialogVisible = true;
},
编写表单关闭按钮
handleClose(done) { // 添加/修改表单关闭按钮触发事件
this.$confirm('确认关闭?')
.then(_ => {
done();
})
.catch(_ => {});
},
编写表单提交函数
onSubmit() { // 添加/修改表单提交
// 添加的时候,把form里面的内容传到后台即可
this.$axios.post("t-user", qs.stringify(this.form)).then(r => {
if (r.data.t == true) {
this.$message({
showClose: true,
type: 'success',
message: '操作成功!'
});
// 关闭弹出对话框
this.dialogVisible = false;
// 将表单内容清空
this.form = {};
// 刷新表格数据
this.hasSearchData();
} else {
this.$message({
showClose: true,
type: 'warning',
message: '操作失败!'
});
}
})
},
7、表单验证(含复选框)
7.1 前端代码
两种格式接收数据一样
定义验证规则:
<!-- 表单验证 :rules="rules" -->
<el-form ref="form" :rules="rules" :model="form" label-width="80px">
<!-- 这里的prop属性值要和下面的v-model保持一致 -->
<el-form-item label="用户名字" prop="username">
<el-input v-model="form.username"></el-input>
</el-form-item>
<el-form-item>
<!-- 提交时验证表单form -->
<el-button type="primary" @click="onSubmit('form')">确定</el-button>
<el-button @click="dialogVisible=false">取消</el-button>
</el-form-item>
<el-form-item label="兴趣爱好" prop="inter">
<template>
<el-checkbox-group v-model="form.inter">
<el-checkbox label="跑步" name="inter"></el-checkbox>
<el-checkbox label="唱歌" name="inter"></el-checkbox>
<el-checkbox label="吃饭" name="inter"></el-checkbox>
</el-checkbox-group>
</template>
</el-form-item>
</el-form>
定义复选框变量:
form: {
sex:'男',
inter: []
},
编写表单验证规则(定义在data里面)
// 表单验证规则
rules: {
username: [{
required: true,
message: '请填写名称',
trigger: 'blur'
},
{
min: 1,
max: 5,
message: '长度在 1 到 5 个字符',
trigger: 'blur'
}
],
sex: [{
required: true,
message: '请选择性别',
trigger: 'change'
}],
birthday: [{
required: true,
message: '请选择日期',
trigger: 'change'
}],
rid: [{
required: true,
message: '请选择角色',
trigger: 'change'
}],
status: [{
required: true,
message: '请选择状态',
trigger: 'blur'
}],
inter: [{
required: true,
message: '请至少选择一个兴趣爱好',
trigger: 'change',
}]
}
改写表单提交函数:
onSubmit(formName) { // 添加/修改表单提交
// 将数组转化为字符串,这里是将每一个数据通过,来进行拼接
let inter1 = this.form.inter.join(',');
//赋值给对象的inter属性,传递给后台字符串属性
this.form.inter = inter1;
this.$refs[formName].validate((valid) => {
if (valid) {
// 添加的时候,把form里面的内容传到后台即可
this.$axios.post("t-user", qs.stringify(this.form)).then(r => {
if (r.data.t == true) {
this.$message({
showClose: true,
type: 'success',
message: '操作成功!'
});
// 关闭弹出对话框
this.dialogVisible = false;
// 将表单内容清空
this.form = {};
// 刷新表格数据
this.hasSearchData();
} else {
this.$message({
showClose: true,
type: 'warning',
message: '操作失败!'
});
}
})
} else {
console.log('error submit!!');
return false;
}
});
},
8、修改
8.1 后端代码
/**
* 添加/修改用户
*/
@PostMapping
public Result addOrUpd(TUser tUser){
boolean b = itUserService.saveOrUpdate(tUser);
return new Result(b);
}
8.2 前端代码
定义修改按钮及函数
<el-table-column fixed="right" label="操作" width="100">
<template slot-scope="scope">
<el-button @click="delStu(scope.row)" type="text" size="small">删除</el-button>
<el-button @click="updStu(scope.row)" type="text" size="small">修改</el-button>
</template>
</el-table-column>
编写修改函数
updStu(row) { //表格修改按钮触发事件
if (this.$refs.form != undefined) {
this.$refs.form.clearValidate();
}
//实体格式接收数据进行修改时 不需要另外一张表的数据 可以直接把另外一张表的数据删除即可
delete this.form.trole
//显示弹出对话框
this.dialogVisible = true;
//将当前这一行的数据赋值给表单
//this.form = row 浅拷贝的形式不行
//采取深克隆的形式 JSON.stringify(row):转化为json字符串
// JSON.parse():把JSON字符串转化为JSON对象
this.form = JSON.parse(JSON.stringify(row));
},
注:
//实体格式接收数据进行修改时 不需要另外一张表的数据 可以直接把另外一张表的数据删除即可
delete this.form.trole
9、总结
9.1 单表和多表的异同
①单表和多表的查询实现不同,因为MybatisPlus支持单表的增删改查,多表增删改查时需要自己编写sql
②多表在进行增删改时其实是操作单表,和单表的增删改是相同的
9.2 以实体类接收数据和以Map接收数据的异同
①编写sql时,Map接收不需要实体类,以实体类接收需要改写实体类
②修改时,以实体类接收数据的后端不能接收前端传过来的另外一张表的数据,所以需要把另外一张表的数据去掉
使用 delete关键字可以
9.3 注意
在编写sql时,两张表的id可能会重复,要操作哪张表优先把哪张表放在前面,避免操作时id值错误