Likt's Blog

天空一直都在,是云来了又去。

0%

生成钱包地址公钥私钥,使用mysql以及Java的orm框架mybatis

一、实验目的

  1. 区块链中的公钥私钥以及钱包;
  2. 学习mysql;
  3. 学习Java中ORM框架mybatis;
  4. 完成书本模块;

二、实验环境

  • Windows 11
  • IDEA java、maven、springboot
  • navicat
  • postman

三、实验步骤

第一部分 区块链中的公钥私钥以及钱包

  1. 拉取项目代码

    1
    git clone https://gitee.com/daitoulin/testmysql.git
  2. 在pom.xml文件中引入web3j开源包,web3j包中内置了生成钱包地址公钥私钥的算法,我们只要调用就可以很便捷的生成。

    1
    2
    3
    4
    5
    6
    <!-- web3j依赖  用于生成eth钱包-->
    <dependency>
    <groupId>org.web3j</groupId>
    <artifactId>core</artifactId>
    <version>4.9.4</version>
    </dependency>
  3. 运行EthUtils.java进行公钥、私钥、钱包地址、签名的生成,签名是否有效验证。

    image-20241020234026864

  4. 创建一个test类进行测试,使用EthUtils类.getWallet()方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    package com.example.testmysql.utils;

    import com.example.testmysql.entity.EthWallet;

    import java.security.InvalidAlgorithmParameterException;
    import java.security.NoSuchAlgorithmException;
    import java.security.NoSuchProviderException;

    public class test {
    public static void main(String[] args) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchProviderException {
    EthWallet wallet=EthUtils.getWallet();
    System.out.println(wallet);

    }
    }

    这里还要进入Ethwallet类,加入一个toString方法,这样test.java才能成功运行,代码截图如下

    1
    2
    3
    4
    5
    6
    7
    public String toString() {
    return "EthWallet{" +
    "publicKey='" + publicKey + '\'' +
    ", privateKey='" + privateKey + '\'' +
    ", address='" + address + '\'' +
    '}';
    }

    image-20241020234807149

第二部分:学习mysql

一)MySQL基本配置使用
  1. mysql安装,解压到路径下D:\MySql\mysql-8.0.20-winx64

  2. 配置环境变量,在系统变量PATH中添加D:\MySql\mysql-8.0.20-winx64\bin\

  3. 创建配置文件my.ini配置文件,可以先后缀.txt,等内容输入之后更改后缀。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    [mysqld]
    # 设置3306端⼝
    port=3306
    # ⾃定义设置mysql的安装⽬录,即解压mysql压缩包的⽬录
    basedir=D:\work\mysql
    # ⾃定义设置mysql数据库的数据存放⽬录
    datadir=D:\work\mysql\data
    # 允许最⼤连接数
    max_connections=1000
    # 允许连接失败的次数,这是为了防⽌有⼈从该主机试图攻击数据库系统
    max_connect_errors=10
    # 服务端使⽤的字符集默认为UTF8
    character-set-server=utf8mb4
    # 创建新表时将使⽤的默认存储引擎
    default-storage-engine=INNODB
    # 默认使⽤“mysql_native_password”插件认证
    default_authentication_plugin=mysql_native_password
    # 去除mysql8对ONLY_FULL_GROUP_BY的限制
    sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISI
    ON_BY_ZERO,NO_ENGINE_SUBSTITUTION
    [mysql]
    # 设置mysql客户端默认字符集
    default-character-set=utf8mb4
    [client]
    # 设置mysql客户端连接服务端时默认使⽤的端⼝和默认字符集
    port=3306
    default-character-set=utf8mb4

    image-20241019160250803

  4. windows+R,CTRL+shift+enter进入管理员权限,进入目录D:\MySql\mysql-8.0.20-winx64\bin\

    • mysqld --install "MySQL" --defaults-file="D:\MySql\mysql-8.0.20-winx64\my.ini

    • 初始化mysql:mysqld --initialize --console

    • 记住自定义密码,待会用到登录

      image-20241019161840822

    • 启动MySQL服务端net start mysql

      image-20241019161924352

    • 登录MySQL:mysql -uroot -p

    • 修改MySQL密码:ALTER USER 'root'@'localhost' IDENTIFIED BY '你的密码';

      image-20241019162419606

二)navicat连接本地MySQL数据库进行操作
  1. 建立连接

    image-20241019162220024

  2. 新建数据库

    image-20241019162611427

  3. 利用SQL语言,创建数据表

    image-20241019163638689

  4. 插入操作

    image-20241019164040839

  5. 数据查询

    image-20241019164245613

  6. 更新修改

    image-20241019170554502

第三部分 学习Java中ORM框架mybatis

一)项目引入mybatis
  1. pom.xml中加入依赖

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <!--mybatis依赖 -->
    <dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.3.2</version>
    </dependency>
    <!-- Mysql驱动包 -->
    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.29</version>
    </dependency>

    image-20241019171003587

  2. application.properties中添加,注意可能存在修改点testdb,password

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    spring.application.name=testMysql
    server.port=8087
    ### mybatis
    mybatis.mapper-locations=classpath:/mybatis-mapper/*Mapper.xml
    mybatis.configuration.map-underscore-to-camel-case=true
    ### xxl-job, datasource
    spring.datasource.url=jdbc:mysql://localhost:3306/testdb?useUnicode=true&useSSL=false&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
    spring.datasource.username=root
    spring.datasource.password=123456
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    ### datasource-pool
    spring.datasource.type=com.zaxxer.hikari.HikariDataSource
    spring.datasource.hikari.minimum-idle=10
    spring.datasource.hikari.maximum-pool-size=30
    spring.datasource.hikari.auto-commit=true
    spring.datasource.hikari.idle-timeout=30000
    spring.datasource.hikari.pool-name=HikariCP
    spring.datasource.hikari.max-lifetime=900000
    spring.datasource.hikari.connection-timeout=10000
    spring.datasource.hikari.connection-test-query=SELECT 1
    spring.datasource.hikari.validation-timeout=1000

二)完成一个完整的用户模块

navicat连接MySQL数据库,postman连接本地服务端口,run TestMysqlApplication.java,

@RequestBody 要以json形式提交,点开对象TUser确认我们这个需要提交什么参数

  1. 使用register接口进行用户注册

    1
    2
    3
    @RequestMapping(value = "/register")
    public ResponseEntity<JSONObject> save(@RequestBody TUser user){}
    //@RequestBody注释意味着TUser提交参数要以json体形式提交,CTRL+鼠标左键进入查看需要提交哪些参数。

    ①查看TUser.java发现总共有五个参数但是只有三个要求用户输入注册username,password,nickname

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    package com.example.testmysql.entity;
    public class TUser {
    private int id;
    private String username;
    private String password;
    private String nickname;
    private String createTime;
    private int delStatus;
    public int getId() {
    return id;
    }
    public void setId(int 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;
    }
    public String getCreateTime() {
    return createTime;
    }
    public void setCreateTime(String createTime) {
    this.createTime = createTime;
    }
    public int getDelStatus() {
    return delStatus;
    }
    public void setDelStatus(int delStatus) {
    this.delStatus = delStatus;
    }
    }

    ②找到TUserMapper.xml中的save,有个insert标签,useGeneratedKyes主键自增,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <insert id="save" parameterType="com.example.testmysql.entity.TUser" useGeneratedKeys="true" keyProperty="id" >
    insert into t_user (
    `username`,
    `password`,
    `nickname`,
    `create_time`,
    `del_status`
    ) VALUES (
    #{username},
    #{password},
    #{nickname},
    #{createTime},
    #{delStatus}
    );
    </insert>

    ③JSON体提交形式如下:

    ④【postman选择post上传方式 url为http://localhost:8087/register】

    1
    2
    3
    4
    5
    {
    "username":"ting",
    "password":"123468899",
    "nickname":"070ltx"
    }

    ⑤已有用户进行注册会提示username已经存在,请更改

    image-20241021191653334

    ⑥用户名为空如下

    image-20241021191723351

    ⑦通过consoller层校验,成功注册如下

    image-20241021191843750

  2. 使用queryAllUser接口查询所有存在的用户信息,不需要传参

    image-20241021193024017

    同样navicat连接MySQL数据库,可以同步查看到目前所有用户信息

    image-20241021193122646

  3. 使用login接口进行用户登录,会对username、password进行校验,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    @RequestMapping(value = "/login")
    public ResponseEntity<JSONObject> login(@RequestBody TUser user){
    JSONObject jo = new JSONObject();

    if (user.getUsername() == null || "".equals(user.getUsername())){
    jo.setCode("-1");
    jo.setMsg("username不能为空");
    return new ResponseEntity<JSONObject>(jo, HttpStatus.OK);
    }
    if (user.getPassword() == null || "".equals(user.getPassword())){
    jo.setCode("-1");
    jo.setMsg("password不能为空");
    return new ResponseEntity<JSONObject>(jo, HttpStatus.OK);
    }

    TUser exist = userService.queryUserByUsername(user.getUsername());
    if (exist == null){
    jo.setCode("-1");
    jo.setMsg("username不存在,请先注册");
    return new ResponseEntity<JSONObject>(jo, HttpStatus.OK);
    }

    if (!MD5Utils.passwordIsTrue(user.getPassword(),exist.getPassword())){
    jo.setCode("-1");
    jo.setMsg("密码错误,请重试");
    return new ResponseEntity<JSONObject>(jo, HttpStatus.OK);
    }


    jo.setCode("1");
    jo.setMsg("登录成功");
    return new ResponseEntity<JSONObject>(jo, HttpStatus.OK);
    }

    ①密码错误时如下

    image-20241021195009253

    ②成功登录

    image-20241021195110613

  4. 修改密码接口updatePassword,这里针对UpdateUser类,需要用户上传三个属性username,oldPassword,newPassword

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    package com.example.testmysql.entity;

    public class UpdateUser {

    private String username;
    private String oldPassword;
    private String newPassword;

    public String getUsername() {
    return username;
    }

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

    public String getOldPassword() {
    return oldPassword;
    }

    public void setOldPassword(String oldPassword) {
    this.oldPassword = oldPassword;
    }

    public String getNewPassword() {
    return newPassword;
    }

    public void setNewPassword(String newPassword) {
    this.newPassword = newPassword;
    }
    }

    updatePassword

    1
    2
    3
    <update id="updatePassword" parameterType="com.example.testmysql.entity.UpdateUser">
    update t_user set password = #{newPassword} where username = #{username}
    </update>

    image-20241021200017076

  5. 删除用户接口/deleteUser校验username,password,状态置0,无法继续登录

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    @RequestMapping(value = "/deleteUser")
    public ResponseEntity<JSONObject> deleteUser(@RequestBody TUser user) {
    JSONObject jo = new JSONObject();

    if (user.getUsername() == null || "".equals(user.getUsername())){
    jo.setCode("-1");
    jo.setMsg("username不能为空");
    return new ResponseEntity<JSONObject>(jo, HttpStatus.OK);
    }
    if (user.getPassword() == null || "".equals(user.getPassword())){
    jo.setCode("-1");
    jo.setMsg("password不能为空");
    return new ResponseEntity<JSONObject>(jo, HttpStatus.OK);
    }

    TUser exist = userService.queryUserByUsername(user.getUsername());
    if (exist == null){
    jo.setCode("-1");
    jo.setMsg("username不存在,请先注册");
    return new ResponseEntity<JSONObject>(jo, HttpStatus.OK);
    }

    if (!MD5Utils.passwordIsTrue(user.getPassword(),exist.getPassword())){
    jo.setCode("-1");
    jo.setMsg("密码错误,请重试");
    return new ResponseEntity<JSONObject>(jo, HttpStatus.OK);
    }

    userService.deleteUser(user);

    jo.setCode("1");
    jo.setMsg("删除成功");
    return new ResponseEntity<JSONObject>(jo, HttpStatus.OK);
    }
    }

    image-20241021200402673

    删除后查看mybatis

    image-20241021204758106

    1
    2
    3
    <update id="deleteUser" parameterType="com.example.testmysql.entity.UpdateUser">
    update t_user set del_status = 0 where username = #{username}
    </update>

第四部分 完成书本模块

t_book表 字段:id,book_name 书名,price 价钱,publisher 出版社,status 状态0为借出,1为存在。

接⼝1:新增书本

接⼝2:输⼊书名,查询书籍是否存在

接⼝3:输⼊出版社名字,查询该出版社的所有书籍

一)创建t_book表
  1. 创建数据t_book表

    1
    2
    3
    4
    5
    6
    7
    8
    9
    create TABLE `t_book`(
    `id` int(11) not null AUTO_INCREMENT,
    `book_name` varchar(50) not null comment '书名',
    `price` float not null comment '价钱',
    `publisher` varchar(50) comment '出版社',
    `status` int(4) not null comment'状态0为借出,1为存在',
    PRIMARY KEY (`id`)
    );

二)创建接口
  1. 接口1:新增书本,即类似注册

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <!--接口代码-->
    <insert id="save" parameterType="com.example.testmysql.entity.TUser" useGeneratedKeys="true" keyProperty="id" >
    insert into t_book (
    `book_name`,
    `price`,
    `publisher`,
    `status`
    ) VALUES (
    #{book_name},
    #{price},
    #{publisher},
    #{status}
    );
    </insert>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    //controller层代码 
    @RequestMapping(value = "/register")
    public ResponseEntity<JSONObject> save(@RequestBody TUser user){
    JSONObject jo = new JSONObject();

    if (user.getBookName() == null || "".equals(user.getBookName())){
    jo.setCode("-1");
    jo.setMsg("书名不能为空");
    return new ResponseEntity<JSONObject>(jo, HttpStatus.OK);
    }
    if (user.getPrice() == null || "".equals(user.getPrice())){
    jo.setCode("-1");
    jo.setMsg("价格不能为空");
    return new ResponseEntity<JSONObject>(jo, HttpStatus.OK);
    }
    if (user.getPublisher() == null || "".equals(user.getPublisher())){
    jo.setCode("-1");
    jo.setMsg("作者名不能为空");
    return new ResponseEntity<JSONObject>(jo, HttpStatus.OK);
    }

    TUser exist = userService.queryBookByBookname(user.getBookName());
    if (exist != null){
    jo.setCode("-1");
    jo.setMsg("书名已存在,请更改");
    return new ResponseEntity<JSONObject>(jo, HttpStatus.OK);
    }
    user.setPrice(user.getPrice());
    user.setPublisher(user.getPublisher());
    user.setStatus(1);
    userService.save(user);

    jo.setCode("1");
    jo.setMsg("注册成功");
    return new ResponseEntity<JSONObject>(jo, HttpStatus.OK);

    }

    image-20241025195127568

    查看t_book表如下:

    image-20241025195801508

  2. 接⼝2:输⼊书名,查询书籍是否存在

    1
    2
    3
    4
    <!--接口代码-->
    <select id="queryBookByBookname" parameterType="string" resultType="com.example.testmysql.entity.TUser">
    select * from t_book where book_name = #{book_name} and status = 1
    </select>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    @RequestMapping(value = "/login")
    public ResponseEntity<JSONObject> login(@RequestBody TUser user){
    JSONObject jo = new JSONObject();

    if (user.getBookName() == null || "".equals(user.getBookName())){
    jo.setCode("-1");
    jo.setMsg("书名不能为空");
    return new ResponseEntity<JSONObject>(jo, HttpStatus.OK);
    }
    TUser exist = userService.queryBookByBookname(user.getBookName());
    if (exist == null){
    jo.setCode("-1");
    jo.setMsg("书名不存在,请先注册");
    return new ResponseEntity<JSONObject>(jo, HttpStatus.OK);
    }

    jo.setCode("1");
    jo.setMsg("这本书已经存在!");
    return new ResponseEntity<JSONObject>(jo, HttpStatus.OK);
    }

    image-20241025201046371

  3. 接⼝3:输⼊出版社名字,查询该出版社的所有书籍

    1
    2
    3
    <select id="queryBookByPublisher" parameterType="string" resultType="com.example.testmysql.entity.TUser">
    select * from t_book where publisher = #{publisher}
    </select>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    //controller代码
    @RequestMapping(value = "/queryBookByPublisher")
    public ResponseEntity<JSONObject> queryBookByPublisher(@RequestBody TUser user){
    JSONObject jo = new JSONObject();

    if (user.getPublisher() == null || "".equals(user.getPublisher())){
    jo.setCode("-1");
    jo.setMsg("出版商名不能为空");
    return new ResponseEntity<JSONObject>(jo, HttpStatus.OK);
    }

    List <TUser> exist = userService.queryBookByPublisher(user.getPublisher());

    jo.setCode("1");
    jo.setMsg("经由这家出版社出版的书籍有:");
    jo.setO(exist);
    return new ResponseEntity<JSONObject>(jo, HttpStatus.OK);
    }

    image-20241025204059725

四、实验结果与讨论

  1. 生成钱包地址、公钥私钥;

    image-20250112174200534

  2. mysql数据库配置,navicat进行连接;

    image-20250112174208445

  3. java中ORM框架mybatis,用户模块;

    image-20250112174215470

  4. 完成书本模块测试、创建接口

    image-20250112174222062

五、总结

  1. 项目架构:运行TUserMapper.xml;userController—>userService—>userServicelmp—>TUserMapper.xml;consoller控制层校验,service,dao数据交互层有个xml格式映射三层。

  2. 这里用到一种驼峰命名法,book_name在代码中应当命名为bookName,否则会出现postman查询处理失败的情况,查出来book_name为null。

  3. mybatis作用:

    • 简化数据库操作;
    • 灵活的SQL映射;
    • 对象映射,mybatis将数据库查询结果映射到Java对象,支持复炸的对象关系映射,数据处理更加便捷。
  4. @RequestBody 要以json形式提交,点开对象TUser确认我们这个需要提交什么参数

  5. MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

  6. 这里是mybatis数据库部署常见步骤:

    image-20241022233539052

-------------本文结束感谢您的阅读-------------