一、JDBC简介
JDBC(Java database connectivity):Java数据库连接。顾名思义JDBC是通过将Java与数据库连接,进而操作数据库的Java语言。原来我们在学习mysql数据库时都是在控制台中用sql语句操作数据库,而JDBC则通过用Java语言向数据库发送请求来操作数据库。也就是说学习了JDBC我们就可以通过使用Java语言来操作数据库,在后续的学习中将数据库更灵活的运用。总的来说JDBC就是充当了Java和数据库之间的桥梁。
二、驱动和接口介绍
2.1、驱动介绍
JDBC驱动是指实现了JDBC规范的程序。它是来按照JDBC定义的规范完成对底层数据库的操作。也就是说JDBC只是定义了API操作,并没有去实现这些接口的具体实现操作,这时候我们就要用驱动去实现这些操作了。而不同的数据库提供商针对自己的产品,开发出实现JDBC规范的程序,而这些程序就是JDBC驱动。(我用的数据库是MySQL,所以用的驱动自然是MySQL的JDBC驱动,驱动需要在官网下载)虽然不同的数据库的JDBC驱动内容程序不一致,但由于JDBC规范了这些程序的接口,所以我们在使用JDBC时只需考虑JDBC的接口使用,而无需再去思考JDBC接口具体实现方式。
2.2、DriverManager——驱动管理器
DriverManager 管理这一个应用程序中所有的JDBC程序,它的主要作用是获得与数据库连接的Connection实例。这里要说明一下,之前的老版本需要用Class.forName(驱动程序类的全路径名);去手动加载JDBC驱动,然而我发现在新版本数据库中可以不用手动去加载驱动,因为程序会自动给我们加载好驱动(前提是你得先导好对应的JDBC驱动包,导包在下面会详细讲解)。
DriverManager获取Connection 实例的主要方法:
* getConnection(String url):通过数据库URL得到数据库连接;
* getConnection(String url,String user,String password):通过数据库URL得到数据库连接。连接的时候使用用户名和密码进行验证。
* getConnection(String url,java.util.Properties props):通过数据库URL得到数据库连接。连接的属性在props类中定义。Properties类可以看做是一个Map,其中的元素就是键值对。
2.3、Connection 接口
通过DriverManager.getConnection(....)方法可以得到一个Connection类实例。Connection的作用主要是生成Statement和PreparedStatement,这里我们主要介绍Connection接口中常用的方法:
* createStatement():返回一个Statement对象。
* prepareStatement(String sql):返回一个PreparedStatement对象。
* rollback():撤销本连接做出的所有改动(在之后学习事务的时候会用到)
* commit():提交本次连接的所有改动。
* setAutoCommit(boolean autoCommit):设置是否每次改动都自动提交。如果没有设置这个方法,程序会默认每次执行一次sql操作都自动提交到数据库中更改数据。在之后学习事务的时候我们需要将这个方法里的参数设置为false。注意,如果参数设置为true,则commit()方法和rollback()方法都没用了。
* getAutocommit():查看本连接是否是自动提交的;
* close():关闭一个连接,释放资源。在使用完一个连接后应该将它关闭。
2.4 Statement 接口
Statemetn接口的作用是执行SQL语句。SQL语句可以是查询,也可以是跟新(增、删、改),以下介绍几个Statement中的重要方法:
* executeQuery(String sql):执行一条查询SQL语句,返回值为ResultSet。
* executeUpdate(String sql):执行一条更行SQL语句,返回值为int类型,代表该语句影响到的记录行数。
* addBatch(String sql):增加一条SQL语句作为批处理语句。
* executeBatch():执行所有的批处理语句,返回值是int数组,每个元素代表一条批处理语句的执行结果。
* close():关闭当前的Statement。
2.5 PreparedStatement 接口
PreparedStatement继承自Statement,所以Statment有的方法PreparedStatement都有,在通过Connection获取PreparedStatement实例时,要注意perpareStatement(String sql)方法中是包含SQL语句参数的,只不过这个SQL语句中对于未确定的变量都用问好(?)来代替了。在用executeQuery()和executeUpdate()方法时必须先对未确定的变量用setXXX()方法设值,这里的XXX可以是Java的基本数据类型,例如setInt(int index, int x),这里的index表示不确定值(?)的位置,从1开始。
PreparedStatement主要方法:
* setXXX(变量类型 设置变量位置,变量类型 变量值)
* executeQuery():执行一条查询SQL语句,返回值为ResultSet。注意,这里的SQL语句已经在创建PreparedStatement的时候确定了。
* executeUpdate():执行一条更行SQL语句。
2.6 ResultSet 接口
在执行完executeQuery(String sql) 和executeQuery() 方法时,会返回一个ResultSet实例,这个实例代表着返回内容的结果集,这个结果集是一条数据库中的记录。以下介绍它的主要方法:
* next():判断结果集中是否还有下一条记录。如果有,则指针指向下一条记录,返回true,如果没有返回false;在这里要注意,如果想对结果集进行操作,必须执行next()方法,因为结果集引用需要指向一个明确的结果集对象,才能对指针所指向明确的结果集对象进行操作,不执行next()的话 ,会返回NullPointerException异常。
* getXXX(int colunmnIndex):得到当前记录中第colunmnIndex列的数据,这里的XXX表示得到数据的变量类型。colunmnIndex的值从1开始。
* getXXX(“列名”):得到当前记录中对应列名的列的数据,这里XXX也表示得到数据的变量类型。
* getRow():得到当前记录的行号,如果是第一行则返回第一行。
* getMetaData():返回当前结果集的 ResultSetMetaDate对象。这个对象包涵了当前结果集的一些属性值。
* close():关闭结果集。
以下为ResultMetaDate中常用的方法:
* getColumnCount():得到一条记录列的数目。
* getColumnCountName(int columnIndex):得到columnIndex的列名。
* getTableName(int column):得到指定列所属的表名。
三、具体使用方法
3.1、得到Connection对象
1.导jar包。mysql-connector-java-8.0.11.jar(我用的是mysql的JDBC驱动)。
2.给出url、username、password等参数。
3.使用DriverManager类来的到Connection对象。
这里要再次说明一下,新版本的驱动无需我们手动通过Class.forName(“类名”)去加载。如果你非要手动去加载,那么新版本的mysql驱动类名为:com.mysql.cj.jdbc.Driver。
时刻牢记JDBC中的四大参数:
- driverClassName:com.mysql.cj.jdbc.Driver
- url:jdbc:mysql://localhost:3306/数据库名
- username:mysql用户名
- password:mysql密码
Demo:
public class Demo{
public void main(String[] args) throws ClassNotFoundException,SQLException{
String url="jdbc:mysql://localhost:3306/数据库名?useSSL=fasle”;
String username="root";
String password="123";
Connection con=DriverManager.getConnection(url,username,password);
}
}
说明:
1、出现SQLException的原因:1.url username password 是否正确。2.检查是否打开了sql服务器
2、出现ClassNotFoundException的原因:1.没导入驱动包。2.Class.forName()传入的字符串参数错误。
3、遇到连接其他问题无法连接成功,请参见我上一篇文章:JDBC MySQL使用时遇到的问题及解决方案
3.2 JDBC对数据库的增、删、改、查
3.2.1 增、删、改
public class Demo{
public void main(String[] args) throws ClassNotFoundException,SQLException{
String url="jdbc:mysql://localhost:3306/数据库名?useSSL=false”;
String username="root";
String password="123";
Connection con=DriverManager.getConnection(url,username,password);
Statement stmt=con.createStatement();//调用Connection的方法创建Statement对象,它是sql语句的发送器,功能就是向数据库发送sql语句
String sql="insert into stu values('...','...','...','...')";//右括号不需要打分号,打了就会出错,因为程序会自动帮我们加。
stmt.executeUpdate(sql);//调用此方法向数据库发送sql语句。该语句返回的值为改变数据库的行数。
}
}
}
注意:上述中出现的Connection和Statement都应该导入java.mysql下的包,而不是java.jdbc下的包。
3.2.2 查询
Demo1(Statement):
public class Demo{
public void main(String[] args) throws ClassNotFoundException,SQLException{
String url="jdbc:mysql://localhost:3306/数据库名?useSSL=false”;
String username="root";
String password="123";
Connection con=DriverManager.getConnection(url,username,password);
Statement stmt=con.createStatement();
String sql="selece * from stu";
ResultSet rs=stmt.execute(sql);
/*
*解析ResultSet
*ResultSet提供了一系列的getXxx()方法
*/
while(rs.next())//第一次调用next()方法是将光标移动到该表的第一行
{
rs.getInt(1);//通过列编号来获取该列的值
rs.getString("name");//通过列名称来获取该列的值。
}
}
}
Demo2(PreparedStatement 注意与Demo1的区别):
public class Demo{
public void main(String[] args) throws ClassNotFoundException,SQLException{
String url="jdbc:mysql://localhost:3306/数据库名?useSSL=false”;
String username="root";
String password="123";
Connection con=DriverManager.getConnection(url,username,password);
String sql="insert into stu values(?,?)";//定义sql模板,即参数以问号的形式给出
PreparedStatement pst=con.prepaerStatement(sql);
pst.setString(1,username);//数字1代表第一个问号
pst.setString(2.password);//数字2代表第二个问号
pst.executeUpdate();//向数据库发送sql语句
}
}
3.3 关闭资源
关闭资源时采用倒关的手法将对象进行处理:即先得到的对象后关,后得到的对象先关。
rs.close();
stmt.close();
con.close();
为了注意代码的规范化:在try外给出引用的定义,在try内位对象实例化,在finally中对资源进行关闭。