AI+JavaWeb(四)MySQL+JDBC+MyBatis

MySQL+JDBC+MyBatis

MySQL

图形化工具:DataGrip

DataGrip是JetBrains旗下的一款数据库管理工具,是管理和开发MySQL、Oracle、PostgreSQL的理想解决方案。
DataGrip这款工具可以不用安装,因为Jetbrains公司已经将DataGrip这款工具的功能已经集成到了IDEA当中,所以我们就可以使用IDEA来作为一款图形化界面工具来操作Mysql数据库。

JDBC

Java DataBase Connectivity:Java语言操作关系型数据库的一套API。
image

入门程序

基本流程:

  1. 注册jdbc驱动
  2. 获取数据库连接
  3. 获取SQL语句执行对象(句柄)
  4. 通过句柄执行SQL语句
  5. 释放资源
    image
    如何查找MySQL的jdbc驱动类名?
    image
package com.zjq;


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 username = "root",password = "zjq.182";
        Connection conn = DriverManager.getConnection(url, username, password);

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

        //4.执行SQL
        int cnt = statement.executeUpdate("update user set age = 18 where id = 1");//DML
        System.out.println("SQL更新语句影响的记录数:" + cnt);

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

查询数据DQL

image
基本流程:

  1. 注册jdbc驱动
  2. 获取数据库连接
  3. 获取预编译查询语句的对象(句柄)并执行SQL语句
  4. 处理查询结果集
  5. 释放资源
@Test
public void testSelect() throws ClassNotFoundException, SQLException {
	// 1.注册驱动
	Class.forName("com.mysql.cj.jdbc.Driver");

	//2.获取数据库连接
	String url = "jdbc:mysql://localhost:3306/web01";//格式:协议名:数据库://地址:端口/数据库名
	String username = "root",password = "zjq.182";
	Connection conn = DriverManager.getConnection(url, username, password);
	PreparedStatement stmt = null;
	ResultSet rs = null;

	try{
		//3.获取SQL语句执行对象并执行SQL
		String sql = "SELECT * FROM user WHERE username = ? AND password = ?";
		stmt = conn.prepareStatement(sql);
		stmt.setString(1,"zjq");//注意:下标从1开始
		stmt.setString(2,"123456");

		//4.处理查询结果
		rs = stmt.executeQuery();
		while(rs.next()){
			User user = new User(
					rs.getInt("id"),
					rs.getString("username"),
					rs.getString("password"),
					rs.getString("name"),
					rs.getInt("age")
			);
			System.out.println(user);
		}
	}catch (SQLException exception){
		exception.printStackTrace();
	}finally {
		//5.释放资源
		rs.close();
		stmt.close();
		conn.close();
	}
}

预编译SQL

  1. 静态SQL(参数硬编码)
Statement statement = conn.createStatement();
int cnt = statement.executeUpdate("update user set age = 18 where id = 1");//DML
System.out.println("SQL更新语句影响的记录数:" + cnt);
  1. 预编译SQL(参数动态传递)
String sql = "SELECT * FROM user WHERE username = ? AND password = ?";
PrepareStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1,"zjq");//注意:下标从1开始
pstmt.setString(2,"123456");
ResultSet rs = pstmt.executeQuery();

注意:表名、字段名不可作为预编译的参数值,因为它们是SQL语法结构的一部分。

优势
  1. 可以防止SQL注入,更加安全

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

例如:

String sql = "SELECT * FROM user WHERE username = '" + input_name + "' AND password = '" + input_pwd + "'";

上面程序中,当输入的password为' or '1'='1时,整个SQL语句变为SELECT * FROM user WHERE username = 'ferwf' AND password = '' or '1'='1',WHERE始终为TRUE,使得无须输入正确的账密即可登录成功。
2. 性能更高
image

MyBatis

MyBatis是一款优秀的持久层框架,主要用于简化JDBC的开发,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。官方文档:https://mybatis.org/mybatis-3/zh_CN/index.html
image
image

入门程序

image
基本流程:

  1. 创建SpringBoot模块,引入Spring Web、Lombok、Mybatis、MySQL Driver等依赖项
    image
  2. 准备数据库表User和实体类User
package org.zjq.springboot_mybatis_01.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Integer id;
    private String username;
    private String password;
    private String name;
    private Integer age;
}
  1. 配置MyBatis(在application.properties中p配置数据库连接信息)
    注意:需要将.properties属性文件的默认编码设置为UTF-8
    image
spring.application.name=springboot_mybatis_01

# 配置数据库连接信息
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/web01
spring.datasource.username=root
spring.datasource.password=zjq.182
  1. 编写MyBatis的持久层接口
    UserMapper.java
package org.zjq.springboot_mybatis_01.mapper;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.zjq.springboot_mybatis_01.pojo.User;

import java.util.List;

@Mapper //运行时,会自动为该接口创建一个类对象(代理对象),且会自动将该实现类对象存入SpringBoot的IOC容器
public interface UserMapper {

    @Select("select * from user")
    public List<User> findAll();
}
  1. 编写springboot单元测试方法
package org.zjq.springboot_mybatis_01;

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

import java.util.List;

@SpringBootTest //SpringBoot单元测试的注解 - 会在单元测试运行时,加载springboot的环境-IOC容器
class SpringbootMybatis01ApplicationTests {

    @Autowired
    private UserMapper userMapper;

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

IDE辅助配置

idea辅助SQL语句编写的配置

默认在MyBatis中配的SQL语句是不识别的,可做如下配置:
image

idea配置MyBatis的日志输出

默认情况下,在Mybatis中执行SQL语句时,看不到执行日志。可在applications.properties配置文件中加入如下配置,即可查看日志:

# Mybatis的配置
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

image

JDBC vs Mybatis

image

数据库连接池

数据库连接池是一个容器,负责分配、管理数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立。
当某个连接的空闲时间超过最大空闲时间,连接池会对其释放,从而避免由于没有释放连接而引起的数据库连接泄漏。
image
优势:

  1. 资源复用
  2. 提升系统响应速度(避免重复建立连接)
  3. 避免数据库连接遗漏

标准接口:DataSource

官方提供的数据库连接池接口,由第三方组织实现此接口
功能:通过Connection getConnection() throws SQLException获取连接

常见产品

image
Hikari:Springboot默认提供的连接池
Druid:阿里巴巴开源的数据库连接池项目,是Java最好的数据库连接池之一

切换数据库连接池

由Hikari切换为Druid
pom.xml

<!--Druid连接池-->
<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>druid-spring-boot-starter</artifactId>
	<version>1.2.19</version>
</dependency>

application.properties

# 选择Druid作为数据库连接池的实现
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

增删改查操作

MyBatis SQL中的#号和$号

image
注意:表名、字段名不可作为预编译的参数值,因为它们是SQL语法结构的一部分。如需动态设置,只能使用拼接符$。

SQL注入示例

UserMapper.java

@Mapper //运行时,会自动为该接口创建一个类对象(代理对象),且会自动将该实现类对象存入SpringBoot的IOC容器
public interface UserMapper {
    @Select("select * from user where username = #{username} AND password = #{pwd}")
    public List<User> safe_login(String username,String pwd);

    @Select("select * from user where username = ${username} AND password = ${pwd}")
    public List<User> unsafe_login(String username,String pwd);
}

Test.java

@ParameterizedTest
    @CsvSource({
            "\"zjq\",\"\" OR '1'='1'",
    })
    public void loginTest(String username,String pwd){
        List<User> users = userMapper.unsafe_login(username,pwd);
        Assertions.assertEquals(0, users.size());
    }

删除

示例:根据id删除用户信息

@Delete("delete from user where id = #{id}")
    public Integer deleteById(Integer id);

返回值为Integer时表示:执行SQL语句影响的记录个数,即删除的记录个数,也可以为void

新增

示例:新增一个用户

@Insert("insert into user (username, password, name, age) values (#{username},#{password},#{name},#{age});")
    public Integer Insert(User user);

返回值为Integer时表示:执行SQL语句影响的记录个数,即成功新增的记录个数,也可以为void

更新

示例:根据ID更新用户信息

/*
更新用户的所有信息
 */
@Update("update user set username=#{username},password=#{password},name=#{name},age=#{age} where id=#{id}")
public Integer Update(User user);

/*
更新用户的单个字段信息
 */
@Update("update user set name=#{name} where id=#{id}")
public Integer Updatename(User user);

返回值为Integer时表示:执行SQL语句影响的记录个数,即被更新的记录个数,也可以为void

查询

示例:根据用户名和密码查询用户信息

@Select("select * from user where username = #{username} AND password = #{pwd}")
public User safe_login(@Param("username") String username,@Param("pwd") String pwd);

@Select("select * from user where username = ${username} AND password = ${pwd}")
public User unsafe_login(@Param("username") String username,@Param("pwd") String pwd);

注意:

  1. 基于官方骨架创建的Springboot项目中,接口编译时会保留方法形参名,@Param注解可以省略
  2. 返回值可以自定义,对于登录模块最多返回一条记录时,可定义返回值为User,当查询不到时返回null

XML映射配置

在Mybatis中,既可以通过注解配置SQL语句,也可以通过XML配置文件来配置SQL语句。

默认规则

  1. XML映射文件的名称与Mapper接口名称一致,且将XML映射文件和Mapper接口放置在相同包下(同名同包
    注意:Resource中定义多层目录是通过/来进行的,不能使用.
    image
  2. XML映射文件的namespace属性为Mapper接口全限定名
  3. XML映射文件中SQL语句的id与Mapper接口中的方法名一致,且返回类型一致,返回类型为单行查询结果的封装bean
    image

示例

将UserMapper中的方法使用XML映射配置文件改造
UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="org.zjq.springboot_mybatis_01.mapper.UserMapper">
<!--    注意:只有select类型语句有返回值,且返回值类型为单行查询记录的封装bean-->
    <select id="findAll" resultType="org.zjq.springboot_mybatis_01.pojo.User">
        select * from user
    </select>

    <select id="findByName" resultType="org.zjq.springboot_mybatis_01.pojo.User">
        select * from user where name = #{name}
    </select>

    <select id="safe_login" resultType="org.zjq.springboot_mybatis_01.pojo.User">
        select * from user where username = #{username} AND password = #{pwd}
    </select>

    <select id="unsafe_login" resultType="org.zjq.springboot_mybatis_01.pojo.User">
        select * from user where username = ${username} AND password = ${pwd}
    </select>

    <delete id="deleteById">
        delete from user where id = #{id}
    </delete>
    
    <insert id="Insert">
        insert into user (username, password, name, age) values (#{username},#{password},#{name},#{age});
    </insert>
    
    <update id="Update">
        update user set username=#{username},password=#{password},name=#{name},age=#{age} where id=#{id}
    </update>

    <update id="Updatename">
        update user set name=#{name} where id=#{id}
    </update>
</mapper>

UserMapper.java

package org.zjq.springboot_mybatis_01.mapper;

import org.apache.ibatis.annotations.*;
import org.zjq.springboot_mybatis_01.pojo.User;

import java.util.List;

@Mapper //运行时,会自动为该接口创建一个类对象(代理对象),且会自动将该实现类对象存入SpringBoot的IOC容器
public interface UserMapper {

//    @Select("select * from user")
    public List<User> findAll();

//    @Select("select * from user where name = #{name}")
    public List<User> findByName(String name);

//    @Select("select * from user where username = #{username} AND password = #{pwd}")
    public User safe_login(@Param("username") String username,@Param("pwd") String pwd);

//    @Select("select * from user where username = ${username} AND password = ${pwd}")
    public User unsafe_login(@Param("username") String username,@Param("pwd") String pwd);

//    @Delete("delete from user where id = #{id}")
    public Integer deleteById(Integer id);

//    @Insert("insert into user (username, password, name, age) values (#{username},#{password},#{name},#{age});")
    public Integer Insert(User user);

    /*
    更新用户的所有信息
     */
//    @Update("update user set username=#{username},password=#{password},name=#{name},age=#{age} where id=#{id}")
    public Integer Update(User user);

    /*
    更新用户的单个字段信息
     */
//    @Update("update user set name=#{name} where id=#{id}")
    public Integer Updatename(User user);
}

辅助配置

指定XML配置文件的位置

当XML配置文件与Mapper接口文件不在同一个包中,可通过在application.properties文件中指定XML文件的路径。
image

# 指定mybatis的XML映射配置文件的位置
# main中的java和resources目录下的文件编译后都会放在target的classes目录中,因此用classpath表示classes目录的路径
mybatis.mapper-locations=classpath:mapper/*.xml
IDEA中MybatisX插件

MybatisX是一款基于IDEA的快速开发Mybatis的插件,为效率而生。
MybatisX plugin Features:
mapper and xml can jump back and forth
mybatis.xml,mapper.xml prompt
mapper and xml support auto prompt like jpa (reference MybatisCodeHelperPro)
integrate mybatis generator Gui (copy from free mybatis plugin)

posted @ 2026-03-19 15:02  安河桥北i  阅读(1)  评论(0)    收藏  举报