JDBC 與 MyBatis從基礎(chǔ)到實(shí)踐
一、JDBC 介紹
JDBC(Java Database Connectivity)即 Java 數(shù)據(jù)庫連接,是 Java 語言中用來規(guī)范客戶端程序如何來訪問數(shù)據(jù)庫的應(yīng)用程序接口,提供了諸如查詢和更新數(shù)據(jù)庫中數(shù)據(jù)的方法。它由一組用 Java 語言編寫的類和接口組成,使得 Java 程序能夠與各種關(guān)系型數(shù)據(jù)庫進(jìn)行交互,如 MySQL、Oracle、SQL Server 等。通過 JDBC,開發(fā)人員可以在 Java 代碼中執(zhí)行 SQL 語句,處理數(shù)據(jù)庫事務(wù),獲取查詢結(jié)果等。
二、使用 JDBC 查詢用戶信息
下面是一個(gè)簡單的使用 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()方法獲取數(shù)據(jù)庫連接,然后創(chuàng)建Statement對(duì)象用于執(zhí)行 SQL 語句,最后執(zhí)行executeQuery()方法獲取ResultSet結(jié)果集,并遍歷結(jié)果集輸出用戶信息。
三、ResultSet 結(jié)果集
ResultSet是 JDBC 中用于存儲(chǔ)數(shù)據(jù)庫查詢結(jié)果的對(duì)象。它就像一個(gè)表格,每一行代表一條記錄,每一列代表一個(gè)字段。ResultSet提供了一系列方法來訪問其中的數(shù)據(jù),如getInt()、getString()、getDouble()等,根據(jù)字段的數(shù)據(jù)類型來獲取相應(yīng)的值。同時(shí),ResultSet有一個(gè)游標(biāo),默認(rèn)位于第一行之前,通過next()方法可以將游標(biāo)移動(dòng)到下一行,當(dāng)游標(biāo)指向有效行時(shí),才能獲取該行的數(shù)據(jù)。當(dāng)游標(biāo)移動(dòng)到結(jié)果集的末尾(即next()方法返回false)時(shí),表示結(jié)果集遍歷結(jié)束。
四、預(yù)編譯 SQL - SQL 注入問題
SQL 注入是一種常見的安全漏洞,攻擊者通過在輸入?yún)?shù)中插入惡意的 SQL 代碼,從而改變原本 SQL 語句的邏輯,獲取敏感信息或進(jìn)行非法操作。例如,在一個(gè)用戶登錄驗(yàn)證的場景中,如果使用普通的 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 = '',這樣無論密碼是否正確,都能成功登錄。預(yù)編譯 SQL 可以有效防止 SQL 注入問題。預(yù)編譯 SQL 是將 SQL 語句先發(fā)送到數(shù)據(jù)庫進(jìn)行編譯,然后再將參數(shù)傳遞給已經(jīng)編譯好的語句。在 JDBC 中,使用
PreparedStatement來實(shí)現(xiàn)預(yù)編譯 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();
// 處理結(jié)果集
} catch (SQLException e) {
e.printStackTrace();
}在上述代碼中,使用
?作為占位符,然后通過setString()等方法設(shè)置參數(shù),這樣數(shù)據(jù)庫會(huì)將參數(shù)作為普通值處理,而不會(huì)將其解析為 SQL 代碼,從而避免了 SQL 注入問題。
五、預(yù)編譯 SQL - 性能更高
預(yù)編譯 SQL 除了能防止 SQL 注入外,還具有更高的性能。當(dāng)使用普通的
Statement執(zhí)行 SQL 語句時(shí),數(shù)據(jù)庫每次都需要對(duì) SQL 語句進(jìn)行語法解析、查詢優(yōu)化等操作。而預(yù)編譯 SQL 會(huì)將 SQL 語句先編譯好,后續(xù)如果執(zhí)行相同結(jié)構(gòu)的 SQL 語句,只需要傳遞參數(shù)即可,數(shù)據(jù)庫不需要再次進(jìn)行語法解析和查詢優(yōu)化,從而提高了執(zhí)行效率。特別是在需要頻繁執(zhí)行相同結(jié)構(gòu) SQL 語句的場景下,預(yù)編譯 SQL 的性能優(yōu)勢更加明顯。
六、JDBC 增刪改操作
以下是使用 JDBC 進(jìn)行增刪改操作的示例代碼:
插入數(shù)據(jù):
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();
}
}
}更新數(shù)據(jù):
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();
}
}
}刪除數(shù)據(jù):
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 是一款優(yōu)秀的持久層框架,它支持定制化 SQL、存儲(chǔ)過程以及高級(jí)映射。MyBatis 避免了幾乎所有的 JDBC 代碼和手動(dòng)設(shè)置參數(shù)以及獲取結(jié)果集,它可以使用簡單的 XML 或注解來配置和映射原生信息,將接口和 Java 的 POJO(Plain Old Java Objects,普通的 Java 對(duì)象)映射成數(shù)據(jù)庫中的記錄。MyBatis 對(duì) JDBC 進(jìn)行了封裝,使得數(shù)據(jù)庫操作更加簡潔、高效,同時(shí)也提高了代碼的可維護(hù)性和可擴(kuò)展性。
八、MyBatis 入門程序
以下是一個(gè)簡單的 MyBatis 入門示例:
引入依賴:
在 Maven 項(xiàng)目的
pom.xml文件中添加 MyBatis 和數(shù)據(jù)庫驅(qū)動(dòng)依賴:
<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>創(chuàng)建實(shí)體類:
public class User {
private int id;
private String username;
private String email;
private String password;
// 省略 getters 和 setters
}創(chuàng)建 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 提示
為了在開發(fā)過程中獲得更好的 SQL 提示,可以使用一些 IDE 插件,如在 IntelliJ IDEA 中安裝 MyBatis Log Plugin 等插件,這些插件可以將 MyBatis 執(zhí)行的 SQL 語句打印出來,并對(duì) SQL 語法進(jìn)行高亮顯示和提示,方便開發(fā)人員調(diào)試和優(yōu)化 SQL 語句。同時(shí),也可以在 SQL 映射文件中使用
<!-- -->進(jìn)行注釋,對(duì) SQL 語句的功能和邏輯進(jìn)行說明,提高代碼的可讀性。
十、MyBatis 輔助配置 - 日志輸出
MyBatis 支持配置日志輸出,以便更好地了解程序的執(zhí)行情況。可以通過在
mybatis-config.xml文件中配置日志工廠來實(shí)現(xiàn)。例如,使用 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 執(zhí)行的 SQL 語句等信息就會(huì)按照配置的日志級(jí)別進(jìn)行輸出。
十一、MyBatis 數(shù)據(jù)庫連接池
MyBatis 支持使用不同的數(shù)據(jù)庫連接池,如
POOLED連接池(默認(rèn))、UNPOOLED連接池等。POOLED連接池會(huì)管理一定數(shù)量的數(shù)據(jù)庫連接,當(dāng)需要連接時(shí)從連接池中獲取,使用完畢后再歸還到連接池,這樣可以避免頻繁地創(chuàng)建和銷毀數(shù)據(jù)庫連接,提高性能。在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 等,只需要在項(xiàng)目中引入相應(yīng)的依賴,并在 MyBatis 配置文件中進(jìn)行相應(yīng)的配置即可。
十二、MyBatis 增刪改查 - 刪除用戶
以下是使用 MyBatis 實(shí)現(xiàn)刪除用戶的示例:
在 SQL 映射文件(UserMapper.xml)中添加刪除語句:
<mapper namespace="com.example.UserMapper">
<!-- 其他語句 -->
<delete id="deleteUserById" parameterType="int">
DELETE FROM users WHERE id = #{id}
</delete>
</mapper>在接口(UserMapper.java)中添加對(duì)應(yīng)的方法:
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()方法執(zhí)行刪除操作,最后調(diào)用sqlSession.commit()方法提交事務(wù)。通過以上對(duì) JDBC 和 MyBatis 的詳細(xì)介紹和示例代碼,希望能幫助讀者更好地理解和掌握這兩種數(shù)據(jù)庫操作技術(shù),在實(shí)際項(xiàng)目中選擇合適的方式進(jìn)行數(shù)據(jù)庫開發(fā)。
到此這篇關(guān)于JDBC 與 MyBatis從基礎(chǔ)到實(shí)踐的文章就介紹到這了,更多相關(guān)JDBC 與 MyBatis詳解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- MyBatis 如何簡化的 JDBC(思路詳解)
- 詳解如何使用MyBatis簡化JDBC開發(fā)
- MyBatis中的JdbcType映射使用詳解
- sharding-jdbc 兼容 MybatisPlus動(dòng)態(tài)數(shù)據(jù)源的配置方法
- MySQL text類型對(duì)應(yīng)mybatis jdbcType類型方式
- 解決mybatis plus報(bào)錯(cuò)com.microsoft.sqlserver.jdbc.SQLServerException:必須執(zhí)行該語句才能獲得結(jié)果
- 淺談MyBatis所有的jdbcType類型
- SpringBoot多數(shù)據(jù)源配置詳細(xì)教程(JdbcTemplate、mybatis)
相關(guān)文章
淺談MultipartFile中transferTo方法的坑
這篇文章主要介紹了MultipartFile中transferTo方法的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
springboot-curd基于mybatis項(xiàng)目搭建
這篇文章主要介紹了springboot-curd基于mybatis項(xiàng)目搭建,圍繞相關(guān)資料展開詳細(xì)內(nèi)容,希望對(duì)正在學(xué)習(xí)的你有所幫助,需要的小伙伴也可以參考一下2022-01-01
Mybatis開發(fā)要點(diǎn)-resultType和resultMap有什么區(qū)別詳解
本文主要介紹了Mybatis開發(fā)要點(diǎn)-resultType和resultMap有什么區(qū)別詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04
java通過反射創(chuàng)建對(duì)象并調(diào)用方法
這篇文章主要介紹了java通過反射創(chuàng)建對(duì)象并調(diào)用方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01
java實(shí)現(xiàn)動(dòng)態(tài)圖片效果
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)動(dòng)態(tài)圖片效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-03-03
Java實(shí)現(xiàn)數(shù)組去除重復(fù)數(shù)據(jù)的方法詳解
這篇文章主要介紹了Java實(shí)現(xiàn)數(shù)組去除重復(fù)數(shù)據(jù)的方法,結(jié)合實(shí)例形式詳細(xì)分析了java數(shù)組去除重復(fù)的幾種常用方法、實(shí)現(xiàn)原理與相關(guān)注意事項(xiàng),需要的朋友可以參考下2017-09-09

