MyBatis-Plus 教程中的天花板,还有谁?

MyBatis-Plus 教程中的天花板,还有谁?

一.Mybatis-plus概述

MyBatis-Plus(简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

二愿景

我们的愿景是成为 MyBatis 最好的搭档,就像 魂斗罗 中的 1P、2P,基友搭配,效率翻倍。
在这里插入图片描述

三特性

1.无侵入: 只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑

2.损耗小: 启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作

3.强大的 CRUD 操作: 内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求

4.支持 Lambda 形式调用: 通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错

5.支持主键自动生成: 支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题

6.支持 ActiveRecord 模式: 支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作

7.支持自定义全局通用操作: 支持全局通用方法注入( Write once, use anywhere )

8.内置代码生成器: 采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用

9.内置分页插件: 基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询

10.分页插件支持多种数据库: 支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库

11.内置性能分析插件: 可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询

12.内置全局拦截插件: 提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

四.开始撸代码

1.使用数据库test,创建user表

USE test;
DROP TABLE IF EXISTS USER;

CREATE TABLE USER
(
 id BIGINT(20) NOT NULL COMMENT '主键ID',
 NAME VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
 age INT(11) NULL DEFAULT NULL COMMENT '年龄',
 email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
 PRIMARY KEY (id)
);

2.向user表中添加数据

INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');

3.添加mybatis-plus的坐标


  <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.2</version>
  </dependency>

4.整体依赖

 <dependencies>
  		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.2</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

5.springboot核心配置文件

application.properties文件内容

server.port=8081

spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8&useSSL=true&useUnicode=true&characterEncoding=utf8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

6.创建包pojo,添加实体类User.java

package cn.kgc.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

7.编写UserMapper

@Mapper
public interface UserMapper extends BaseMapper<User> {
	  /*所有的CRUD已经编写完成*/
}

8.配置文件中需要配置日志

server.port=8081
#datasource
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8&useSSL=true&useUnicode=true&characterEncoding=utf8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

#mybatis-plus 日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

9.插入操作

//测试插入
@Test
public void testInsert(){
    User user = new User();
    user.setName("派大星学Java");
    user.setAge(16);
    user.setEmail("none-j@qq.com");

    int insert = userMapper.insert(user);//帮我们自动生成id
    System.out.println(insert);//受影响的行数
    System.out.println(user);//发现,id会自动回填
}

数据库插入的id的默认值为:全局的唯一id。
主键生成策略

1.默认 ID_WORKER 全局唯一
雪花算法:
snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生4096个ID),最后有一个符号,永远是0。可以保证几乎是全球唯一!
2.主键自增
我们需要配置主键自增:
1、实体类字段上@TableId(type = IdType.AUTO)
	 @TableId(type=IdType.AUTO)
      private Long id;
2、数据库字段一定要是自增!

在这里插入图片描述
其他的源码解释

public enum IdType{
    AUTO(0),//数据库id自增
    NONE(1),//未设置主键
    INPUT(2),//手动输入   一旦手动输入id之后,就需要自己设置id了
    ID_WORKER(3),//默认的全局唯一id
    UUID(4),//全局唯一id UUID
    ID_WORKER_STR(5),//ID_WORKER 字符串表示法
}

10.添加和更新信息时间需要自动填充

创建时间、修改时间!这些个操作一般都是自动化完成的,我们不希望手动更新!

阿里巴巴开发手册:所有的数据库表:gmt_create、gmt_modified几乎所有的表都要配置上!而且需要自动化!

方式一:数据库级别(工作中不允许更改数据库)
1、在表中新增字段create_time、update_time
在这里插入图片描述

private Date createTime;
private Date updateTime;

方式二:代码级别
1、删除数据库中的默认值、更新操作!
在这里插入图片描述
2、实体类字段属性需要增加注解

 @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;

3、编写处理器来处理这个注解即可!

@Slf4j//日志
@Component
public class MyDateObjectHandler implements MetaObjectHandler {

    //插入时的填充策略
    @Override
    public void insertFill(MetaObject metaObject) {
        this.setFieldValByName("createTime",new Date(),metaObject);
        this.setFieldValByName("updateTime",new Date(),metaObject);

    }
    //更新时的填充策略
    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
}

4、测试插入
5、测试更新,观察时间即可!

11.乐观锁

在面试过程中,我们经常会被问到乐观锁,悲观锁!
乐观锁: 故名思议十分乐观,它总是认为不会出现问题,无论干什么不去上锁!如果出了问题,再次更新值测试
悲观锁: 故名思议十分悲观,它总是认为总是出现问题,无论干什么都会上锁!再去操作!
乐观锁实现方式:
1.取出记录时,获取当前version
2.更新时,带上这个version
3.执行更新时, set version = newVersion where version = oldVersion
4.如果version不对,就更新失败

--A
update user set name = "wumao",version = version + 1
where id = 2 and version = 1

--B  线程抢先完成,这个时候 version = 2,会导致A修改失败
update user set name = "wumao",version = version + 1
where id = 2 and version = 1

测试一下MP的乐观锁插件
1、给数据库中加入version字段
在这里插入图片描述
2、给实体类加上对应的字段!

@Version//乐观锁version的注解
private Integer version;

3、注册组件

@MapperScan("com.aaa.mapper")//扫描mapper文件夹
@EnableTransactionManagement
@Configuration//配置类
public class MyBatisPlusConfig  {

    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }
}

4、测试乐观锁

//测试乐观锁
//成功案例
@Test
public void versionTest(){
    User user = userMapper.selectById(1L);
    user.setName("派大星");
    user.setEmail("admin@qq.com");
    userMapper.updateById(user);
}

//乐观锁失败案例----多线程
@Test
public void OptimisticLockerTest(){
    User user = userMapper.selectById(1L);
    user.setName("派大星111");
    user.setEmail("admin@qq.com");

    //模拟另外一个线程执行了插队操作
    User user2 = userMapper.selectById(1L);
    user.setName("派大星222");
    user.setEmail("admin@qq.com");
    userMapper.updateById(user2);

    userMapper.updateById(user);
}

12.MP配置类的完整代码

/**
 * 乐观锁和配置分页插件拦截器
 */
@MapperScan("cn.kgc.mapper")
@EnableTransactionManagement
@Configuration
public class MybatisPlusConfig {
    /**
     * 配置乐观锁
     * @return
     */
    public OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor(){
        return new OptimisticLockerInnerInterceptor();
    }
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor mybatisPlusInterceptor=new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor( optimisticLockerInnerInterceptor());
        mybatisPlusInterceptor.addInnerInterceptor( paginationInnerInterceptor());
        return mybatisPlusInterceptor;
    }

    /**
     * 配置分页插件
     */

    public PaginationInnerInterceptor  paginationInnerInterceptor(){
        return new PaginationInnerInterceptor(DbType.MYSQL);
    }

}

13.分页查询

分页在网站使用的十分之多!
1.原始的limit 进行分页
2.pageHelper 第三方插件
3.MP内置了分页插件
如何使用!
1、配置拦截器

//分页插件
@Bean
public PaginationInterceptor paginationInterceptor() {
    return new PaginationInterceptor();
}

2、分页查询

//分页查询
@Test
public void PageTest(){
    //参数一:当前页
    //参数二:页的大小
    //使用了分页插件之后,所有的分页操作也变得简单!
    Page<User> page = new Page<>(1,5);

    IPage<User> pages = userMapper.selectPage(page, null);
    pages.getRecords().forEach(System.out::println);
}

14.删除操作

基本的删除操作

//删除操作
@Test
public void deletTest(){
    userMapper.deleteById(1398260764485095426L);
}
//批量删除
@Test
public void deletBatchTest(){
    userMapper.deleteBatchIds(Arrays.asList(1398201429172178946L,5));
}
@Test
public void deletByMap(){
    HashMap<String, Object> map = new HashMap<>();
    map.put("name","泰裤辣");
    userMapper.deleteByMap(map);
}

我们在工作中会遇到一些问题:逻辑删除!
物理删除: 从数据库中直接移除
逻辑删除: 在数据库中没有被移除,而是通过一个变量让他无效!delete = 0 —> delete = 1
管理员可以查看被删除的记录!防止数据的丢失,类似于回收站!
测试一下:
1、在数据库中增加一个deleted字段,默认值是0
在这里插入图片描述2、在pojo中增加新的属性

//value = “未删除的值,默认值为0”;若设置为2,则查询时 where 后面自动拼接 is_del = 2
    //delval = “删除后的值,默认值为1”
    @TableLogic(value = "0",delval = "1")//逻辑删除
    private Integer deleted;

3、配置组件 (这个我没有配置,因为我的MP版本中LogicSqlInjector找不到)

@Bean//逻辑删除组件
public ISqlInjector sqlInjector(){
    return new LogicSqlInjector();
}
#配置标记逻辑删除的字段
mybatis-plus.global-config.db-config.logic-delete-field=deleted
#配置逻辑删除  1 删除  0 未删除
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0

4、测试一下:

  //逻辑删操作
    @Test
    public void deleteLogic(){
        int i = userMapper.deleteById(1L);
        System.out.println(i);
    }

记录依旧在数据库中!
以上的所有CRUD操作及其扩展操作,我们必须精通掌握!

15.service层接口UserService.java

public interface UserService {
    //查询所有用户
    List<User> findAllUser();
    //根据id查询一个用户
    User findUserById(Integer id);
    //添加用户
    boolean saveUser(User user);
    //根据id更新用户
    boolean modifyUserById(User user);
    //根据id删除用户
    boolean removeUserById(Integer id);
    //多条件查询用户
    List<User> findUserByCon(String userName,String email);
}

16.service层实现类UserServiceImpl.java

@Service
public class UserServiceImpl implements UserService {
    @Resource
    private UserMapper userMapper;

    /**
     * 添加用户
     * @param user
     * @return
     */
    @Override
    public boolean saveUser(User user) {
        int id=userMapper.insert(user);
        return id>0?true:false;
    }

    /**
     * 根据id更新用户
     * @param user
     * @return
     */
    @Override
    public boolean modifyUserById(User user) {
        int modifyResult=userMapper.updateById(user);
        return modifyResult>0?true:false;
    }

    /**
     * 根据id删除用户
     * @param id
     * @return
     */
    @Override
    public boolean removeUserById(Integer id) {
      int delResult=userMapper.deleteById(id);
        return delResult>0?true:false;
    }

    /**
     * 多条件分页查询用户
     * @param userName
     * @param email
     * @return
     */
    @Override
    public List<User> findUserByCon(String userName, String email) {
        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
        queryWrapper.like("name",userName);
        queryWrapper.like("email",email);
        Page<User> page=new Page<>(1,5);
        IPage<User> pages =userMapper.selectPage(page,queryWrapper);
        pages.getRecords().forEach(System.out::println);
        return pages.getRecords();
    }

    /**
     * 分页查询所有用户
     * @return
     */
    @Override
    public List<User> findAllUser() {
        Page<User> page=new Page<>(1,5);
        IPage<User> pages =userMapper.selectPage(page,null);
        return pages.getRecords();
    }

    /**
     * 根据id查询一个用户
     * @param id
     * @return
     */
    @Override
    public User findUserById(Integer id) {
        QueryWrapper wrapper=new QueryWrapper<>();
        wrapper.eq("id",id);
        User user= userMapper.selectOne(wrapper);
        return user;
    }
}

17. 控制层 IndexController.java

@Controller
public class IndexController {
    @RequestMapping("/")
    public String init(){
        return "redirect:/user/queryAllUser";
    }
}

18.UserController.java

package cn.kgc.controller;

import cn.kgc.pojo.User;
import cn.kgc.service.UserService;
import cn.kgc.utils.ResultDto;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.jws.WebParam;
import javax.xml.ws.RequestWrapper;
import java.util.List;

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

    @Resource
    private UserService userService;
    @GetMapping(value = {"queryAllUser"})
    public String queryAllUser(Model model){
        List<User> userList=userService.findAllUser();
        model.addAttribute("userList",userList);
        return "userList";
    }

    /**
     * 去增加页面
     * @return
     */
    @GetMapping("toAddUser")
    public String toAddUser(){
        return "addUser";
    }

    /**
     * 添加用户
     * @param user
     * @return
     */
    @RequestMapping("addUser")
    public String addUser(User user){
        boolean addResult=userService.saveUser(user);
        if (addResult) {
            return "redirect:/user/queryAllUser";
        }else{
            return "addUser";
        }
    }

    /**
     * 去修改页面
     * @return
     */
    @GetMapping("toModifyUser")
    public String toModifyUser(Integer id,Model model){
        User user = userService.findUserById(id);
        System.out.println(user);
        model.addAttribute("user",user);
        return "modifyUser";
    }
    /**
     * 修改用户
     * @return
     */
    @PostMapping("doModifyUser")
    @ResponseBody
    public ResultDto doModifyUser(@RequestBody User user){
        System.out.println(user);
        boolean modifyResult = userService.modifyUserById(user);
        ResultDto resultDto=new ResultDto();
        if (modifyResult) {
            resultDto.setCode(200);
            resultDto.setMessage("修改成功");
        }else{
            resultDto.setCode(222);
            resultDto.setMessage("修改失败");
        }

       return resultDto;
    }

    /**
     * 查看用户详情
     * @param model
     * @param id
     * @return
     */
    @RequestMapping("goDetailsUser")
    public String goDetailsUser(Model model,Integer id){
        User user = userService.findUserById(id);
        model.addAttribute("user",user);
        return "detailsUser";
    }

    /**
     * 删除用户
     * @param id
     * @return
     */
    @RequestMapping("delUser")
    @ResponseBody
    public ResultDto delUser(Integer id){
        System.out.println(id);
        boolean delResult=userService.removeUserById(id);
        ResultDto resultDto=new ResultDto();
        if (delResult){
            resultDto.setCode(200);
            resultDto.setMessage("删除成功");
        }else{
            resultDto.setCode(222);
            resultDto.setMessage("删除失败!");
        }
        return resultDto;
    }

    /**
     * 多条件查询所有用户
     * @param model
     * @param name
     * @param email
     * @return
     */
    @RequestMapping("searchUserInfo")
    public String searchUserInfo(Model model,String name,String email){
        System.out.println(name+"\t"+email);
        List<User> userList=userService.findUserByCon(name,email);
        model.addAttribute("userList",userList);
        model.addAttribute("queryEmail",email);
        model.addAttribute("queryName",name);
        return "userList";
    }
}

20. resources目录下template目录下的页面

1.首页userlist.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link type="text/css" th:href="@{/css/common.css}" rel="stylesheet"/>
    <link type="text/css" th:href="@{/css/userList.css}" rel="stylesheet" />
</head>
<body>
    <div align="center" id="userCon">
        <h2>用户信息</h2>
        <div class="addUserBtnCon" style="text-align: left;width: 900px">
            <button class="addUserBtn" th:onclick="addUser()">&nbsp;&nbsp;</button>
        </div>
        <div class="queryCon">
            姓名:<input th:placeholder="请输入姓名" name="queryName" class="queryUserName" th:value="${queryName}"/>&nbsp;&nbsp;&nbsp;邮箱:<input name="queryEmail" class="queryUserEmail" th:value="${queryEmail}"/><button type="button" class="queryInfoBtn" th:onclick="queryUser()">搜索</button>
        </div>
        <table width="1000">
            <tr align="center">
                <th>编号</th>
                <th>名字</th>
                <th>年龄</th>
                <th>邮箱</th>
                <th>操作</th>
            </tr>
            <tr align="center" th:each="u:${userList}">
                <td th:text="${u.id}"></td>
                <td  th:text="${u.name}"></td>
                <td  th:text="${u.age}"></td>
                <td  th:text="${u.email}"></td>
                <td>
                    <button type="button" class="detailsUserBtn" th:onclick="detailsUser([[${u.id}]])">详情</button>
                    <button type="button" class="modifyUserBtn" th:onclick="modifyUser([[${u.id}]])">修改</button>
                    <button type="button" class="delUserBtn" th:onclick="delUser(this,[[${u.id}]])">删除</button>
                </td>
            </tr>
        </table>
    </div>
<script type="text/javascript" th:src="@{/js/jquery-3.6.1.js}"></script>
<script type="text/javascript">
    //去添加页面
    function addUser(){
       location.href="/user/toAddUser";
    }
    //去修改页面
    function modifyUser(id){
        location.href="/user/toModifyUser?id="+id;
    }
    //去用户详情页面
    function detailsUser(id){
        location.href="/user/goDetailsUser?id="+id;
    }
    //删除用户
    function delUser(dom,id){
        console.log(id);
        let result=confirm("确认要删除吗?");
        if (result){
            $.get("/user/delUser","id="+id,function(res){
                console.log(res);
                if(res.code==200){
                    alert("删除成功!");
                    $(dom).parent().parent().remove();
                }else{
                    alert("删除失败!")
                }
            },"json");
        }else{
            alert("您取消了删除操作!");
        }
    }
    //搜索
    function queryUser(){
        let uName=$(".queryUserName").val();
        let uEmail=$(".queryUserEmail").val();
        console.log(uName+"==="+uEmail);
        location.href="/user/searchUserInfo?name="+uName+"&email="+uEmail;
    }
</script>
</body>
</html>
21.添加用户addUser.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link type="text/css" th:href="@{/css/common.css}" rel="stylesheet"/>
    <link type="text/css" th:href="@{/css/userList.css}" rel="stylesheet" />
</head>
<body>
    <div>
        <h2>添加用户信息</h2>
        <form th:action="@{/user/addUser}" th:method="post">
           <p>姓名:<input name="name" class="name" /></p>
            <p>年龄:<input name="age" class="age" /></p>
            <p>邮箱:<input name="email" class="email" /></p>
            <button class="addUserBtn">添加</button>
            <button type="reset" class="addUserBtn">重置</button>
        </form>
    </div>
</body>
</html>
22.用户详情detailsUser.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="detailsUserCon">
    <h2>用户详细信息</h2>
    <form id="detailsForm">
        <p>姓名:<input name="name" class="name" th:value="${user.name}" /></p>
        <p>年龄:<input name="age" class="age" th:value="${user.age}" /></p>
        <p>邮箱:<input name="email" class="email" th:value="${user.email}" /></p>
    </form>
</div>

</body>
</html>
23.修改用户页面modifyUser.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="modifyUserCon">
    <h2>修改用户信息</h2>
    <form id="modifyForm">
        <input type="hidden" name="version" class="version" th:value="${user.version}" />
        <input type="hidden" name="id" class="id" th:value="${user.id}" />
        <p>姓名:<input name="name" class="name" th:value="${user.name}" /></p>
        <p>年龄:<input name="age" class="age" th:value="${user.age}" /></p>
        <p>邮箱:<input name="email" class="email" th:value="${user.email}" /></p>
        <button class="addUserBtn" type="button" th:onclick="doModifyUser()">修改</button>
        <button type="reset" class="addUserBtn">重置</button>
    </form>
</div>
<script type="text/javascript" th:src="@{/js/jquery-3.6.1.js}"></script>
<script type="text/javascript">
    function doModifyUser(){
        var id=$(".id").val();
        var userName=$(".name").val();
        var age=$(".age").val();
        var email=$(".email").val();
        var version=$(".version").val();
        let obj={"id":id,"name":userName,"age":age,"email":email,"version":version};
        $.ajax({
            url:"/user/doModifyUser",
            type:"post",
            data:JSON.stringify(obj),
            dataType:"json",
            contentType:"application/json;charset=UTF-8",
            success:function(res){
               if (res.code==200){
                   alert("修改成功");
                   location.href="/user/queryAllUser";
               }else {
                   alert("修改失败");
               }
            },
            error:function (){
                alert("系统发生异常,请联系管理员!");
            }
        });
    }
</script>
</body>
</html>

24.页面效果

在这里插入图片描述
需要源码的评论联系即可!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值