宝剑锋从磨砺出,梅花香苦自苦寒来。
1. Class.forName("com.mysql.cj.jdbc.Driver"); # jdbc8.0版本的驱动 2. Class.forName("com.mysql.jdbc.Driver"); # jdbc8.0之前的版本
简要说明
Statement: 用于执行静态SQL语句并返回其生成的结果的对象。
DriverManager: 驱动管理对象
getConnection(String url,String user,String password)
url:" jdbc:mysql://主机名称:mysql服务端口号/数据库名称"?参数=值&参数=值
Driver接口: Java.sql.Driver 接口是所有 JDBC 驱动程序需要实现的接口。这个接口是提供给数据库厂商使用的,不同数据库厂商提供不同的实现。
步骤:
1. 导入驱动jar包 2. 注册驱动 3. 获取数据库连接对象Connection 4. 定义sql 5. 获取执行sql语句的对象statement 6. 执行sql,接受返回结果 7. 处理结果 8. 释放资源
初试:
package com.jdbc_learn.test; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement; public class jdbcFirstDemo { public static void main(String[] args) throws Exception{ //1. 导入驱动 //2. 注册驱动 Class.forName("com.mysql.cj.jdbc.Driver"); //3.获取数据库连接对象 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1","root", "111"); //4.定义sql语句 String sql = "update grades set grade = 10 where id = 4"; //5.获取执行对象sql的对象 statement Statement stmt = conn.createStatement(); //6.执行sql int count = stmt.executeUpdate(sql); System.out.println(count); //7.释放资源 stmt.close(); conn.close(); } }
运行后查看数据库:
二、prepareStatement- 表示预编译的SQL语句的对象, 执行动态SQL语句。 可以通过调用 Connection 对象的
- preparedStatement(String sql) 方法获取 PreparedStatement 对象。
- SQL语句已预编译并存储在PreparedStatement对象中。 然后可以使用该对象多次有效地执行此语句。
PreparedStatement 优点:
- SQL 注入是利用某些系统没有对用户输入的数据进行充分的检查,而在用户输入数据中注入非法的 SQL 语句段或命令,从而利用系统的 SQL引擎完成恶意行为的做法。对于 Java 而言,要防范 SQL 注入,只要用PreparedStatement 取代 Statement就可以了。
- Update大量的数据时, 先构建一个INSERT语句再多次的执行, 会导致很多次的网络连接.。要减少JDBC的调用次数改善性能, 可以使用PreparedStatement的AddBatch()方法一次性发送多个查询给数据库。
代码:
package com.jdbc_learn.test; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.Statement; public class jdbcTwoDemo { public static void main(String[] args) throws Exception{ //注册驱动 Class.forName("com.mysql.cj.jdbc.Driver"); //获取数据库连接对象 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1","root","111"); // 更新数据 //PreparedStatement pre = conn.prepareStatement("update grades set grade=? where id=1"); //pre.setInt(1,49); //插入数据 PreparedStatement pre = conn.prepareStatement("insert into grades values(null ,?,?)"); // pre.setInt(1, 0); pre.setString(1,"新1"); pre.setInt(2, 100); int i = pre.executeUpdate(); System.out.println(i); } }
运行结果:
完善后:
package com.jdbc_learn.test; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; public class Demo3 { public static void main(String[] args){ Connection conn=null; PreparedStatement pre=null; try { Class.forName("com.mysql.cj.jdbc.Driver"); //获取数据库连接对象 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1","root","111"); // 更新数据 //PreparedStatement pre = conn.prepareStatement("update grades set grade=? where id=1"); //pre.setInt(1,49); //插入数据 pre = conn.prepareStatement("insert into grades values(null ,?,?)"); // pre.setInt(1, 0); pre.setString(1,"新3"); pre.setInt(2, 100); int i = pre.executeUpdate(); System.out.println(i); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { try { pre.close(); conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }三、jdbc.properties配置文件
properties类表示一组持久的属性。properties可以保存到流中或从流中加载。 属性列表中的每个键及其对应的值都是一个字符串。
//加载,读取jdbc.properties配置的信息
//pro.load的作用是把jdbc.properties文件中配置的信息,一一put到pro这个map中
Properties中的主要方法:
(1)load(InputStream inStream) 从输入字节流中读取属性列表(键和元素对)。
pro.load(ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties"));
(2)getProperty/setProperty
这两个方法是分别是获取和设置属性信息。
pro.getProperty("user")
示例:
在src下建立文件jdbc.properties
代码:
package com.jdbc_learn.test; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.util.Properties; public class Demo3 { public static void main(String[] args) throws Exception{ //预先加载配置文件jdbc.properties,把配置信息封装到Properties对象中 Properties pro = new Properties(); Connection conn = null; PreparedStatement pre = null; try { pro.load(ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties")); // 加载与注册驱动 Class.forName(pro.getProperty("driver")); //获取数据库连接 conn = DriverManager.getConnection(pro.getProperty("url"), pro.getProperty("user"), pro.getProperty("password")); pre = conn.prepareStatement("insert into grades values(null, ?, ?)"); pre.setString(1,"李四"); pre.setInt(2,30); int count = pre.executeUpdate(); if(count>0) { System.out.println(" sucess!"); } else { System.out.println("error!"); } } catch (IOException e) { e.printStackTrace(); } finally { pre.close(); conn.close(); } } }
运行结果:
-
表示数据库结果集的数据表,通常通过执行查询数据库的语句生成。
-
ResultSet对象保持一个光标指向其当前的数据行。 最初,光标位于第一行之前。 next方法将光标移动到下一行,并且由于在ResultSet对象中没有更多行时返回false ,因此可以在while循环中使用循环来遍历结果集。
-
默认的ResultSet对象不可更新,并且只有一个向前移动的光标。 因此,您只能从第一行到最后一行迭代一次。
ResultSet 接口的常用方法:
- boolean next() 遍历
- getXxx(String columnLabel):columnLabel使用 数字索引指定的列标签或者,使用列名称
- getXxx(int index) :索引从1开始
读取方法1 –通过索引来遍历读取:
while (result.next()) { int id = result.getInt(1); //从 1开始 String name = result.getString(2); int grade = result.getInt(3); System.out.println("id="+id+" "+"name="+name+" "+"grade="+grade); }
读取方法2 – 通过字段名称来读取
略
完整代码:
package com.jdbc_learn.test; import javax.xml.transform.Result; import java.io.IOException; import java.sql.*; import java.util.Properties; public class Resultset_test { public static void main(String[] args) throws Exception{ //预先加载配置文件jdbc.properties,把配置信息封装到P。个体roperties对象中 Properties pro = new Properties(); Connection conn = null; Statement statement = null; try { pro.load(ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties")); // 加载与注册驱动 Class.forName(pro.getProperty("driver")); //获取数据库连接 conn = DriverManager.getConnection(pro.getProperty("url"), pro.getProperty("user"), pro.getProperty("password")); String sql = "select * from grades;"; statement = conn.createStatement(); //执行查询并返回结果集 ResultSet result = statement.executeQuery(sql); while (result.next()) { int id = result.getInt(1); //从 1开始 String name = result.getString(2); int grade = result.getInt(3); System.out.println("id="+id+" "+"name="+name+" "+"grade="+grade); } } catch (IOException e) { e.printStackTrace(); } finally { statement.close(); conn.close(); } } }
运行结果:
游标可以前后移动,也可移动与当前位置相关的某一行.
结果集可更新.
boolean absolute(int row) 纪录集定位到第某条
void beforeFirst() 移到第一条纪录前
可以移动游标
记得释放资源
七、总结(1)加载和注册驱动,整个项目做一次即可
(2)获取数据库连接可以封装到一个方法中
(3)释放资源可以封装到一个方法中
(4)JDBC驱动的最佳化是基于使用的是什么功能,选择PreparedStatement还是Statement取决于你要怎么使用它们,对于只执行一次的SQL语句选择Statement是最好的。相反,如果SQL语句被多次执行选用PreparedStatement是最好的。
(5)PreparedStatement的第一次执行消耗是很高的,它的性能体现在后面的重复执行,使用PreparedStatement的方式来执行一个针对数据库表的查询,JDBC驱动会发送一个网络请求到数据解析和优化这个查询,而执行时会产生另一个网络请求,在JDBC驱动中,减少网络通讯是最终的目的。如果我的程序在运行期间只需要一次请求, 那么就使用Statement,对于Statement,同一个查询只会产生一次网络到数据库的通讯。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)