一、实验目的
- 区块链中的公钥私钥以及钱包;
- 学习mysql;
- 学习Java中ORM框架mybatis;
- 完成书本模块;
二、实验环境
- Windows 11
- IDEA java、maven、springboot
- navicat
- postman
三、实验步骤
第一部分 区块链中的公钥私钥以及钱包
拉取项目代码
1
git clone https://gitee.com/daitoulin/testmysql.git
在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>运行
EthUtils.java
进行公钥、私钥、钱包地址、签名的生成,签名是否有效验证。创建一个test类进行测试,使用
EthUtils类
的.getWallet()
方法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16package 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
7public String toString() {
return "EthWallet{" +
"publicKey='" + publicKey + '\'' +
", privateKey='" + privateKey + '\'' +
", address='" + address + '\'' +
'}';
}
第二部分:学习mysql
一)MySQL基本配置使用
mysql安装,解压到路径下
D:\MySql\mysql-8.0.20-winx64
,配置环境变量,在系统变量PATH中添加
D:\MySql\mysql-8.0.20-winx64\bin\
创建配置文件
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=utf8mb4windows+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
记住自定义密码,待会用到登录
启动MySQL服务端
net start mysql
登录MySQL:
mysql -uroot -p
修改MySQL密码:
ALTER USER 'root'@'localhost' IDENTIFIED BY '你的密码';
二)navicat连接本地MySQL数据库进行操作
建立连接
新建数据库
利用SQL语言,创建数据表
插入操作
数据查询
更新修改
第三部分 学习Java中ORM框架mybatis
一)项目引入mybatis
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>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
22spring.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确认我们这个需要提交什么参数
使用register接口进行用户注册
1
2
3
public ResponseEntity<JSONObject> save({} 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
46package 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已经存在,请更改
⑥用户名为空如下
⑦通过consoller层校验,成功注册如下
使用
queryAllUser
接口查询所有存在的用户信息,不需要传参同样navicat连接MySQL数据库,可以同步查看到目前所有用户信息
使用
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
public ResponseEntity<JSONObject> login({ 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);
}①密码错误时如下
②成功登录
修改密码接口
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
33package 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>删除用户接口
/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
public ResponseEntity<JSONObject> deleteUser( { 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);
}
}删除后查看mybatis
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表
创建数据t_book表
1
2
3
4
5
6
7
8
9create 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
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层代码
public ResponseEntity<JSONObject> save({ 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);
}查看
t_book
表如下:接⼝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
public ResponseEntity<JSONObject> login({ 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);
}接⼝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代码
public ResponseEntity<JSONObject> queryBookByPublisher({ 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);
}
四、实验结果与讨论
生成钱包地址、公钥私钥;
mysql数据库配置,navicat进行连接;
java中ORM框架mybatis,用户模块;
完成书本模块测试、创建接口
五、总结
项目架构:运行TUserMapper.xml;userController—>userService—>userServicelmp—>TUserMapper.xml;consoller控制层校验,service,dao数据交互层有个xml格式映射三层。
这里用到一种驼峰命名法,book_name在代码中应当命名为bookName,否则会出现postman查询处理失败的情况,查出来book_name为null。
mybatis作用:
- 简化数据库操作;
- 灵活的SQL映射;
- 对象映射,mybatis将数据库查询结果映射到Java对象,支持复炸的对象关系映射,数据处理更加便捷。
@RequestBody 要以json形式提交,点开对象TUser确认我们这个需要提交什么参数
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
这里是mybatis数据库部署常见步骤: