JDBC与Mybatis

JDBC与Mybatis

1.0 连接数据库并操作

我们使用jdbc来操作Mysql数据库,首先需要在pom中引入mysql驱动并且导入Junit单元测试包

package com.javalearn;

import org.junit.jupiter.api.Test;

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

public class JDBCTest {
    @Test
    public void testUpdate() throws Exception {
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb","root","352532451");
        Statement statement=connection.createStatement();
        ResultSet resultSet =statement.executeQuery("select * from user");
        while (resultSet.next()){
            System.out.println(resultSet.getString("username"));
        }
        statement.close();
        connection.close();


    }
}

接着是使用Class注册驱动,注册驱动通过加载驱动类来执行内部的静态代码块,如果不注册驱动SPI也会帮我们自

动的注册完成

接着去创建连接对象,如果我们的mysql服务在本地,可以将localhost:3306 省略掉

接着获取执行对象,我们当前创建的是普通的sql执行对象,我们还可以创建预编译sql执行对象

然后执行数据库操作语句,如果想要执行查询操作就使用ececuteQuery 如果想要执行DDL和DML语句,也就是

增删改和定义表,则使用executeUpdate语句

使用executeUpdate 语句返回的是本次操作中受到影响的行号,使用ececuteQuery返回的是一个ResultSet

象,来存储接受到的结果,查询的结果可能是0行,也可能是多行next方法可以对当前行是否有值进行判断,如果

有就返回true,如果一条也没查到就返回false,无论是true还是false,执行完后都会自动的向下移动一行

获取数据可以通过下标或者列名,如果通过下标起始下标是1,需要根据数据的类型调用对应的get方法

如果需要查询多条数据我们一般放在对象中

我们如果要测试,像这样直接写死sql语句肯定是不行的,就要用到参数化测试:

package com.javalearn;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;
import org.junit.jupiter.params.provider.CsvSource;

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


public class JDBCTest {
    @ParameterizedTest
    @CsvSource({"admin, 1234","mysql, 111"})
    public void testUpdate(String username,String password) throws Exception {
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb","root","352532451");
        Statement statement=connection.createStatement();
        ResultSet resultSet =statement.executeQuery("select * from user where username='"+username+"' and password='"+password+"'");
        while (resultSet.next()){
            System.out.println(resultSet.getString("username"));
            System.out.println(resultSet.getString("password"));
        }
        statement.close();
        connection.close();


    }
}

但如果我们之前学习过网络安全相关知识的话,就能发现现在这种写法是存在安全风险的,很轻松的就可以进行

sql注入,所以我们要采取预编译的sql语句

下面是修改后的代码:

package com.javalearn;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;

import java.sql.*;


public class JDBCTest {
    @ParameterizedTest
    @CsvSource({"admin, 1234","mysql, 111"})
    public void testUpdate(String username,String password) throws Exception {
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb","root","352532451");
        PreparedStatement preparedStatement=connection.prepareStatement("select * from user where username=? and password =?");
        preparedStatement.setString(1,username);
        preparedStatement.setString(2,password);
        ResultSet resultSet = preparedStatement.executeQuery();
        while (resultSet.next()){
            System.out.println(resultSet.getString("username"));
            System.out.println(resultSet.getString("password"));
        }
        preparedStatement.close();
        connection.close();


    }
}

当前的这种写法因为通过使用预编译sql,做到了避免sql注入的效果,注意我们通过?替代我们本来要写入变量的

地方,通过下面的setString来赋字符串变量值,这里在内部做了处理,不单是简单拼接,为了适配sql语法在变量

替换时两侧加了引号

使用预编译sql 不仅可以避免sql注入,还可以减少编译次数,优化sql操作的性能

1.1 Mybatis入门

使用jdbc操作数据库还是太麻烦了,所以我们将使用持久层框架mybatis来操作数据库

首先我们创建一个sping项目,将Mybits和mysql驱动都导入到依赖中

然后再resources中配置mybatis设置

spring.application.name=Mybatis
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=111

接下来创建实体类

我们创建entity包来存储实体类

package com.javalearn.mybatis.entity;

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

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Integer id;
    private String name;
    private String username;
    private String password;
    private String gender;
    private Integer age;
}

然后创建mapper包写mapper接口

package com.javalearn.mybatis.mapper;

import com.javalearn.mybatis.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.List;

@Mapper //程序启动时会自动生成该接口的代理对象交由ioc管理
public interface UserMapper {
    @Select("select * from user")
    public List<User> list();
}

将sql语句写到注释里,因为使用的是select所以使用select注解

使用Mapper接口替代Dao

再去测试接口

创建测试类

package com.javalearn.mybatis;

import com.javalearn.mybatis.entity.User;
import com.javalearn.mybatis.mapper.UserMapper;
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
public class UserMapperTest {
    @Autowired
    private UserMapper userMapper;
    @Test
    public void listTest(){
        List<User> users=userMapper.list();
        for (User user : users) {
            System.out.println(user);
        }
    }
}

因为这里需要用到依赖注入,所以需要使用到@SpringBootTest来加载spingboot,默认是不在测试文件夹加载

但直接运行我们输出是看不到sql语句等信息的,如果想要看到就需要在配置文件加入

mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

将输出直接打印到控制台

测试类想要正确运行也需要在测试的启动类在一个包或者自包下

使用Mybatis和之前的jdbc对比,我们不需要自己取获得值创建实体类对象,而是自动去封装,不需要我们自己去

处理

1.2 数据库连接池

和线程池类似,Mybatis使用数据库连接池管理数据库连接对象优势是可以实现资源重用,提升系统响应速度,并

且可以避免数据库连接遗漏

SpringBoot使用的默认数据库连接池是hikari 国内使用较多的是阿里的Druid

想要使用Druid直接导入依赖后在配置文件加

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

即可切换

1.3基于xml执行sql语句

我们之前执行sql语句都是基于注解,还可以基于xml执行sql语句,我们执行的xml文件结构如下:

image-20250905212414419

xml文件需要和我们的mapper接口同包名同文件名,除了后缀不需要相同,需要注意在resources下无法创建包,

所以我们要按/来代替.创建文件夹

xml的内容如下:

<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.javalearn.mybatis.mapper.UserMapper">
    <select id="list" resultType="com.javalearn.mybatis.entity.User">
        select * from user;
    </select>
</mapper>

最上面引入的dtd文件对xml文件的内容做约束,namespace 声明了mapper 接口的全类名,id代之接口中的方

法,返回的数据类型也需要使用全类名,因为使用的是select方法,所以使用select标签/

1.4 数据封装

mybatis提供了自动封装功能,会将数据库返回的结果封装成实体类的数据,前提是字段名和属性名一致,如果字

段我们使用的_分割单词,属性使用驼峰,就需要开启转换的配置才能实现自动封装

mybatis.configuration.map-underscore-to-camel-case=true

需要在配置文件上加上这一行才能实现自动封装

除了自动我们也可也选择手动结果映射

使用@Results注解

@Results({
    @Result(column="",property=""),
})

将这个放到mapper接口的函数之上即可建立映射关系

posted @ 2025-09-06 23:43  折翼的小鸟先生  阅读(16)  评论(0)    收藏  举报