mysql-connector-java-xxx-bin.jar包的使用
Class.forName("com.mysql.jdbc.Driver")的作用
第一步、将mysql连接包放在lib目录上,并右键Build Path——Add to Build Path,即可将其加载进eclipse中的引用包Reference Library下,作为提供ava中连接数据库的驱动。
第二步、编写代码,Student实体对象类、JDBC类以及测试类。
Student类:
package com.xiaoxiao.jdbc; public class Student { public static int id; public static String name; public static int age; public Student(int id,String name,int age){ this.id=id; this.name=name; this.age=age; } public static int getId() { return id; } public static void setId(int id) { Student.id = id; } public static String getName() { return name; } public static void setName(String name) { Student.name = name; } public static int getAge() { return age; } public static void setAge(int age) { Student.age = age; } }
JDBC类:
package com.xiaoxiao.jdbc; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import com.xiaoxiao.forExemple.Person; public class JDBC { Connection connection; //连接数据库的连接对象 PreparedStatement preparedStatement; //预编译语句 ResultSet resultSet; //获得的结果集 //编辑数据库连接池:mysql数据库连接驱动(com.mysql.jdbc.Driver)、JDBC url地址、登录名和密码 public Connection getConnection(){ String url="jdbc:mysql://localhost:3306/family"; String userName="root"; String password="1234"; try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { System.out.println("找不到驱动"); e.printStackTrace(); } try { connection=DriverManager.getConnection(url,userName,password); if (connection!=null) { System.err.println("数据库连接成功"); } } catch (SQLException e) { System.out.println("数据库连接失败"); e.printStackTrace(); } return connection; } /* * 1、执行静态SQL语句。通常通过Statement实例实现。 这应该是某个指定的sql语句 * 2、执行动态SQL语句。通常通过PreparedStatement实例实现。 但这应该是多条(much manty)sql语句 * 3、执行数据库存储过程。通常通过CallableStatement实例实现。 */ public void querySql(){ System.out.println("开始在数据库查询sql语句"); String sql = "select * from student "; connection =getConnection(); //连接数据库 try { preparedStatement=connection.prepareStatement(sql); //获取预编译的sql语句 // 创建Statement对象并设置参数(问题:这里明明设置的是prepareStatement对象,怎么成了Statement对象呢,难道是一次性执行sql语句的原因) resultSet =preparedStatement.executeQuery(sql); //执行sql语句 while(resultSet.next()){ String id=resultSet.getString(1); String name=resultSet.getString(2); String age=resultSet.getString(3); System.out.println(id+"\t"+name+"\t"+age+"\t"+"你是我心目中英雄"); //遍历resultSet里的所有sql语句,并将其id,name,age的属性值全转化为字符串的形式 用图表的形式打印出来 } } catch (SQLException e) { System.out.println("查询数据库失败了"); e.printStackTrace(); }finally { // 停止执行sql语句,关闭生成sql语句的进程以及关掉与数据库交互的连接,进而达到释放资源内存的作用 try { resultSet.close(); preparedStatement.close(); connection.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public void queryStudentById(int id){ System.out.println("------------这究竟是一个怎样的方法!-----------------"); String sql = "select name,age from student where id=?"; connection =getConnection(); try { preparedStatement = connection.prepareStatement(sql); preparedStatement.setInt(1, id); //设置占位符对应的值 resultSet = preparedStatement.executeQuery(); //这里为什么不能添加参数sql while(resultSet.next()){ Student student = new Student(); student.setId(id); student.setName(resultSet.getString(1)); //这里的resultSet.getString()是个什么鬼 student.setAge(resultSet.getInt(2)); System.out.println(student); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void addSql(){ String sql="INSERT INTO family.student(id,name,age) VALUES(?,?,?)"; connection =getConnection(); try { preparedStatement =connection.prepareStatement(sql); //错误: Duplicate entry '3' for key 'PRIMARY'---》主键重复输入“3” 因为当我看看表的时候才发现我的3、肖文飞、15已经在数据库被创建了 preparedStatement.setString(1,"6"); preparedStatement.setString(2, "周楠"); preparedStatement.setString(3,"22"); preparedStatement.executeUpdate(); System.out.println("已经成功添加创建了一条新的数据了"); } catch (SQLException e) { System.out.println("重复添加一条数据,即已经被添加或被创建了"); e.printStackTrace(); }finally { try { preparedStatement.close(); connection.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } /* * 通过传参数的形式 为value 赋值 */ public void addSql1(Student student){ String sql="INSERT INTO family.student(id,name,age) VALUES(?,?,?)"; connection =getConnection(); try { preparedStatement =connection.prepareStatement(sql); preparedStatement.setInt(1,student.getId()); preparedStatement.setString(2, student.getName()); preparedStatement.setInt(3,student.getAge()); preparedStatement.executeUpdate(); //处理以上结果集 System.out.println("已经成功添加创建了一条新的数据了"); } catch (SQLException e) { System.out.println("重复添加一条数据,即已经被添加或被创建了"); e.printStackTrace(); }finally { try { preparedStatement.close(); connection.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public void deleteSql(){ String sql="DELETE FROM `family`.`student` WHERE `id`='7'"; connection = getConnection(); try { preparedStatement =connection.prepareStatement(sql); preparedStatement.executeUpdate(sql); System.out.println("成功删除了id为7的 数据"); } catch (SQLException e) { System.out.println("删除操作失败,这是为什么呢"); e.printStackTrace(); } } public void updateSql(){ String sql="UPDATE `family`.`student` SET `name`='肖肖肖' WHERE `id`='7'"; connection =getConnection(); try { preparedStatement=connection.prepareStatement(sql); preparedStatement.executeUpdate(sql); System.out.println("更新修改成功"); } catch (SQLException e) { System.out.println("这是一首简单的小情歌,但是你还是测试失败了,这怪谁呢"); e.printStackTrace(); } } }
测试类TestDemo:
package com.xiaoxiao.jdbc; /* * 通过java程序对数据库进行增删查改 */ public class TestDemo { public static void main(String[] args) { JDBC jdbc=new JDBC(); jdbc.querySql(); System.out.println("---------------------------这是一首简单的小情歌,华丽的分割线--------------------------------"); jdbc.queryStudentById(1); // jdbc.addSql(); //当我已经执行一遍这个方法的时候 ,再执行的时候就会重复添加相同的数据。 执行一次不可以再执行了! // jdbc.deleteSql(); //删除一个sql语句,即就是删除一条语句 // jdbc.updateSql(); //修改 数据库的某个字段。 // Student student=new Student(10,"周楠",22); // jdbc.addSql1(student); // jdbc.addSql1(new Student(10, "周楠", 22)); //通过传参数的形式对数据库进行一些操作,比如添加一条新的数据 } }
控制台输出如下:

z注意:
1)、如果没有上传mysql连接驱动包mysql-connector-java-xxx-bin.jar,就会报错:ClassNotFoundException—>com.mysql.jdbc.Driver,即驱动找不到

所以
Class.forName("com.mysql.jdbc.Driver");
这一段代码的作用就是用来加载指定驱动类的。
为什么需要手动去加载这个驱动类呢?正常情况下,对于一个java程序而言我们是不需要去管这个类的加载,只需要在需要用的时候直接import进去即可,但是对于JDBC的设计而言就不同 ,从代码:
connection=DriverManager.getConnection(url,userName,password);
我们知道,决定使用哪个驱动并不是由我们开发者指定的(我们只能指定连接数据库的url地址、登录用户名以及密码),而是通过遍历所有已注册的驱动来尝试获取连接的,成功就返回connection,反之连接数据库失败,所以代码中没有显示指定的驱动,可从如下的DrverManager代码可以看出:
for(DriverInfo aDriver : registeredDrivers) { // If the caller does not have permission to load the driver then // skip it. if(isDriverAllowed(aDriver.driver, callerCL)) { try { println(" trying " + aDriver.driver.getClass().getName()); Connection con = aDriver.driver.connect(url, info); if (con != null) { // Success! println("getConnection returning " + aDriver.driver.getClass().getName()); return (con); } } catch (SQLException ex) { if (reason == null) { reason = ex; } } } else { println(" skipping: " + aDriver.getClass().getName()); } }
这个类基本可以明白JDBC是如何获取连接的,问题是:registeredDrivers是怎么来的?请看如下com.mysql.jdbc.Driver的一段static代码:
// // Register ourselves with the DriverManager // static { try { java.sql.DriverManager.registerDriver(new Driver()); } catch (SQLException E) { throw new RuntimeException("Can't register driver!"); } }
在DriverManager类下有一个registerDriver(new Driver())方法,能处理新注册的驱动,即此方法将新注册驱动加载进集合registedDrivers中,然后通过遍历的方式识别驱动。而
Class.forName("com.mysql.jdbc.Driver");
就是指定当前类加载的是mysql驱动、sql server驱动还是orcle驱动。
2)、PreparedStatement接口以及ResultSet结果集
说明:
1、PreparedStatement接口继承Statement,它的实例包含预编译的sql语句,当然比statement执行得更快。
2、PreparedStatement接口继承了Statement的所有功能方法,为:executeUpdate、executeQuery、execute
3、在jdbc应用中,一般都用PreparedStatement,而不是Statement。
通过调用Connection对象的prepareStatement(sql)方法来获取 预编译的sql对象,并保存至PerparedStatement对象中,然后通过执行executeQuery()方法获取执行静态 SQL 语句并返回它所生成结果的对象。

浙公网安备 33010602011771号