目录
配置 MyBatis 核心文件(mybatis-config.xml):
在 SQL 映射文件(UserMapper.xml)中添加删除语句:
一、JDBC 介绍
JDBC(Java Database Connectivity)即 Java 数据库连接,是 Java 语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。它由一组用 Java 语言编写的类和接口组成,使得 Java 程序能够与各种关系型数据库进行交互,如 MySQL、Oracle、SQL Server 等。通过 JDBC,开发人员可以在 Java 代码中执行 SQL 语句,处理数据库事务,获取查询结果等。
二、使用 JDBC 查询用户信息
下面是一个简单的使用 JDBC 查询用户信息的示例代码:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCUserQuery {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/mydb";
String user = "root";
String password = "password";
try (Connection connection = DriverManager.getConnection(url, user, password);
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("SELECT * FROM users")) {
while (resultSet.next()) {
int id = resultSet.getInt("id");
String username = resultSet.getString("username");
String email = resultSet.getString("email");
System.out.println("ID: " + id + ", Username: " + username + ", Email: " + email);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
在上述代码中,首先通过
DriverManager.getConnection()
方法获取数据库连接,然后创建Statement
对象用于执行 SQL 语句,最后执行executeQuery()
方法获取ResultSet
结果集,并遍历结果集输出用户信息。
三、ResultSet 结果集
ResultSet
是 JDBC 中用于存储数据库查询结果的对象。它就像一个表格,每一行代表一条记录,每一列代表一个字段。ResultSet
提供了一系列方法来访问其中的数据,如getInt()
、getString()
、getDouble()
等,根据字段的数据类型来获取相应的值。同时,ResultSet
有一个游标,默认位于第一行之前,通过next()
方法可以将游标移动到下一行,当游标指向有效行时,才能获取该行的数据。当游标移动到结果集的末尾(即next()
方法返回false
)时,表示结果集遍历结束。
四、预编译 SQL - SQL 注入问题
SQL 注入是一种常见的安全漏洞,攻击者通过在输入参数中插入恶意的 SQL 代码,从而改变原本 SQL 语句的逻辑,获取敏感信息或进行非法操作。例如,在一个用户登录验证的场景中,如果使用普通的 SQL 语句拼接用户输入:
String username = request.getParameter("username");
String password = request.getParameter("password");
String sql = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";
如果用户输入的
username
为' OR '1'='1
,那么拼接后的 SQL 语句就变成了SELECT * FROM users WHERE username = '' OR '1'='1' AND password = ''
,这样无论密码是否正确,都能成功登录。预编译 SQL 可以有效防止 SQL 注入问题。预编译 SQL 是将 SQL 语句先发送到数据库进行编译,然后再将参数传递给已经编译好的语句。在 JDBC 中,使用
PreparedStatement
来实现预编译 SQL:
String url = "jdbc:mysql://localhost:3306/mydb";
String user = "root";
String password = "password";
String username = request.getParameter("username");
String password = request.getParameter("password");
try (Connection connection = DriverManager.getConnection(url, user, password);
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM users WHERE username =? AND password =?")) {
preparedStatement.setString(1, username);
preparedStatement.setString(2, password);
ResultSet resultSet = preparedStatement.executeQuery();
// 处理结果集
} catch (SQLException e) {
e.printStackTrace();
}
在上述代码中,使用
?
作为占位符,然后通过setString()
等方法设置参数,这样数据库会将参数作为普通值处理,而不会将其解析为 SQL 代码,从而避免了 SQL 注入问题。
五、预编译 SQL - 性能更高
预编译 SQL 除了能防止 SQL 注入外,还具有更高的性能。当使用普通的
Statement
执行 SQL 语句时,数据库每次都需要对 SQL 语句进行语法解析、查询优化等操作。而预编译 SQL 会将 SQL 语句先编译好,后续如果执行相同结构的 SQL 语句,只需要传递参数即可,数据库不需要再次进行语法解析和查询优化,从而提高了执行效率。特别是在需要频繁执行相同结构 SQL 语句的场景下,预编译 SQL 的性能优势更加明显。
六、JDBC 增删改操作
以下是使用 JDBC 进行增删改操作的示例代码:
插入数据:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class JDBCInsert {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/mydb";
String user = "root";
String password = "password";
try (Connection connection = DriverManager.getConnection(url, user, password);
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO users (username, email, password) VALUES (?,?,?)")) {
preparedStatement.setString(1, "newuser");
preparedStatement.setString(2, "newuser@example.com");
preparedStatement.setString(3, "newpassword");
int rowsInserted = preparedStatement.executeUpdate();
if (rowsInserted > 0) {
System.out.println("A new user was inserted successfully!");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
更新数据:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class JDBCUpdate {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/mydb";
String user = "root";
String password = "password";
try (Connection connection = DriverManager.getConnection(url, user, password);
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE users SET password =? WHERE username =?")) {
preparedStatement.setString(1, "newpassword123");
preparedStatement.setString(2, "newuser");
int rowsUpdated = preparedStatement.executeUpdate();
if (rowsUpdated > 0) {
System.out.println("User password was updated successfully!");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
删除数据:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class JDBCDelete {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/mydb";
String user = "root";
String password = "password";
try (Connection connection = DriverManager.getConnection(url, user, password);
PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM users WHERE username =?")) {
preparedStatement.setString(1, "newuser");
int rowsDeleted = preparedStatement.executeUpdate();
if (rowsDeleted > 0) {
System.out.println("User was deleted successfully!");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
七、MyBatis 介绍
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集,它可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJO(Plain Old Java Objects,普通的 Java 对象)映射成数据库中的记录。MyBatis 对 JDBC 进行了封装,使得数据库操作更加简洁、高效,同时也提高了代码的可维护性和可扩展性。
八、MyBatis 入门程序
以下是一个简单的 MyBatis 入门示例:
引入依赖:
在 Maven 项目的
pom.xml
文件中添加 MyBatis 和数据库驱动依赖:
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.9</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
</dependencies>
创建实体类:
public class User {
private int id;
private String username;
private String email;
private String password;
// 省略 getters 和 setters
}
创建 SQL 映射文件(UserMapper.xml):
<?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.UserMapper">
<select id="getUserById" parameterType="int" resultType="com.example.User">
SELECT * FROM users WHERE id = #{id}
</select>
</mapper>
配置 MyBatis 核心文件(mybatis-config.xml):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="UserMapper.xml"/>
</mappers>
</configuration>
编写测试代码:
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class MyBatisTest {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.getUserById(1);
System.out.println(user.getUsername());
}
}
}
九、MyBatis 辅助配置 - SQL 提示
为了在开发过程中获得更好的 SQL 提示,可以使用一些 IDE 插件,如在 IntelliJ IDEA 中安装 MyBatis Log Plugin 等插件,这些插件可以将 MyBatis 执行的 SQL 语句打印出来,并对 SQL 语法进行高亮显示和提示,方便开发人员调试和优化 SQL 语句。同时,也可以在 SQL 映射文件中使用
<!-- -->
进行注释,对 SQL 语句的功能和逻辑进行说明,提高代码的可读性。
十、MyBatis 辅助配置 - 日志输出
MyBatis 支持配置日志输出,以便更好地了解程序的执行情况。可以通过在
mybatis-config.xml
文件中配置日志工厂来实现。例如,使用 Log4j 作为日志框架:
引入 Log4j 依赖:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.14.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.14.1</version>
</dependency>
配置 Log4j 配置文件(log4j2.xml)
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="Console"/>
</Root>
<Logger name="com.example" level="debug"/>
</Loggers>
</Configuration>
在 MyBatis 配置文件中启用日志:
<configuration>
<settings>
<setting name="logImpl" value="LOG4J2"/>
</settings>
<!-- 其他配置 -->
</configuration>
这样,MyBatis 执行的 SQL 语句等信息就会按照配置的日志级别进行输出。
十一、MyBatis 数据库连接池
MyBatis 支持使用不同的数据库连接池,如
POOLED
连接池(默认)、UNPOOLED
连接池等。POOLED
连接池会管理一定数量的数据库连接,当需要连接时从连接池中获取,使用完毕后再归还到连接池,这样可以避免频繁地创建和销毁数据库连接,提高性能。在mybatis-config.xml
文件中配置POOLED
连接池的示例如下:
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
</dataSource>
</environment>
此外,也可以使用第三方连接池,如 HikariCP、C3P0 等,只需要在项目中引入相应的依赖,并在 MyBatis 配置文件中进行相应的配置即可。
十二、MyBatis 增删改查 - 删除用户
以下是使用 MyBatis 实现删除用户的示例:
在 SQL 映射文件(UserMapper.xml)中添加删除语句:
<mapper namespace="com.example.UserMapper">
<!-- 其他语句 -->
<delete id="deleteUserById" parameterType="int">
DELETE FROM users WHERE id = #{id}
</delete>
</mapper>
在接口(UserMapper.java)中添加对应的方法:
public interface UserMapper {
// 其他方法
int deleteUserById(int id);
}
编写测试代码:
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class MyBatisDeleteTest {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
int rowsDeleted = userMapper.deleteUserById(1);
if (rowsDeleted > 0) {
System.out.println("User was deleted successfully!");
}
sqlSession.commit();
}
}
}
在上述代码中,通过
UserMapper
接口的deleteUserById()
方法执行删除操作,最后调用sqlSession.commit()
方法提交事务。通过以上对 JDBC 和 MyBatis 的详细介绍和示例代码,希望能帮助读者更好地理解和掌握这两种数据库操作技术,在实际项目中选择合适的方式进行数据库开发。