最近想整理一下SSM(Spring+SpringMVC+Mybatis)的文章,我比較喜歡一步一步詳細地拆分再組合。那麼我的想法是單獨使用Spring,SpringMVC,Mybatis。最後再把他們整合到一起,那麼這篇文章就是Mybatis模塊的搭建。並且我會從JDBC開始,一步一步搭建成Mybatis。
使用JDBC操作數據庫
一、環境準備
(1)jdk
(2)mysql-connector-java(我這裏以mysql數據庫爲例,每個數據庫廠商都封裝了自己的底層操作數據庫的jar包供程序員使用)
<!--這是mysql的jar包的maven座標 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
二、JDBC操作數據庫的流程
1.第1步:註冊驅動 (僅僅做一次)
首先將要操作的數據庫(mysql、oracle等)的驅動註冊,比如我用的是mysql,所以我需要將mysql的驅動註冊。代碼只有一句:
//此步爲註冊mysql驅動:通過反射將此類信息加載至虛擬機,那麼該類的靜態方法會執行,註冊mysql驅動。
Class.forName("com.mysql.jdbc.Driver");
此步爲註冊mysql驅動:通過反射將此類信息加載至虛擬機,那麼該類的靜態方法會執行,註冊mysql驅動。
打開com.mysql.jdbc.Driver類查看源碼會發現:
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
靜態代碼執行將此驅動註冊到JAVA對數據庫的驅動管理(DriverManager)中。
並且,使用反射還可以動態更換想要操作的數據庫(通過配置文件的形式)。
2.第二步:建立連接(Connection)
連接數據庫首先需要獲取一個數據庫的連接,通過這個連接繼續對數據庫操作。數據庫的基礎架構也很好的說明了這一點,如果不太懂可以看我之前的文章
Mysql成長系列之一:Mysql的基礎架構
上一步說到,我們已經將mysql驅動註冊到了DriverManager,所以我們現在可以從註冊管理那裏獲得一個對數據庫的連接。
String url= "jdbc:mysql://localhost:3306/october?characterEncoding=utf8&useSSL=false";
String user = "root";
String password = "root";
Connection conn=null;
//DriverManager攜帶url、user、password等信息得到一個連接對象,賦值給此類的Connection對象conn。
conn= DriverManager.getConnection(url,user,password);
此時我們就已經獲得了一個連接。
3.第三步:創建運行SQL語句的statement
Statement接口用於執行SQL語句,這裏我們使用擴展了功能的PreparedStatement。
PreparedStatement也是一個接口,他的實現類由上一步的Connection對象給出
String sql="select * from student";
PreparedStatement preparedStatement=conn.prepareStatement(sql);
4.第四步:運行語句
拿到了執行器PreparedStatement ,便可以執行語句了。
PreparedStatement 提供了
(1)executeQuery方法用於查詢(讀操作),並返回一個結果集ResultSet 。
(2)executeUpdate方法用於增刪改(寫操作),並返回一個int值,代表受影響行數。
查詢:
ResultSet resultSet=preparedStatement.executeQuery();
更新:
int i=preparedStatement.executeUpdate();
5.第五步:處理運行結果
這裏主要針對查詢語句,查詢語句獲得查詢結果集ResultSet 。通過對Result操作獲取查詢的內容。
結果集ResultSet是通過遊標來操作的。
ResultSet rs的next方法配合getString()取出結果。
代碼示例:
List<StudentEntity> list=new ArrayList<StudentEntity>();
while(resultSet.next())
{
student=new StudentEntity();
student.setId(resultSet.getLong("id"));
student.setName(resultSet.getString("name"));
student.setAge(resultSet.getInt("age"));
list.add(student);
}
6.第六步:釋放資源
前邊用到的Result、preparedStatement、connection都需要釋放掉。
倒敘釋放資源resultSet-》preparedStatement-》connection。
resultSet.close();
preparedStatement.close();
conn.close();
7.總結
OK,到這裏JDBC的操作流程就結束了,最後再總結一下:
/**
* JDBC對數據庫的操作需要分爲5步進行:
* 第一步:加載Driver類,註冊數據庫驅動到DriverManager;
* 第二步:通過DriverManager,使用url,用戶名和密碼獲取連接(Connection);
* 第三步:通過Connection,使用sql語句得到Statement對象;
* 第四步:執行語句,將結果返回resultSet;
* 第五步:對結果resultSet進行處理;
* 第六步:倒敘釋放資源resultSet-》preparedStatement-》connection。
*
* 此類主要完成前兩步,通過實例化此類,獲取Connection類的對象,可完成3-5步操作。
*/
8.代碼以及運行示例
我一共寫了四個類用於操作數據庫:
(1)JDBCConfig
這個類主要是完成JDBC流程的前兩步,即註冊驅動和獲取連接對象:
package FirstStep;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* 此類爲JDBC的配置類,JDBC對數據庫的操作需要分爲5步進行:
* 第一步:加載Driver類,註冊數據庫驅動;
* 第二步:通過DriverManager,使用url,用戶名和密碼建立連接(Connection);
* 第三步:通過Connection,使用sql語句打開Statement對象;
* 第四步:執行語句,將結果返回resultSet;
* 第五步:對結果resultSet進行處理;
* 第六步:倒敘釋放資源resultSet-》preparedStatement-》connection。
*
* 此類主要完成前兩步,通過實例化此類,獲取Connection類的對象,可完成3-5步操作。
*/
public class JDBCConfig {
private String driver = "com.mysql.jdbc.Driver";
private String url= "jdbc:mysql://localhost:3306/october?characterEncoding=utf8&useSSL=false";
private String user = "root";
private String password = "root";
//註冊驅動只需要操作一次,我直接放在了此類的靜態代碼塊裏
static{
try {
Class.forName("com.mysql.jdbc.Driver");//此步爲註冊mysql驅動:通過反射將此類信息加載至虛擬機,那麼該類的靜態方法會執行,註冊mysql驅動。
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
Connection conn=null;
public JDBCConfig() {
try {
conn= DriverManager.getConnection(url,user,password);//DriverManager攜帶url、user、password等信息得到一個連接對象,賦值給此類的Connection對象conn。
} catch (SQLException e) {
e.printStackTrace();
}
}
}
(2)JDBCExcute
這個類是封裝的對數據庫的操作方法,參數是sql語句(只寫了查詢和更新)
package FirstStep;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* 此類爲JDBC的執行類,封裝了對JDBC對數據庫的增刪改查操作
*/
public class JDBCExcute {
public static List<StudentEntity> show(String sql)
{
List<StudentEntity> list=new ArrayList<StudentEntity>();
JDBCConfig jdbcConfig=new JDBCConfig();
ResultSet resultSet=null;
try {
PreparedStatement preparedStatement=jdbcConfig.conn.prepareStatement(sql);
resultSet=preparedStatement.executeQuery();
StudentEntity student=null;
while(resultSet.next())
{
student=new StudentEntity();
student.setId(resultSet.getLong("id"));
student.setName(resultSet.getString("name"));
student.setAge(resultSet.getInt("age"));
list.add(student);
}
resultSet.close();
preparedStatement.close();
jdbcConfig.conn.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
}
return list;
}
public static int update(String sql)
{
List<StudentEntity> list=new ArrayList<StudentEntity>();
int i=0;
JDBCConfig jdbcConfig=new JDBCConfig();
// ResultSet resultSet=null;
try {
PreparedStatement preparedStatement=jdbcConfig.conn.prepareStatement(sql);
i=preparedStatement.executeUpdate();
preparedStatement.close();
jdbcConfig.conn.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
}
return i;
}
public static int update2(String sql)
{
List<StudentEntity> list=new ArrayList<StudentEntity>();
int i=0;
JDBCConfig jdbcConfig=new JDBCConfig();
// ResultSet resultSet=null;
try {
PreparedStatement preparedStatement=jdbcConfig.conn.prepareStatement(sql);
preparedStatement.setInt(1,1);
i=preparedStatement.executeUpdate();
preparedStatement.close();
jdbcConfig.conn.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
}
return i;
}
}
(3)StudentEntity
這個就是對象數據庫表的實體類
package FirstStep;
public class StudentEntity {
private long id;
private String name;
private int age;
@Override
public String toString() {
return "StudentEntity{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
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;
}
}
(4)Main
這裏執行代碼
另外這裏還調用了兩個不同的update方法,是因爲擴展了statement的preparedStatement接口提供了先寫沒有參數的sql語句再設置參數(update2方法)
package FirstStep;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
showTest();
}
public static void showTest()
{
String sql="select * from student";
List<StudentEntity> studentEntityList=JDBCExcute.show(sql);
for (StudentEntity studentEntity : studentEntityList) {
System.out.println(studentEntity);
}
}
public static void updateTest()
{
String sql="update student set name='updateTestName',age='18' where id='1'";
int result=JDBCExcute.update(sql);
System.out.println(result);
}
public static void updateTest2()
{
String sql="update student set name='updateTestName',age='18' where id=?";
int result=JDBCExcute.update2(sql);
System.out.println(result);
}
}
運行結果(查詢):
數據庫內容:
下一篇,我會整合C3P0數據庫連接池並且搭建MyBatis。