mysql学习笔记(六):JDBC详解

来源:互联网 发布:新软件发布 编辑:程序博客网 时间:2024/05/17 00:16

一、快速入门

1.概念

数据库驱动:

数据库厂商为了方便开发人员从程序中操作数据库而提供的一套jar包,通过导入这个jar包就可以调用其中的方法操作数据库,这样的jar包就叫做数据库驱动

JDBC驱动:

sun定义的一套标准,本质上是一大堆的操作数据库的接口,所有数据库厂商为java设计的数据库驱动都实现过这套接口,这样一来同一了不同数据库驱动的方法,开发人员只需要学习JDBC就会使用任意数据库驱动了

如下图:


2.创建数据库数据和导入数据库驱动jar包

创建数据库

create table user(id int primary key auto_increment,name varchar(40),password varchar(40),email varchar(60),birthday date)character set utf8 collate utf8_general_ci;insert into user(name,password,email,birthday) values('zs','123456','zs@sina.com','1980-12-04');insert into user(name,password,email,birthday) values('lisi','123456','lisi@sina.com','1981-12-04');insert into user(name,password,email,birthday) values('wangwu','123456','wangwu@sina.com','1979-12-04');

这时候就可以看到创建的数据了


导入数据库驱动

JDBC驱动不用导入,因为java自带的,但是只有JDBC驱动是不行的,还需要导入导入数据库驱动jar包

先建立一个文件lib,然后将数据库驱动复制到文件内


复制到lib文件中



3.快速入门

案例:要遍历上面数据库的名字

JDBCDemo1.java

package com.java.jdbc;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import com.mysql.jdbc.Driver;public class JDBCDemo1 {public static void main(String[] agrs) throws SQLException{//1.注册数据库驱动DriverManager.registerDriver(new Driver());//2.获取数据库连接Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/day10", "root", "");//3.获取数据库传输器对象Statement stat=conn.createStatement();//4.利用传输器传输sql语句到数据库中执行ResultSet rs=stat.executeQuery("select * from user");//5.遍历结果集获取查询结果while(rs.next()){String name = rs.getString("name");System.out.println(name);}//6.关闭资源rs.close();stat.close();conn.close();}}

运行可以输出:

zs
lisi
wangwu

二、JDBC细节

我们一一分析上面的代码:

//1.注册数据库驱动DriverManager.registerDriver(new Driver());
上面有两个问题:

(1)由于mysql在Driver类的实现中自己注册了一次,而我们又注册了一次,于是会导致MySql驱动被注册两次
(2)创建MySql的Driver对象时,导致了程序和具体的Mysql驱动绑死在了一起,在切换数据库时需要改动java代码

第一个问题看Driver类的原代码得出来的,我们先导入Driver类的源码




而第二个问题,则在这里出现的状况?


如何解决?

可以用Class.forName("com.mysql.jdbc.Driver");方式解决

Class.forName()就是如果路径的文件已经加载了,那么就不会重复的加载

改动后变成如下的了:

package com.java.jdbc;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import com.mysql.jdbc.Driver;public class JDBCDemo1 {public static void main(String[] agrs) throws SQLException, ClassNotFoundException{//1.注册数据库驱动//DriverManager.registerDriver(new Driver());Class.forName("com.mysql.jdbc.Driver");//2.获取数据库连接Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/day10", "root", "");//3.获取数据库传输器对象Statement stat=conn.createStatement();//4.利用传输器传输sql语句到数据库中执行ResultSet rs=stat.executeQuery("select * from user");//5.遍历结果集获取查询结果while(rs.next()){String name = rs.getString("name");System.out.println(name);}//6.关闭资源rs.close();stat.close();conn.close();}}

第二个代码:

//2.获取数据库连接Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/day10", "root", "");
可参看如下:


这跟http协议有点类似


那么上面的参数和参数值可以是哪些?这也是mysql已经定义好的了,我们可以打开mysql文档看一下


所以上面的用户名和密码也可以用参数的形式改变:

"jdbc:mysql:/3306//day10?user=root&password=root"

另外Connection类也是很重要的类,它常见的方法有下面的几点:

createStatement():创建向数据库发送sql的statement对象。
prepareStatement(sql) :创建向数据库发送预编译sql的PrepareSatement对象。
prepareCall(sql):创建执行存储过程的callableStatement对象。 
setAutoCommit(boolean autoCommit):设置事务是否自动提交。 
commit() :在链接上提交事务。
rollback() :在此链接上回滚事务。


第三个代码:

//3.获取数据库传输器对象Statement stat=conn.createStatement();
它除了有executeQuery(String sql) :用于向数据发送查询语句。

还有:

executeUpdate(String sql):用于向数据库发送insert、update或delete语句

这是用于增删改

那么除了,这个还有两者的结合:

execute(String sql):用于向数据库发送任意sql语句

这跟上面的有什么不一样?

我们先看executeQuery和executeUpdate的不一样


返回的类型不一样:

executeQuery返回 Resultset(结果集)

executeUpdate则返回改动数据的个数,如果没有就返回0

execute里面的sql语句如果是查询的话,则返回true,如果不是查询或者没有结果就返回false


另外它还有方法

addBatch(String sql) :把多条sql语句放到一个批处理中。
executeBatch():向数据库发送一批sql语句执行。


第四、五个代码:
//4.利用传输器传输sql语句到数据库中执行ResultSet rs=stat.executeQuery("select * from user");//5.遍历结果集获取查询结果while(rs.next()){String name = rs.getString("name");System.out.println(name);}


ResultSet既然用于封装执行结果的,所以该对象提供的都是用于获取数据的get方法:
获取任意类型的数据
getObject(int index)
getObject(string columnName)
获取指定类型的数据,例如:
getString(int index)
getString(String columnName)
提问:数据库中列的类型是varchar,获取该列的数据调用什么方法?Int类型呢?bigInt类型呢?Boolean类型?

上面的提问是有相应的类型的


ResultSet还有下面的方法:

next():移动到下一行Previous():移动到前一行absolute(int row):移动到指定行beforeFirst():移动resultSet的最前面。afterLast() :移动到resultSet的最后面。
比如下面的案例:

表user是这样的:


package com.java.jdbc;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import com.mysql.jdbc.Driver;public class JDBCDemo1 {public static void main(String[] agrs) throws SQLException, ClassNotFoundException{//1.注册数据库驱动//DriverManager.registerDriver(new Driver());Class.forName("com.mysql.jdbc.Driver");//2.获取数据库连接Connection conn=DriverManager.getConnection(<span style="font-family: Arial, Helvetica, sans-serif;">"jdbc:mysql://localhost:3306/day10", "root", ""</span>);//3.获取数据库传输器对象Statement stat=conn.createStatement();//4.利用传输器传输sql语句到数据库中执行ResultSet rs=stat.executeQuery("select * from user");//5.遍历结果集获取查询结果//while(rs.next()){//String name = rs.getString("name");//System.out.println(name);//}rs.next();rs.next();String name = rs.getString("name");System.out.println(name);//6.关闭资源rs.close();stat.close();conn.close();}}

上面执行的结果是:

lisi


第六个代码:

//6.关闭资源rs.close();stat.close();conn.close();
上面的代码是不严谨的,因为当rs出异常的时候,程序停止,那么stat 和conn就无法正常关闭了,所以要用finally

下面是改造后的代码:

package com.java.jdbc;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;public class JDBCDemo1 {public static void main(String[] args){Connection conn = null;Statement stat = null;ResultSet rs = null;try{//1.注册数据库驱动//--由于mysql在Driver类的实现中自己注册了一次,而我们又注册了一次,于是会导致MySql驱动被注册两次//--创建MySql的Driver对象时,导致了程序和具体的Mysql驱动绑死在了一起,在切换数据库时需要改动java代码//DriverManager.registerDriver(new Driver());Class.forName("com.mysql.jdbc.Driver");//2.获取数据库连接conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day10", "root", "");//3.获取传输器对象stat = conn.createStatement();//4.利用传输器传输sql语句到数据库中执行,获取结果集对象rs = stat.executeQuery("select * from user");//5.遍历结果集获取查询结果while(rs.next()){String name = rs.getString("name");System.out.println(name);}}catch (Exception e) {e.printStackTrace();}finally{//6.关闭资源if(rs!=null){try {rs.close();} catch (SQLException e) {e.printStackTrace();}finally{rs = null;}}if(stat!=null){try {stat.close();} catch (SQLException e) {e.printStackTrace();}finally{stat = null;}}if(conn!=null){try {conn.close();} catch (SQLException e) {e.printStackTrace();}finally{conn = null;}}}}}


三、JDBC增删改查

上面已经初步的了解了相关的知识点,下面就在实现它的增删改查

增加的功能:

</pre><p><pre name="code" class="java">public  void add(){Connection conn = null;Statement stat = null;ResultSet rs = null;//1.注册数据库驱动try {Class.forName("com.mysql.jdbc.Driver");//2.获取数据库连接conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day10", "root", "");//3.获取传输器对象stat = conn.createStatement();//4.利用传输器传输sql语句到数据库中执行,添加对象int count = stat.executeUpdate("insert into user values (null,'zhaoliu','123456','zhaoliu@qq.com','1999-09-09')");// 5.处理结果if (count > 0) {System.out.println("执行成功!影响到的行数为" + count);} else {System.out.println("执行失败!!");}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{//6.关闭资源if(rs!=null){try {rs.close();} catch (SQLException e) {e.printStackTrace();}finally{rs = null;}}if(stat!=null){try {stat.close();} catch (SQLException e) {e.printStackTrace();}finally{stat = null;}}if(conn!=null){try {conn.close();} catch (SQLException e) {e.printStackTrace();}finally{conn = null;}}}}

执行成功!影响到的行数为1


修改的功能:

我们发现修改的功能和增加的功能代码有很多一样的,所以我们可以将一些功能变为工具类:

将获得数据库连接和异常处理变为工具类

先建立工具类:

package com.itheima.util;import java.io.FileReader;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.util.Properties;public class JDBCUtils {private static Properties prop = null;private JDBCUtils() {}static{try{prop = new Properties();prop.load(new FileReader(JDBCUtils.class.getClassLoader().getResource("config.properties").getPath()));}catch (Exception e) {e.printStackTrace();throw new RuntimeException(e);}}/** * 获取连接 * @throws ClassNotFoundException  * @throws SQLException  */public static Connection getConn() throws ClassNotFoundException, SQLException{// 1.注册数据库驱动Class.forName(prop.getProperty("driver"));// 2.获取连接return DriverManager.getConnection(prop.getProperty("url"), prop.getProperty("user"), prop.getProperty("password"));}/** * 关闭连接 */public static void close(ResultSet rs, Statement stat,Connection conn){if(rs!=null){try {rs.close();} catch (SQLException e) {e.printStackTrace();}finally{rs = null;}}if(stat!=null){try {stat.close();} catch (SQLException e) {e.printStackTrace();}finally{stat = null;}}if(conn!=null){try {conn.close();} catch (SQLException e) {e.printStackTrace();}finally{conn = null;}}}}



上面的是有用到了配置文件:


配置文件的内容是这样的:

driver=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost:3306/day10user=rootpassword=

这时候修改功能的java就是这样:

@Testpublic void update() {Connection conn = null;Statement stat = null;try{conn = JDBCUtils.getConn();stat =  conn.createStatement();stat.executeUpdate("update user set password=999 where name='zhaoliu'");}catch (Exception e) {e.printStackTrace();}finally{JDBCUtils.close(null, stat, conn);}}

查询的功能:

@Testpublic void find(){Connection conn = null;Statement stat = null;ResultSet rs = null;try{conn = JDBCUtils.getConn();stat =  conn.createStatement();rs = stat.executeQuery("select * from user where name='zhaoliu'");while(rs.next()){String name = rs.getString("name");String password = rs.getString("password");System.out.println(name+":"+password);}}catch (Exception e) {e.printStackTrace();}finally{JDBCUtils.close(rs, stat, conn);}}


删除的功能:

public void delete(){Connection conn = null;Statement stat = null;ResultSet rs = null;try{conn = JDBCUtils.getConn();stat =  conn.createStatement();stat.executeUpdate("delete from user where name='zhaoliu'");}catch (Exception e) {e.printStackTrace();}finally{JDBCUtils.close(rs, stat, conn);}}




0 0