SpringBoot第五讲

目录

一、两表的增删改查

1、配置文件

1.1 pom文件

1.2 properties文件

1.3 根据数据库表生成代码

1.4 启动类代码

2、简单查询

2.1 后端代码

2.2 前端代码

3、分页查询

3.1 后端代码

3.2 前端代码

4、模糊查询

4.1 后端代码

4.2 前端代码

5、删除

5.1 后端代码

5.2 前端代码

6、添加

6.1后端代码

6.2 前端代码

7、表单验证(含复选框)

7.1 前端代码

8、修改

8.1 后端代码

8.2 前端代码

9、总结

9.1 单表和多表的异同

9.2 以实体类接收数据和以Map接收数据的异同

9.3 注意


一、两表的增删改查

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值错误

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值