ZhuangRenyang / blog

蝉时雨网站文章仓库
https://ovoz.cn
3 stars 0 forks source link

Mybatis框架 #47

Open ZhuangRenyang opened 1 year ago

ZhuangRenyang commented 1 year ago

Mybatis

  1. 创建boot2-2工程 , 创建工程时需要勾选3个依赖分别是:

    a. Web --> Spring Web

    b. SQL --> Mybatis Framework

    c. SQL --> MySQL Driver

  2. 在application.properties配置文件中书写连接数据库的信息

    spring.datasource.url=jdbc:mysql://localhost:3306/empdb?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
    
    spring.datasource.username=root
    
    spring.datasource.password=root

    User

    package cn.tedu.boot22.entity;
    
    public class User {
       private Integer id;
       private String username;
       private String password;
       private String nickname;
    
       public Integer getId() {
           return id;
       }
    
       public void setId(Integer id) {
           this.id = id;
       }
    
       public String getUsername() {
           return username;
       }
    
       public void setUsername(String username) {
           this.username = username;
       }
    
       public String getPassword() {
           return password;
       }
    
       public void setPassword(String password) {
           this.password = password;
       }
    
       public String getNickname() {
           return nickname;
       }
    
       public void setNickname(String nickname) {
           this.nickname = nickname;
       }
    
       @Override
       public String toString() {
           return "User{" +
                   "id=" + id +
                   ", username='" + username + '\'' +
                   ", password='" + password + '\'' +
                   ", nickname='" + nickname + '\'' +
                   '}';
       }
    }
    

    Hero

    package cn.tedu.boot22.entity;
    
    public class Hero {
       private Integer id;
       private String name;
       private Integer money;
    
       public Integer getId() {
           return id;
       }
    
       public void setId(Integer id) {
           this.id = id;
       }
    
       public String getName() {
           return name;
       }
    
       public void setName(String name) {
           this.name = name;
       }
    
       public Integer getMoney() {
           return money;
       }
    
       public void setMoney(Integer money) {
           this.money = money;
       }
    
       @Override
       public String toString() {
           return "Hero{" +
                   "id=" + id +
                   ", name='" + name + '\'' +
                   ", money=" + money +
                   '}';
       }
    }
    

创建index页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>首页</h1>
    <a href="/add.html">添加英雄</a>
    <a href="/delete.html">删除英雄</a>
    <a href="/select">查询英雄</a>
</body>
</html>

创建add页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>添加英雄页面</h1>
    <form action="/add">
        <input type="text" name="name" placeholder="英雄名">
        <input type="text" name="money" placeholder="英雄价格">
        <input type="submit" value="添加">
    </form>
</body>
</html>

创建delete页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>请输入要删除的英雄名称</h1>
    <form action="/delete">
        <input type="text" name="name">
        <input type="submit" value="删除">
    </form>
</body>
</html>

创建接口

HeroMapper

package cn.tedu.boot22.mapper;

import cn.tedu.boot22.entity.Hero;
import org.apache.ibatis.annotations.*;

import java.util.List;

@Mapper //Mybatis框架提供的注解,会创建实现类
public interface HeroMapper {
    /**
     * #{xxx}会从下面方法中的参数列表中找到同名的变量,如果没有同名的变量则进入对象中查找同名
     * 的成员变量的get方法
     * mybatis框架根据此方法声明生成具体的实现类的实现方法,方法内部就是JDBC代码
     */
    @Insert("insert into hero values(null,#{name},#{money})")
    void insert(Hero hero);

    @Delete("delete from hero where name = #{name}")
    void deleteByName(String name);

    @Select("select * from hero")
    List<Hero> select();

    @Update("update hero set name = #{name},money = #{money} where id = #{id}")
    void update(Hero hero);
}

创建update页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>修改英雄页面</h1>
    <form action="/update">
        <input type="text" name="id" placeholder="请输入修改的id">
        <input type="text" name="name" placeholder="名字">
        <input type="text" name="money" placeholder="价格">
        <input type="submit" value="修改">
    </form>
</body>
</html>

创建HeroController

package cn.tedu.boot22.controller;

@Controller
public class HeroController {
    /**
     * 自动注入/自动装配注解的作用:Spring框架结合mybatis框架会自动的将HeroMapper生成一个实现类和
     * 实现内部的方法,并且会自动实例化此对象,并交给Spring容器管理
     * required = false 告诉idea编译器此对象是非必须的
     */
    @Autowired(required = false)
    HeroMapper mapper;

    @RequestMapping("add")
    @ResponseBody
    public String add(Hero hero) {
        System.out.println("hero:"+hero);
        mapper.insert(hero);
        return "添加完成";
    }

    @RequestMapping("delete")
    @ResponseBody
    public String delete(String name) {
        mapper.deleteByName(name);
        return "删除完成";
    }

    @RequestMapping("select")
    @ResponseBody
    public String select() {
        List<Hero> list = mapper.select();
        return list.toString();
    }

    @RequestMapping("update")
    @ResponseBody
    public String update(Hero hero) {
        mapper.update(hero);
        return "修改完成";
    }
}

Mybatis框架添加英雄步骤:

  1. 创建boot2-2, 添加三个依赖

  2. 在application.properties配置文件中添加内容

  3. 停止之前工程, 运行新工程测试是否能正常运行

  4. 创建index.html 页面里面添加超链接 , 添加英雄 , 访问地址为add.html

  5. 创建add.html页面里面添加form表单 , 请求地址为 /add

  6. 创建controller.HeroController, 里面添加@Controller注解,添加@RequestMapping注解处理 /add请求并添加add方法,

  7. 创建entity.Hero实体类 并提供get和set方法 还有tostring方法

  8. 在HeroController的add方法参数列表中声明Hero对象 , 用来接收传递过来的参数 ,此时打桩输出hero对象 检查是否接收到了参数

  9. 创建mapper.HeroMapper接口, 里面添加@Mapper注解, 声明一个insert方法通过@Insert注解修饰,注解里面添加插入数据的SQL语句

  10. 在HeroController里面 通过@Autowired注解把HeroMapper装配进来, 在add方法里面调用mapper.insert方法把接收到的hero对象传递进去, 重启工程测试即可!

删除英雄步骤:

  1. 在首页中添加删除英雄超链接 访问地址为 delete.html

  2. 创建delete.html页面 在里面添加form表单 提交地址为/delete

  3. 在HeroController 中创建delete方法 处理路径为/delete 参数列表中声明name 接收页面传递过来的名字

  4. 在HeroMapper里面添加deleteByName方法 通过@Delete注解修饰,里面填写 删除的SQL语句

  5. 在HeroController里面的delete方法中调用mapper的deleteByName方法

修改英雄步骤:

  1. 在首页添加修改英雄超链接, 地址为update.html页面

  2. 创建update.html页面 并添加form表单 提交地址为/update

  3. 在Controller中添加update方法 处理/update请求

  4. 在HeroMapper里面添加update方法 通过@Update注解进行修饰,里面添加修改的SQL语句

  5. 在HeroController里面的update方法中调用mapper的update方法把接收到的hero对象传递到方法中

查询英雄步骤:

  1. 在首页添加查询的超链接,请求地址为/select

  2. 在HeroController中添加select方法处理/select请求

  3. 在HeroMapper里面添加select方法用@Select注解进行修饰,里面写查询的SQL语句

  4. 在HeroController的select方法中 调用mapper的select方法,把查询到的List集合返回给客户端展示

商品表的增删改查

use empdb;

create table product(id int primary key auto_increment,title varchar(100),price double(10,2),sale_count int)charset=utf8;
  1. 创建boot3-1工程 , 添加三个依赖

  2. 从之前工程中复制application.properties配置文件的信息到新工程, 启动工程测试是否成功

  3. 创建index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>商品管理首页</h1>
    <a href="/insert.html">添加商品</a>
    <a href="/select">查询商品</a>
    <a href="/update.html">修改商品</a>

    <hr>
    <a href="/helloAxios.html">异步请求测试</a>
</body>
</html>

创建insert.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>添加商品页面</h1>
    <form action="/insert">
        <input type="text" name="title" placeholder="商品标题">
        <input type="text" name="price" placeholder="商品价格">
        <input type="text" name="saleCount" placeholder="商品销量">
        <input type="submit" value="添加">
    </form>
</body>
</html>

创建update.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>修改商品页面</h1>
    <form action="/update">
        <input type="text" name="id" placeholder="请输入修改商品的id">
        <input type="text" name="title" placeholder="商品标题">
        <input type="text" name="price" placeholder="商品价格">
        <input type="text" name="saleCount" placeholder="商品销量">
        <input type="submit" value="修改">
    </form>
</body>
</html>

创建ProductController

package cn.tedu.boot31.controller;

//@Controller
//@ResponseBody //此注解相当于在每个方法上都添加了ResponseBody注解
@RestController //=@Controller + @ResponseBody
public class ProductController {
    @Autowired
    ProductMapper mapper;

    @RequestMapping("insert")
    public String insert(Product product) {
        mapper.insert(product);
        return "添加完成!<a href='/'>返回首页</a>";
    }

    @RequestMapping("select")
    public String select() {
        List<Product> list = mapper.select();
        String html = "<table border=1>";
        html+="<caption>商品列表</caption>";
        html+="<tr><th>id</th><th>标题</th><th>价格</th><th>销量</th><th>操作</th></tr>";
        for (Product p : list) {
            html+="<tr>";
            html+="<td>"+p.getId()+"</td>";
            html+="<td>"+p.getTitle()+"</td>";
            html+="<td>"+p.getPrice()+"</td>";
            html+="<td>"+p.getSaleCount()+"</td>";
            html+="<td><a href='/delete?id="+p.getId()+"'>删除</a></td>";
            html+="</tr>";
        }
        html+="</table>";
        return html;
    }

    @RequestMapping("delete")
    public String delete(int id) {
        mapper.deleteById(id);
        return "删除完成!<a href='/select'>返回列表页面</a>";
    }

    @RequestMapping("update")
    public String update(Product product) {
        mapper.update(product);
        return "修改完成<a href='/select'>返回列表页面</a>";
    }
}

创建Product

package cn.tedu.boot31.entity;

public class Product {
    private Integer id;
    private String title;
    private Double price;
    private Integer saleCount;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    public Integer getSaleCount() {
        return saleCount;
    }

    public void setSaleCount(Integer saleCount) {
        this.saleCount = saleCount;
    }

    @Override
    public String toString() {
        return "Product{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", price=" + price +
                ", saleCount=" + saleCount +
                '}';
    }
}

创建ProductMapper

package cn.tedu.boot31.mapper;

@Mapper
public interface ProductMapper {

    @Insert("insert into product values(null,#{title},#{price},#{saleCount})")
    void insert(Product product);

    @Select("select * from product")
    @Result(column = "sale_count",property = "saleCount")
    List<Product> select();

    @Delete("delete from product where id = #{id}")
    void deleteById(int id);

    @Update("update product set title = #{title},price = #{price},sale_count=#{saleCount} where id = #{id}")
    void update(Product product);
}

同步请求和异步请求

客户端发出请求的几种方式

  1. 通过浏览器的地址栏中发出请求 同步请求
  2. 通过html页面中的超链接发出请求 同步请求
  3. 通过html页面中的form表单发出请求 同步请求
  4. 通过前端框架发出请求 异步请求

客户端如何发出异步请求

  1. 通过Axios框架发出异步请求

  2. 此框架就是一个普通的js文件 , 页面需要使用此框架时需要将此文件引入到页面中

  3. axios框架地址 , 下载axios.min.js文件

    <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>

static目录下创建js目录 , 将axios.min.js和vue.js放入此目录中

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div>
        <h1>{{info}}</h1>
        <input type="button" value="测试异步请求get" @click="f1()">
        <input type="button" value="测试异步请求post" @click="f2()">
    </div>
    <script src="js/vue.js"></script>
    <script src="js/axios.min.js"></script>
    <script>
        let v = new Vue({
            el:"div",
            data:{
                info:"测试Vue!"
            },
            methods:{
                f1(){
                    axios.get("/hello1Axios?info=tom").then(function (response) {
                        //response代表服务器的响应对象
                        //response.data代表服务器响应的数据
                        alert(response.data);
                    })
                },
                f2(){
                    //发出异步post请求
                    axios.post("/hello2Axios",{info:"刘德华"}).then(function (response) {
                        alert(response.data);
                    })
                }
            }
        })
    </script>
</body>
</html>

AxiosController

package cn.tedu.boot31.controller;

@RestController
public class AxiosController {

    @RequestMapping("hello1Axios")
    public String hello1(String info) {
        return "请求成功! info="+info;
    }

    /**
     * @RequestBody 注解作用:当客户端发出post请求并且提交的是自定义对象时,服务器端接收参数
     * 必须使用此注解,否则获取不到传递过来的参数
     */
    @RequestMapping("hello2Axios")
    public String hello2(@RequestBody String info) {
        return "请求成功! info="+info;
    }
}

Get请求和Post请求

注册登录步骤 :

  1. 创建工程boot3-2 , 添加三个依赖

  2. 从之前工程中复制application.properties里面的连接数据库的信息 , 复制完之后立即启动工程 , 测试是否创建成功 , 如果工程启动不起来 , 检查报错是不是因为端口被占用 , 如果不是 , 刷新maven再次启动 , 如果还是启动不了 , 删除工程重新创建新工程 , 直至启动成功

  3. 创建index.html页面 , 在里面添加两个超链接访问注册和登录页面

  4. 创建reg.html页面 , 在页面中引入vue和axios两个框架文件 , 从之前工程中复制js文件夹(检查里面是不是包含这两个框架文件) , 在页面中点击按钮时向/reg发出异步请求 , 同时把用户输入的信息提交给服务器,然后在then方法里面判断返回的response.data值为1代表注册成功 , 显示首页 , 值为2代表用户名已存在

  5. 创建controller.UserController并且创建entity.User实体类

  6. 在Controller里面添加reg方法处理/reg请求 , 声明User变量用来接收传递过来的用户信息

  7. 创建mapper.UserMapper , 在里面提供两个方法 , 分别是 selectByUsername和insert两个方法

  8. 回到Controller里面把UserMapper通过@Autowired装配进来 , 在reg方法中先调用mapper里面的selectByUsername方法 , 判断返回值是否有值 , 如果有值则给客户端返回2代表用户名已存在 , 如果没有值 , 则调用mapper的insert方法 , 把用户信息保存到数据库 , 最后返回1代表注册成功

  9. 下一步开始实现登录功能 , 步骤类似注册 , 先创建login.html页面 , 然后在页面中通过Vue对内容进行管理 , 当点击登录按钮的时候向/login发出异步请求 , 同样把输入的用户信息提交给服务器 , 在then方法中判断response.data的值为1代表登录成功显示首页 , 值为2代表用户名不存在, 值为3代表密码错误

  10. 在Controller里面添加login方法处理/login请求 , 声明User对象接收传递过来的用户信息 , 在方法中调用mapper的selectByUsername 通过用户输入的用户名查询对应的用户信息 , 如果没有查询到 , 直接返回2代表用户名不存在 , 如果查询到了 , 继续通过输入的密码和查询到的密码比较如果一致返回1代表登录成功 , 如果不一致返回2 , 代表密码错误.

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>工程首页</h1>
    <a href="/reg.html">注册</a>
    <a href="/login.html">登录</a>
</body>
</html>

将上个项目中的js目录复制到新项目中的static目录下

reg.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>注册页面</h1>
    <div>
        <input type="text" v-model="user.username" placeholder="请输入用户名">
        <input type="text" v-model="user.password" placeholder="请输入密码">
        <input type="text" v-model="user.nickname" placeholder="请输入昵称">
        <input type="button" value="注册" @click="reg()">
    </div>
    <script src="js/vue.js"></script>
    <script src="js/axios.min.js"></script>
    <script>
        let v = new Vue({
            el:"div",
            data:{
                user:{
                    username:"",
                    password:"",
                    nickname:""
                }
            },
            methods:{
                reg(){
                    //发出post请求
                    axios.post("/reg",v.user).then(function (response) {
                        //alert(response.data);
                        //判断如果注册成功,返回首页
                        if (response.data == 1) {
                            alert("注册成功!");
                            //让浏览器跳转到首页
                            location.href="/";
                        }else {
                            alert("用户名已存在!")
                        }
                    })
                }
            }
        })
    </script>
</body>
</html>

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>登录页面</h1>
    <div>
        <input type="text" v-model="user.username" placeholder="用户名">
        <input type="text" v-model="user.password" placeholder="密码">
        <input type="button" value="登录" @click="login()">
    </div>
    <script src="js/vue.js"></script>
    <script src="js/axios.min.js"></script>
    <script>
        let v = new Vue({
            el:"div",
            data:{
                user:{
                    username:"",
                    password:""
                }
            },
            methods: {
                login() {
                    //发出异步请求
                    axios.post("/login",v.user).then(function (response) {
                        if (response.data == 1) {
                            alert("登录成功!");
                            location.href="/";
                        }else if(response.data == 2){
                            alert("用户名不存在!")
                        }else {
                            alert("密码错误!");
                        }
                    })
                }
            }

        })
    </script>
</body>
</html>

UserController

package cn.tedu.boot32.controller;

@RestController
public class UserController {

    @Autowired
    UserMapper mapper;

    @RequestMapping("reg")
    public int reg(@RequestBody User user) {
        //获取用户输入的用户名到数据库中查询用户信息
        User u = mapper.selectByUsername(user.getUsername());
        if (u != null) {
            return 2; //2代表用户名已存在
        }
        mapper.insert(user);
        return 1; //1注册成功
    }

    @RequestMapping("login")
    public int login(@RequestBody User user) {
        //获取用户输入的用户名到数据库中查询用户信息
        User u = mapper.selectByUsername(user.getUsername());
        if (u != null) {//代表查询到了用户信息
            //判断用户输入的密码和查询的密码是否一致
            if (user.getPassword().equals(u.getPassword())) {
                return 1; //登录成功
            }
            return 3; //密码错误
        }
        return 2; //用户名不存在
    }
}

User实体类

package cn.tedu.boot32.entity;

public class User {
    private Integer id;
    private String username;
    private String password;
    private String nickname;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", nickname='" + nickname + '\'' +
                '}';
    }
}

UserMapper

package cn.tedu.boot32.mapper;

@Mapper
public interface UserMapper {
    //因为返回值为一个对象,要求查询回来的结果必须是0或者1条
    @Select("select * from user where username = #{username}")
    User selectByUsername(String username);

    @Insert("insert into user values(null,#{username},#{password},#{nickname})")
    void insert(User user);
}