Java 操作数据库

JDBC

  • JDBC:(Java DataBase Connectivity),就是使用 Java 语言操作关系型数据库的一套 API。
  • 本质:
    • sun 公司官方定义的一套操作所有关系型数据库的规范,即接口。
    • 各个数据库厂商去实现这一套接口,提供数据库驱动 jar 包。
    • 我们可以使用这一套接口(JDBC)编程,真正执行的代码是驱动 jar 包中的实现类。

入门程序

  • 需求:基于 JDBC 程序,执行 update 语句 update user set age = 25 where id = 1
  • 步骤:
    • 准备工作:创建一个 maven 项目,引入依赖;并准备数据库表 user。
    • 代码实现:编写 JDBC 程序,操作数据库
import org.junit.jupiter.api.Test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class JdbcTest {

    /**
     * JDBC 入门程序
     */
    @Test
    public void testUpdate() throws ClassNotFoundException, SQLException {
        // 1. 注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");

        // 2. 获取数据库连接
        String url = "jdbc:mysql://localhost:3306/web01";
        String user = "root";
        String password = "115248";
        Connection connection = DriverManager.getConnection(url, user, password);

        // 3. 获取 SQL 语句执行对象
        Statement statement = connection.createStatement();

        // 4. 执行 SQL
        String sql = "update user set age = 25 where id = 1";
        int count = statement.executeUpdate(sql);// DML
        System.out.println("该操作受影响的行数:" + count);

        // 5. 释放资源
        statement.close();
        connection.close();

    }
}

查询数据

  • 需求:基于 JDBC 执行如下 select 语句,将查询结果封装到 User 对象中。
  • SQL:select * from user where username = 'daqiao' and password = '123456'
  • ResultSet(结果集对象):ResultSet rs = statement.executeQuery()
    • next():将光标从当前位置向前移动一行,并判断当前行是否为有效行,返回值为 boolean。
      • true:有效行,当前行有数据
      • false:无效行,当前行没有数据
    • getXxx(...):获取数据,可以根据列的编号获取,也可以根据列名获取(推荐)。
  • 结果解析步骤:
while (resultSet.next()) {
    int id = resultSet.getInt("id");
    // ... 省略
}
@Test
public void testQuery(){
    Connection connection = null;
    PreparedStatement statement = null;
    ResultSet resultSet = null;
    try {
        Class.forName("com.mysql.cj.jdbc.Driver");
        connection = DriverManager.getConnection(URL, USER, PASSWORD);
        String sql = "select * from user where username = ? and password = ?";// 预编译 SQL,防止 SQL 注入
        statement = connection.prepareStatement(sql);
        statement.setString(1, "daqiao");
        statement.setString(2, "123456");
        resultSet = statement.executeQuery();
        while (resultSet.next()){
            User user = new User(
                resultSet.getInt("id"),
                resultSet.getString("username"),
                resultSet.getString("password"),
                resultSet.getString("name"),
                resultSet.getInt("age")
            );
            System.out.println(user);
        }
    }catch(ClassNotFoundException | SQLException e){
        e.printStackTrace();
    }finally{
        try{
            if(resultSet != null)
                resultSet.close();
            if(statement != null)
                statement.close();
            if(connection != null)
                connection.close();
        }catch(SQLException e){
            e.printStackTrace();
        }
    }
}

预编译 SQL

PreparedStatement ps = conn.prepareStatement("SELECT * FROM user WHERE username = ? AND password = ?");
ps.setString(1, "linchong");
ps.setString(2, "123456");
ResultSet resultSet = pstmt.executeQuery();
  • 优势一:可以防止 SQL 注入,更安全

    SQL 注入:通过控制输入来修改事先定义好的 SQL 语句,以达到执行代码对服务器进行攻击的方法。

  • 优势二:性能更高

MyBatis

  • MyBatis 是一款优秀的持久层框架,用于简化 JDBC 的开发。
  • MyBatis 本是 Apache 的一个开源项目 iBatis,2010年这个项目由 apache 迁移到了 google code,并且改名为 MyBatis。2013年11月迁移到 Github。
  • 官网:https://mybatis.org/mybatis-3/zh_CN/index.html

入门项目:使用 Mybatis 查询所有用户数据

  • 准备工作:
    1. 创建 SpringBoot 工程、引入 Mybatis 相关依赖
    2. 准备数据库表 user、实体类 User
    3. 配置 Mybatis(在 application.properties 中数据库连接信息)
  • 编写 Mybatis 程序:编写 Mybatis 的持久层接口,定义 SQL(注解 / XML)
  • 提示:Mybatis 的持久层接口命名规范为 XxxMapper,也称为 Mapper 接口
package com.faxont.mapper;

import com.faxont.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.List;

@Mapper // 应用程序在运行时,会自动地为该接口创建一个实现类对象(代理对象),并且会自动将该实现类对象存入 IOC 容器 - bean
public interface UserMapper {

    /**
     * 查询所有用户
     * @return
     */
    @Select("select * from `user`")
    public List<User> findAll();
}
package com.faxont;

import com.faxont.mapper.UserMapper;
import com.faxont.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest
class SpringbootMybatisQuickstartApplicationTests {

	@Autowired
	private UserMapper userMapper;

	@Test
	public void testFindAll() {
		List<User> userList = userMapper.findAll();
		userList.forEach(System.out::println);
	}

}

数据库连接池

  • 数据库连接池是个容器,负责分配,管理数据库连接(Connection)。

  • 它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个。

  • 释放空闲时间超过最大空闲时间的连接,来避免因为没有释放连接而引起的数据库连接遗漏。

  • 优势:

    1. 资源重用
    2. 提升系统响应速度
    3. 避免数据库连接遗漏
  • 标准接口:DataSource

    • 官方(sun)提供的数据库连接池接口,由第三方组织实现此接口。
    • 功能:获取连接 Connection getConnection() throws SQLException;
  • 常见产品:

    C3P0 DBCP Druid HiKari(SpringBoot 默认)

  • Druid(德鲁伊)

    • Druid 连接池是阿里巴巴开源的数据库连接池项目
    • 功能强大,性能优秀,是 Java 语言最好的数据库连接池之一
  • 切换数据库连接池

<!-- pom.xml -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.19</version>
</dependency>
# application.properties
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql://localhost:3306/web
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=1234

删除用户-delete

  • 需求:根据 ID 删除用户信息
  • SQL:delete from user where id = 5;
  • Mapper 接口:
@Delete("delete from user where id = #{id}")
public void deleteById(Integer id);

// 返回值为影响的行数
@Delete("delete from user where id = #{id}")
public Integer deleteById(Integer id);
  • 注意:DML 语句执行完毕的返回值,表示该 DML 语句执行完毕影响的行数。
  • Mybatis 中的 # 号与 $ 号:
符号 说明 场景 优缺点
# 占位符。执行时,会将#{...}替换为?,生成预编译 SQL 参数值传递 安全、性能高(推荐)
$ 拼接符。直接将参数拼接在 SQL 语句中,存在 SQL 注入问题 表名、字段名动态设置时使用 不安全、性能低

新增用户-insert

  • 需求:添加一个用户
  • SQL:insert into user(username, password, name, age) values ('zhouyu', '123456', '周瑜', 20);
  • Mapper 接口:
@Insert("insert into user(username, password, name, age) values (#{username}, #{password}, #{name}, #{age})")
public void insert(User user);

修改用户-update

  • 需求:根据 ID 更新用户信息
  • SQL:update user set username = 'zhouyu', password = '123456', name = '周瑜', age = 20 where id = 1
  • Mapper 接口:
@Update("update user set username=#{username}, password=#{password}, name=#{name}, age=#{age} where id=#{id}")
public void update(User user);

查询用户-select

  • 需求:根据用户名和密码查询用户信息
  • SQL:select * from user where username = 'zhouyu' and password = '666888';
  • Mapper 接口:
    • @Param 注解的作用是为接口的方法形参起名字的。
@Select("select * from user where username=#{username} and password=#{password}")
public User findByUsernameAndPassword(@Param("username") String username, @Param("password") String password);
  • 说明:基于官方骨架创建的 springboot 项目中,接口编译时会保留方法形参名,@Param注解可以省略(#{形参名})。
@Select("select * from user where username=#{uname} and password=#{pwd}")
public User findByUsernameAndPassword(String uname, String pwd);

XML 映射配置

  • 在 Mybatis 中,既可以通过注解配置 SQL 语句,也可以通过 XML 配置文件配置 SQL 语句。
  • 默认规则:
    1. XML 映射文件的名称与 Mapper 接口名称一致,并且将 XML 映射文件和 Mapper 接口放置在相同包下(同包同名)。
    2. XML 映射文件的 namespace 属性与 Mapper 接口全限定名一致。
    3. XML 映射文件中 sql 语句的 id 与 Mapper 接口中的方法名一致,并保持返回类型一致。
  • 那在 Mybatis 的开发中,到底使用注解开发还是使用 XML 开发呢?
    • 使用 Mybatis 的注解,主要是来完成一些简单的增删改查功能。如果需要实现复杂的 SQL 功能,建议使用 XML 来配置映射语句。
    • 官方说明:https://mybatis.net.cn/getting-started.html

辅助配置

  • 配置 XML 映射文件的位置:
# application.properties
# 指定 XML 映射配置文件的位置
mybatis.mapper-locations=classpath:mapper/*.xml
  • MybatisX 是一款基于 IDEA 的快速开发 Mybatis 的插件,为效率而生。

配置文件格式

  • SpringBoot 项目提供了多种属性配置方式(properties、yaml、yml)。
# application.properties
# 臃肿、层级结构不清晰
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/web01
spring.datasource.username=root
spring.datasource.password=1234
# application.yaml / application.yml
# 简洁、数据为中心
spring:
	datasource:
		driver-class-name: com.mysql.jdbc.Driver
		url: jdbc:mysql://localhost:3306/web01
		username: root
		password: 1234

yml 配置文件

  • 格式:
    • 数值前边必须有空格,作为分隔符
    • 使用缩进表示层级关系,缩进时,不允许使用 Tab 键,只能用空格(idea 中会自动将 Tab 转换为空格)
    • 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
    • # 表示注释,从这个字符一直到行尾,都会被解析器忽略
  • 定义对象 / Map集合:
user:
	name: 张三
	age: 18
	password: 123456
  • 定义数组 / List / Set 集合:
hobby:
 - java
 - game
 - sport
  • 注意:在 yml 格式的配置文件中,如果配置项的值是以0开头的,值需要使用 ' ' 引起来,因为以0开头在 yml 中表示8进制的数据。
posted @ 2026-06-04 14:17  弋湖  阅读(16)  评论(0)    收藏  举报