回顧 JDBC
使用 IDEA 建立 maven 工程
開啟IDEA,選擇Create New Project,點選Maven,如下:
點選Next,填寫Maven工程資訊,如下:
- GroupId: com.mybatis
- ArtifactId:MyBatisApp
- Version: 1.0-SNAPSHOT
點選建立按鈕,即Maven工程就建立好了
引入mysql依賴包
在Maven工程的pom.xml檔案中匯入 mysql 驅動依賴包
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.15</version>
</dependency>
</dependencies>
建立資料庫
使用Navicat工具建立名為mybatis的資料庫,字符集編碼為utf-8
#建立資料庫
CREATE DATABASE IF NOT EXISTS `mybatis` DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
建立資料庫表
#建立表
DROP TABLE IF EXISTS tb_user;
CREATE TABLE tb_user (
id int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
userName varchar(32) DEFAULT NULL,
password varchar(32) DEFAULT NULL,
name varchar(32) DEFAULT NULL,
age int(10) DEFAULT NULL,
sex int(2) DEFAULT NULL,
birthday date DEFAULT NULL,
created datetime DEFAULT NULL,
updated datetime DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
插入資料
#插入資料
INSERT INTO tb_user ( userName, password, name, age, sex, birthday, created, updated) VALUES ( 'zs', '123456', '張三', '22', '1', '1990-09-02', sysdate(), sysdate());
INSERT INTO tb_user ( userName, password, name, age, sex, birthday, created, updated) VALUES ( 'ls', '123456', '李四', '24', '1', '1993-09-05', sysdate(), sysdate());
Navicat顯示結果如下:
User實體類程式碼
Maven工程的main/java/entity下建立UserEntity.java檔案
import java.util.Date;
public class UserEntity {
private int id;
private String userName;
private String password;
private String name;
private int age;
private int sex;
private Date birthday;
private String created;
private String updated;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getCreated() {
return created;
}
public void setCreated(String created) {
this.created = created;
}
public String getUpdated() {
return updated;
}
public void setUpdated(String updated) {
this.updated = updated;
}
@Override
public String toString() {
return "UserEntity{" +
"id=" + id +
", userName='" + userName + '\'' +
", password='" + password + '\'' +
", name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
", birthday=" + birthday +
", created='" + created + '\'' +
", updated='" + updated + '\'' +
'}';
}
}
JDBC測試程式碼
Maven工程的 main/java下 JDBCDemo.java 檔案,如下:
import entity.UserEntity;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class JDBCDemo {
public static void main(String[] args) throws Exception{
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet rs = null;
try {
//載入驅動
Class.forName("com.mysql.cj.jdbc.Driver");
//獲取連線
String url = "jdbc:mysql://localhost:3306/mybatis";
String user = "root";
String pwd = "123456";
//獲取資料庫連線
connection = DriverManager.getConnection(url, user, pwd);
//獲取preparedStatement
String sql = "select * from tb_user where age>?";
preparedStatement = connection.prepareStatement(sql);
//設定引數
preparedStatement.setLong(1,20);
rs = preparedStatement.executeQuery();
//處理結果集
List<UserEntity> userEntities = new ArrayList<UserEntity>();
while (rs.next()) {
int id = rs.getInt("id");
String userName = rs.getString("userName");
String password = rs.getString("password");
String name = rs.getString("name");
int age = rs.getInt("age");
int sex = rs.getInt("sex");
Date birthday = rs.getDate("birthday");
String created = rs.getString("created");
String updated = rs.getString("updated");
UserEntity userEntity = new UserEntity();
userEntity.setId(id);
userEntity.setUserName(userName);
userEntity.setPassword(password);
userEntity.setName(name);
userEntity.setAge(age);
userEntity.setSex(sex);
userEntity.setBirthday(birthday);
userEntity.setCreated(created);
userEntity.setUpdated(updated);
userEntities.add(userEntity);
}
System.out.println(userEntities);
} finally {
//關閉連線,釋放資源
if (rs != null) {
rs.close();
}
if (preparedStatement != null) {
preparedStatement.close();
}
if (connection != null) {
connection.close();
}
}
}
}
執行結果如下:
[UserEntity{id=1, userName='zs', password='123456', name='張三', age=22, sex=1, birthday=1990-09-02, created='2020-06-17 09:30:58.0', updated='2020-06-17 09:30:58.0'}, UserEntity{id=2, userName='ls', password='123456', name='李四', age=24, sex=1, birthday=1993-09-05, created='2020-06-17 09:30:58.0', updated='2020-06-17 09:30:58.0'}]
Process finished with exit code 0
JDBC缺點分析
開發效率低(程式碼冗餘度高)
載入驅動、獲取連線、拼接sql、執行sql、獲取結果、解析結果、關閉資料庫,這些操作是純jdbc的方式必經的一些過程,每次運算元據庫都需要寫這些,但是真正和開發相關有:拼接sql、執行sql、解析結果,這幾個可能不同,而其他的幾個步驟是所有db操作共用的一些步驟,所以純 jdbc 的方式重複性的程式碼太多了,如果每個操作都使用這種方式會耗費大量的時間。
除錯和維護困難
純jdbc的方式,sql多數都是寫在java程式碼中,我還記得剛開始工作的時候接觸的第一個專案就是jdbc寫的,當時jdbc是寫在jsp中,除錯和維護起來是相當麻煩的。
動態SQL編寫繁瑣
還有就是動態sql方面:面對於各種複雜的條件查詢,需要在程式碼中寫很多判斷,拼接sql,這種情況估計大家都有經歷過,應該是有同感的,各種判斷各種拼接沒有統一的規範,各種寫法也是千奇百怪,最終導致系統難以維護。
JDBC 這些問題使系統開發緩慢、難以維護,後面就出現了各種優秀的框架來解決這些問題,下面我們就來看一下常見的db框架及他們的優缺點,以及我們應該如何選擇?
Hibernate
介紹hibernate之前,我們先了解一下什麼是ORM?
ORM(Object Relational Mapping):物件關係對映,簡單點說就是將資料庫中的表和java中的物件建立對映關係,可以讓我們操作物件來間接的運算元據庫。
ORM最好的框架就是hibernate,hibernate可以讓你透過java物件來間接的運算元據庫,java物件就相當於資料庫中表的代理一樣,當你想刪除表的資料的時候,不需要自己寫delete語句發給資料庫,只需要對hibernate說我需要刪除哪個java物件就行了,hibernate自動根據你的操作去生成db需要的sql然後發給db去執行,對於開發者來說隱藏了底層jdbc和db的互動過程,可能開發者不需要掌握資料庫技術,就可以透過這個框架直接運算元據庫,比如對資料庫進行增、刪、改、查可能需要開發者會寫各種sql指令碼,還有每種資料庫的sql指令碼語法也不一樣,剛開始專案使用的是mysql,你按照mysql的語法寫的,後面可能要切換到oracle,語法上面需要變動,但是如果你使用hibernate,這些都不是問題,你不會sql也沒關係,而你只需要像操作物件一樣去運算元據庫,hibernate會根據你的操作和db的型別自動生成操作所需要的sql,一種寫法能夠跨多種資料庫執行。
優點
- 簡化了整個jdbc操作過程
- 對於開發者來說不需要關心sql了,只需要去操作物件就可以了,hibernate可以幫我們自動生成所需要的sql
- 程式碼移植性比較好,透過hibernate操作db都是透過操作物件來進行的,而hibernate會根據我們的操作和db的型別生成符合各種db要求的sql,如果我們需要切換db的型別,hibernate會自動適應,對於開發者業務程式碼來說不需要做任何業務程式碼上的調整
- 開發效率比較高
缺點
- sql最佳化比較艱難,各種操作最終發給db的sql是由hibernate自動生成的,對於開發者來說如果想幹預最終需要執行的sql,相對來說比較困難
- hibernate入門比較容易,但是想成為高手學習成本比較高
- 對於複雜的動態sql,程式碼中也需要寫很多判斷進行組裝,動態sql這塊的支援比較欠缺
如果做一些簡單的系統,開發週期也比較緊急,對sql的最佳化要求也不是很高,可以使用hibernate。
Spring JdbcTemplate
jdbctemplate 是在spring框架的基礎上開發的一個jdbc框架,所以對spring是有依賴的,它對jdbc做了封裝,隱藏了各種重複的操作,使用時只需傳入:需要執行的sql、引數以及對於結果如何解析的程式就可以了,使用起來還是很方便的,但是面對與動態sql,它也是無能為力了。整體上來說,jdbctemplate相對於純jdbc隱藏了很多重複性的操作,對於sql的寫法和結果的組裝上完全交給了開發者自己去控制,在系統中使用也可以幫助我們節約很多時間,而且學習相當簡單,花2個小時就學會了,也是很優秀的一個框架。
Mybatis
mybatis相對於純jdbc來說,也隱藏了重複性的工作,mybatis是一個半自動化的orm框架,為什麼說是半自動化的呢,因為他需要我們自己去寫sql,而他做的更好的地方就是動態sql的支援上面,而上面說的各種技術,面對與動態sql只能自己寫很多判斷去組裝sql,而這些判斷和組裝在mybatis中實現起來就非常簡單了,完全由mybatis去幫我們實現了。mybatis將sql交由開發者去控制,所以在sql的最佳化方面,開發者可以隨心所欲,也就是說mybatis將重複性的工作最佳化到了極致:操作db的過程、動態sql的拼裝、結果和物件的對映,這些mybatis都幫我們實現的很好,而讓我們將更多的經歷花在sql的寫法和最佳化上面,所以毫無疑問mybatis使用人數和公司也是最多的,大部分網際網路公司基本上都會使用mybatis,其他2種可以不會,但是mybatis你必須要會。
幾種技術的對比
資料引用:
https://blog.csdn.net/zpcandzhj/article/details/80878563
https://www.cnblogs.com/diffx/p/10611082.html
https://www.cnblogs.com/ashleyboy/category/1246107.html