【代码审计】Java数据库操作

0x00 版权声明

JAVA基础系列是笔者学习@炼石星球的笔记,大部分文字描述取自星球内发布的教程文件,仅作学习。

0x01 Java数据库连接简介

Java数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口(位于jdk的java.sql中)。通常说的JDBC是面向关系型数据库的,提供了诸如查询、更新、删除、增加数据库中数据的方法。在使用时候需要导入具体的jar包,不同数据库需要导入的jar包不同。JDBC与MySQL进行连接交互,通常为以下6个流程:

  1. 注册驱动 (仅仅做一次)
  2. 建立连接(Connection)
  3. 创建运行SQL的语句(Statement)
  4. 运行语句
  5. 处理运行结果(ResultSet)
  6. 释放资源

0x02 Demo

创建数据库jdbcdemo并向其中添加数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
CREATE DATABASE jdbcdemo;

USE jdbcdemo;

**CREATE TABLE `user` (

`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '唯一ID',

`username` varchar(25) NOT NULL COMMENT '用户名',

`password` varchar(25) NOT NULL COMMENT '密码',

PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

INSERT INTO user(id,username,password) VALUES (1, "admins","admins");

INSERT INTO user(id,username,password) VALUES (2, "root", "root");

INSERT INTO user(id,username,password) VALUES (3, "admin","admin@123");**

使用select * from user;查询表中数据:

https://zebpic-1301715962.cos.ap-nanjing.myqcloud.com/blog/202210131000222.png

0x03 创建Java项目

创建SpringInitializr项目,选择JAVA8版本,勾选JDBC API和Mysql Driver,等待项目创建成功

在main.java.com.example.jdbcdemo目录新建DdbcDemo.class文件,键入代码:

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
package com.example.jdbcdemo;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class JdbcDemo {
public static void main(String[] args) throws Exception {
// 注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 获取连接
String url = "jdbc:mysql://localhost:3306/jdbcdemo?useUnicode=true&characterEncoding=utf8";
String user = "root";
String password = "root";
Connection conn = DriverManager.getConnection(url, user, password);
Statement stmt = conn.createStatement();
String sql = "SELECT * FROM user";
ResultSet rs = stmt.executeQuery(sql);
while(rs.next()) {
System.out.println("==================");
System.out.println(rs.getInt("id"));
System.out.println(rs.getString("username"));
System.out.println(rs.getString("password"));
}
// 回收资源
rs.close();
stmt.close();
conn.close();
}
}

运行Controller:

https://zebpic-1301715962.cos.ap-nanjing.myqcloud.com/blog/202210131017503.png

如果出现

Exception in thread “main” java.lang.RuntimeException: java.sql.SQLException: The server time zone value ‘xxx’ is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the ‘serverTimezone’ configuration property) to use a more specifc time zone value if you want to utilize time zone support. 错误,是因为使用的mysql时区不同,临时修改为本地时区:

mysql数据set global time_zone = ‘+8:00’;

重新运行即可。

0x04 Mybatis操作数据库

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

01 创建数据库并写入数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
CREATE DATABASE mybatisdemo;

USE mybatisdemo;

CREATE TABLE `user` (

`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '唯一ID',

`username` varchar(25) NOT NULL COMMENT '用户名',

`password` varchar(25) NOT NULL COMMENT '密码',

PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

INSERT INTO user(id,username,password) VALUES (1, "admins","admins");

INSERT INTO user(id,username,password) VALUES (2, "root", "root");

INSERT INTO user(id,username,password) VALUES (3, "admin","admin@123");

select * from user;

02 创建SpringBoot项目

新建项目,选择Spring Initializr,Java8版本。

选择依赖,勾选Spring Web、JBDC API、Mybatis Framework、Mysql Driver,共计四个依赖,等待项目创建成功。

接着根据不同作用类创建对应的代码包:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
src.main.java.com.example.mybatisdemo.controller

src.main.java.com.example.mybatisdemo.entity

src.main.java.com.example.mybatisdemo.mapper

src.main.java.com.example.mybatisdemo.service.impl

src.main.resources.mapper

controller:Controller层

service:业务逻辑层

service/impl:service的实现

entity:实体类,作用一般是和数据表做映射

mapper:数据操作层 DAO

在entiy目录新建User.class,键入代码:

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
package com.example.mybatisdemo.entity;

public class User {
private int id;
private String username;
private String password;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String name) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", password=" + password + "]";
}
}

在mapper目录下新建UserMapper.class,键入代码:

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
package com.example.mybatisdemo.mapper;

import com.example.mybatisdemo.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
public interface UserMapper {
/**
* 新增用户
* @param user
* @return
*/
public boolean addUser(User user);
/**
* 删除用户
* @param userName
* @return
*/
public boolean delUser(String userName);
/**
* 修改用户
*@param user
*@return
* */
public boolean updateUser(User user);
/**
* 单个查询
* @param id
* @return
*/
public User getUser(int id);
/**
* 查询全部
* @return
*/
public List<User> getUsers();
}

在resources.mapper目录新建UserMapper.xml文件,键入代码:

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
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "<http://mybatis.org/dtd/mybatis-3-mapper.dtd>">
<mapper namespace="com.example.mybatisdemo.mapper.UserMapper">
<!-- 添加用户 -->
<insert id="addUser" parameterType="com.example.mybatisdemo.entity.User">
insert into user(id, username, password) values(#{id}, #{username}, #{password})
</insert>
<!-- 删除用户 -->
<delete id="delUser" parameterType="String">
delete from user WHERE username = #{username}
</delete>
<!-- 修改用户 -->
<update id="updateUser" parameterType="com.example.mabatisdemo.entity.User">
update user set username = #{username}, password = #{password},
where id = #{id}
</update>
<!-- 根据主键查询用户 -->
<select id="getUser" resultType="com.example.mybatisdemo.entity.User" parameterType="int">
select * from user where id=#{id}
</select>
<!-- 查询全部数据 -->
<select id="getUsers" resultType="com.example.mybatisdemo.entity.User">
select * from user
</select>
</mapper>

在service目录新建UserService.class,键入代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.example.mybatisdemo.service;

import com.example.mybatisdemo.entity.User;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public interface UserService {
// 添加数据
public boolean addUser(User user);
// 删除数据
public boolean delUserByName(String userName);
// 修改数据
public boolean updateUserByUserId(User user);
// 根据id查询数据
public User getUser(int id);
// 查询全部数据
public List<User> getUsers();
}

在service.impl目录新建UserServiceImpl.class文件,键入代码:

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
47
48
49
50
51
52
53
54
55
56
package com.example.mybatisdemo.service.impl;

import com.example.mybatisdemo.entity.User;
import com.example.mybatisdemo.mapper.UserMapper;
import com.example.mybatisdemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
/**
* 添加用户
* */
@Override
public boolean addUser(User user) {
boolean flag;// 默认值是false
flag = userMapper.addUser(user);
return flag;
}
/**
* 根据id删除用户
* */
@Override
public boolean delUserByName(String userName) {
boolean flag;// 默认值是false
flag = userMapper.delUser(userName);
return flag;
}
/**
* 修改用戶
* */
@Override
public boolean updateUserByUserId(User user) {
boolean flag;// 默认值是fals
flag = userMapper.updateUser(user);
return flag;
}
/**
* 根据id获取用户
* */
@Override
public User getUser(int id) {
User user = userMapper.getUser(id);
return user;
}
/**
* 查询全部数据
* */
@Override
public List<User> getUsers() {
List<User> users = userMapper.getUsers();
return users;
}
}

在controller目录新建UserController.class,键入代码:

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import com.example.mybatisdemo.entity.User;
import com.example.mybatisdemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Controller
@RestController
public class UserController {
@Autowired
private UserService service;
/**
* 新增用户
* @param user
* @return
*/
@RequestMapping(value="/add", method=RequestMethod.POST)
@ResponseBody
public String addUser(User user){
boolean flag = service.addUser(user);
if (flag) {
return "success";
} else {
return "faile";
}
}
/**
* 删除用户
*
* @param name
* @return
* */
@RequestMapping(value="/del", method=RequestMethod.POST)
@ResponseBody
public String delUserByName(@RequestParam("name") String userName)
{
boolean flag = service.delUserByName(userName);
if (flag) {
return "success";
} else {
return "faile";
}
}
/**
* 修改用户
*
* @param User
* @return
* */
@RequestMapping(value="/updata", method=RequestMethod.POST)
@ResponseBody
public String updateUserByName(User user) {
boolean flag = service.updateUserByUserId(user);
if (flag) {
return "success";
} else {
return "faile";
}
}
/**
* 单个查询
* @param id
* @return
*/
@RequestMapping(value="/get/{id}", method= RequestMethod.GET)
public User getUser(@PathVariable("id") int id){
User user = service.getUser(id);
return user;
}
/**
* 查询全部
* @return
*/
@RequestMapping(value="/getUser/list", method=RequestMethod.GET)
@ResponseBody // @ResponseBody - 返回json字符串
public List<User> getUsers(){
List<User> users = service.getUsers();
return users;
}
}

在Application.class种添加注解@MapperScan():

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

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.example.mybatisdemo.mapper")
public class MybatisdemoApplication {

public static void main(String[] args) {
SpringApplication.run(MybatisdemoApplication.class, args);
}

}

在resources.application.properties文件种,添加配置:

原始配置:

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
spring.application.name=mybatisdemo
# 应用服务 WEB 访问端口
server.port=8080
# 数据库驱动:
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 数据源名称
spring.datasource.name=defaultDataSource
# 数据库连接地址
spring.datasource.url=jdbc:mysql://localhost:3306/blue?serverTimezone=UTC
# 数据库用户名&密码:
spring.datasource.username=***
spring.datasource.password=***
#下面这些内容是为了让MyBatis映射
#指定Mybatis的Mapper文件
mybatis.mapper-locations=classpath:mappers/*xml
#指定Mybatis的实体目录
mybatis.type-aliases-package=com.example.mybatisdemo.mybatis.entity
server.port=8080
## 数据源配置
spring.datasource.url=jdbc:mysql://localhost:3306/mybatisdemo?useUnicode=true&characterEncoding=utf8
## 下面是数据库连接账户密码,设置成自己的
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
## Mybatis 配置
## mybatis.typeAliasesPackage 配置为com.example.demo.dao,指向实体类包路径。
mybatis.typeAliasesPackage=com.example.mybatisdemo.dao
## mybatis.mapperLocations 配置为 classpath 路径下 mapper 包下,* 代表会扫描
所有 xml 文件。
mybatis.mapperLocations=classpath:mapper/*.xml

启动项目,访问接口:

1
2
3
http://localhost:8080/get/3

http://localhost:8080/getUser/list

https://zebpic-1301715962.cos.ap-nanjing.myqcloud.com/blog/202210171716895.png