最近想整理一下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。