JDBC-01
jdbc
前言
在学习了sql语句后,我们肯定会思考如何使用数据库里的数据。这个时候,我们便要学习jdbc来将数据库与java结合在一块。
正题
什么是jdbc?
java数据库连接,(java database connectivity,简称jdbc)是java语言中用来规范客户端程序如何来访问数据库的应用程序接口。
jdbc的主要用途
- 与数据库建立连接
- 发送 sql 语句
- 处理结果
数据库驱动
在学习jdbc之前,我们必须了解一个东西,驱动。
驱动:两个设备(两个应用)之间通信的桥梁。
jdbc的开发步骤
- 加载驱动
- 获取连接
- 基本操作(crud)
- 释放资源
使用jdbc的准备工作
1.创建一个maven项目(当然你也可以不用这种方法,但maven在开发中最为方便)
【创建方式请看我之前的博客:利用maven进行导jar包】
2.导入mysql的jar包
<dependencies> <dependency> <groupid>mysql</groupid> <artifactid>mysql-connector-java</artifactid> <version>5.1.6</version> </dependency> </dependencies>
完成以上的操作,我们便可以开始进行jdbc的学习了。
jdbc的简单例子(先了解一下整体的框架,后面会相应的解释以及简化)
package com.jdbc.demo01; import org.junit.test; import java.sql.*; /** * * jdbc的入门程序 * @author charles * */ public class jdbcdemo1 {
@test public void demo01() throws classnotfoundexception, sqlexception { // 1.加载驱动 class.forname("com.jdbc.driver"); // 2.获得连接 connection conn = drivermanager.getconnection("jdbc:mysql://localhost:3306/web_test3", "root" , "1234"); // 3.基本操作:执行sql // 3.1获得执行sql语句的对象 statement statement = conn.createstatement(); // 3.2编写sql语句: string sql = "select * from user"; // 3.3执行sql: resultset rs = statement.executequery(sql); // 3.4遍历结果集 while (rs.next()){ system.out.println(rs.getint(("id")+ " ")); system.out.println(rs.getint(("username")+ " ")); system.out.println(rs.getint(("password")+ " ")); system.out.println(rs.getint(("nickname")+ " ")); system.out.println(rs.getint(("age"))); system.out.println(); } // 4.释放资源 rs.close(); statement.close(); conn.close(); } }
接下来我来介绍一下上面代码的含义:
// 1.加载驱动,双引号里面的内容一般是标准 class.forname("com.jdbc.driver");
此时,你或许会好奇,不是注册驱动吗,为什么代码是加载驱动。
首先,我们来看看java的api中driver注册驱动的介绍
这种方式的确可以完成驱动的注册,但是实际开发中并不会这么做。
原因:
如果需要注册驱动,就会使用dirvermanager.registerdriver(new driver()); ,但是在查询源代码的时候,我们发现源代码中有一段静态代码块已经调用了注册驱动的方法。因此,如果我们再手动调用注册,就会导致驱动被注册两次。
所以调用 class.forname 将自动将加载驱动程序类。(具体的原理可以查看一些api文档)
②:connection conn = drivermanager.getconnection(url, user, password);
// 2.获得连接 connection conn = drivermanager.getconnection("jdbc:mysql://localhost:3306/web_test3", "root", "1234");
参数介绍:
- url:与数据库连接的路径
- user:与数据库连接的用户名
- password:与数据库连接的密码
url:
"jdbc:mysql://localhost:3306/web_test3"
- jdbc:连接数据库的协议
- mysql:是jdbc的子协议
- localhost:连接的mysql数据库服务器的主机地址【本机:localhost,非本机:连接主机的ip地址】
- 3306:mysql数据库服务器的端口号
- web_test3:数据库名称
commit
rollback
接下来我们来看看statement的详细操作:
作用:①执行sql ②执行批处理
①:常用的执行sql方法: 主要使用的是后两个
- boolean execute(string sql)
执行查询,修改,添加,删除的sql语句
- resultset executequery(string sql)
执行查询(select 语句)
- int executeupdate(string sql)
执行修改,添加,删除的sql语句
②:常用的执行批处理的方法
addbatch
clearbatch
executebatch
结果集的获取可以使用: getxxx(); 通常都会有重载的方法。
getxxx(string columnname);
if(rs != null){ try{ rs.close(); } catch (sqlexception e){ e.printstacktrace(); } rs = null; } if(statement != null){ try{ statement.close(); } catch (sqlexception e){ e.printstacktrace(); } statement = null; } if(conn != null){ try{ conn.close(); } catch (sqlexception e){ e.printstacktrace(); } conn = null; }
package com.charles.sql; import org.junit.*; import java.sql.*; public class demo01 { @test public void demo01(){ connection conn = null; statement statement = null; try{ // 注册驱动 class.forname("com.mysql.jdbc.driver"); // 获得连接 conn = drivermanager.getconnection("jdbc:mysql:///web_test3", "root", "1234); // 执行操作 // 创建执行sql语句对象 statement = conn.createstatement(); // 编写sql语句 string sql = "insert into user values (null, 'eee', '123', 'jack', 21)"; // 执行sql语句 int num = statement.executeupdate(sql); if (num > 0){ system.out.println("保存用户成功!"); } }catch (exception e){ e.printstacktrace(); }finally { // 释放资源 if (statement != null){ try{ statement.close(); } catch (sqlexception e){ e.printstacktrace(); } statement = null; } if (conn != null){ try { conn.close(); }catch (sqlexception e){ e.printstacktrace(); } conn = null; } } } }
package com.charles.sql; import org.junit.*; import java.sql.*; public class demo01 { @test public void demo01(){ connection conn = null; statement statement = null; try{ // 注册驱动 class.forname("com.mysql.jdbc.driver"); // 获得连接 conn = drivermanager.getconnection("jdbc:mysql:///web_test3", "root", "1234"); // 执行操作 // 创建执行sql语句对象 statement = conn.createstatement(); // 编写sql语句 string sql = "update user set password='2222',nickname='biubiu' where id=6"; // 执行sql语句 int num = statement.executeupdate(sql); if (num > 0){ system.out.println("修改用户成功!"); } }catch (exception e){ e.printstacktrace(); }finally { // 释放资源 if (statement != null){ try{ statement.close(); } catch (sqlexception e){ e.printstacktrace(); } statement = null; } if (conn != null){ try { conn.close(); }catch (sqlexception e){ e.printstacktrace(); } conn = null; } } } }
package com.charles.sql; import org.junit.*; import java.sql.*; public class demo01 { @test public void demo01(){ connection conn = null; statement statement = null; try{ // 注册驱动 class.forname("com.mysql.jdbc.driver"); // 获得连接 conn = drivermanager.getconnection("jdbc:mysql:///web_test3", "root", "1234"); // 执行操作 // 创建执行sql语句对象 statement = conn.createstatement(); // 编写sql语句 string sql = "delete from user where id=6"; // 执行sql语句 int num = statement.executeupdate(sql); if (num > 0){ system.out.println("删除用户成功!"); } }catch (exception e){ e.printstacktrace(); }finally { // 释放资源 if (statement != null){ try{ statement.close(); } catch (sqlexception e){ e.printstacktrace(); } statement = null; } if (conn != null){ try { conn.close(); }catch (sqlexception e){ e.printstacktrace(); } conn = null; } } } }
package com.charles.sql; import org.junit.*; import java.sql.*; public class demo01 { @test public void demo01(){ connection conn = null; statement statement = null; resultset rs = null; try{ // 注册驱动 class.forname("com.mysql.jdbc.driver"); // 获得连接 conn = drivermanager.getconnection("jdbc:mysql:///web_test3", "root", "1234"); // 执行操作 // 创建执行sql语句对象 statement = conn.createstatement(); // 编写sql语句 string sql = "select * from user"; // 执行sql语句 rs = statement.executequery(sql); while(rs.next()){ system.out.println(rs.getint(("id")+ " ")); system.out.println(rs.getint(("username")+ " ")); system.out.println(rs.getint(("password")+ " ")); system.out.println(rs.getint(("nickname")+ " ")); system.out.println(rs.getint(("age"))); system.out.println(); } }catch (exception e){ e.printstacktrace(); }finally { // 释放资源 if (statement != null){ try{ statement.close(); } catch (sqlexception e){ e.printstacktrace(); } statement = null; } if (conn != null){ try { conn.close(); }catch (sqlexception e){ e.printstacktrace(); } conn = null; } if (rs != null){ try { rs.close(); }catch (sqlexception e){ e.printstacktrace(); } conn = null; } } } }
package com.charles.sql; import org.junit.*; import java.sql.*; public class demo01 { @test public void demo01(){ connection conn = null; statement statement = null; resultset rs = null; try{ // 注册驱动 class.forname("com.mysql.jdbc.driver"); // 获得连接 conn = drivermanager.getconnection("jdbc:mysql:///web_test3", "root", "1234"); // 执行操作 // 创建执行sql语句对象 statement = conn.createstatement(); // 编写sql语句 string sql = "select * from user where id=1"; // 执行sql语句 rs = statement.executequery(sql); if(rs.next()){ system.out.println(rs.getint("id")+" "+rs.getstring("username")+" "+re.getstring("password")); } }catch (exception e){ e.printstacktrace(); }finally { // 释放资源 if (statement != null){ try{ statement.close(); } catch (sqlexception e){ e.printstacktrace(); } statement = null; } if (conn != null){ try { conn.close(); }catch (sqlexception e){ e.printstacktrace(); } conn = null; } if (rs != null){ try { rs.close(); }catch (sqlexception e){ e.printstacktrace(); } conn = null; } } } }
目的:包装成工具类后,能够更方便地使用jdbc,减少不必要的工作量
package org.charl; import java.sql.*; /** * jdbc工具类 * @author charles */ public class demo { // 默认设置 public static final string driverclassname; public static final string url; public static final string username; public static final string password; static { driverclassname = "com.mysql.jdbc.driver"; url = "jdbc:mysql:///web_test3"; username = "root"; password = "1234"; } // 注册驱动类 public static void loaddriver(){ try { class.forname(driverclassname); } catch (classnotfoundexception e) { e.printstacktrace(); } } // 获得连接 public static connection getconnection(){ connection conn = null; try { loaddriver(); conn = drivermanager.getconnection(url,username,password); } catch (sqlexception e) { e.printstacktrace(); } return conn; } // 资源释放 public static void release(statement st,connection conn){ if (st != null){ try{ st.close(); } catch (sqlexception e){ e.printstacktrace(); } st = null; } if (conn != null){ try { conn.close(); }catch (sqlexception e){ e.printstacktrace(); } conn = null; } } public static void release(statement st,connection conn, resultset rs){ if (st != null){ try{ st.close(); } catch (sqlexception e){ e.printstacktrace(); } st = null; } if (conn != null){ try { conn.close(); }catch (sqlexception e){ e.printstacktrace(); } conn = null; } if (rs != null){ try { rs.close(); }catch (sqlexception e){ e.printstacktrace(); } rs = null; } } }
在工具类中解析属性文件
sql注入漏洞的解决方法
采用preparedstatement对象解决sql注入漏洞问题。该对象将sql预先进行编译,使用'?'作为占用符。'?'所代表的内容是sql所固定。如果再次传入变量(包括sql的关键字),这个时候也不会识别这些关键字。
具体操作:
package com.charles.sql; import java.sql.*; /*** * @return * @author charles */ public class demo02 { public boolean login(string username, string password){ connection conn = null; preparedstatement preparedstatement = null; resultset rs = null; boolean flag = false; try{ conn = org.charl.demo.getconnection(); string sql = "select * from user where username = ? and password = ?"; preparedstatement = conn.preparestatement(sql); // 设置参数 preparedstatement.setstring(1,username); preparedstatement.setstring(2,password); rs = preparedstatement.executequery(); if (rs.next()){ flag = true; } } catch (sqlexception e){ e.printstacktrace(); } finally { org.charl.demo.release(preparedstatement,conn,rs); } return flag; } }
接下来展示一下比较完整的实例:
【里面包含了preparedstatement等内容,之前的案例看不懂没关系,这个案例供大家参考】
数据库web_test4中user表原先的信息
工具类代码
package org.charl; import java.sql.*; import java.util.properties; /** * jdbc工具类 * @author charles */ public class demo { // 默认设置 public static final string driverclassname; public static final string url; public static final string username; public static final string password; static { driverclassname = "com.mysql.jdbc.driver"; url = "jdbc:mysql:///web_test4?rewritebatchedstatements=true?characterencoding=utf-8"; username = "root"; password = "1234"; } // 注册驱动类 public static void loaddriver(){ try { class.forname(driverclassname); } catch (classnotfoundexception e) { e.printstacktrace(); } } // 获得连接 public static connection getconnection(){ connection conn = null; try { loaddriver(); conn = drivermanager.getconnection(url,username,password); } catch (sqlexception e) { e.printstacktrace(); } return conn; } // 资源释放 public static void release(statement st,connection conn){ if (st != null){ try{ st.close(); } catch (sqlexception e){ e.printstacktrace(); } st = null; } if (conn != null){ try { conn.close(); }catch (sqlexception e){ e.printstacktrace(); } conn = null; } } public static void release(statement st,connection conn, resultset rs){ if (st != null){ try{ st.close(); } catch (sqlexception e){ e.printstacktrace(); } st = null; } if (conn != null){ try { conn.close(); }catch (sqlexception e){ e.printstacktrace(); } conn = null; } if (rs != null){ try { rs.close(); }catch (sqlexception e){ e.printstacktrace(); } rs = null; } } }
执行主代码
package com.charles.sql; import org.junit.test; import java.sql.*; public class demo03 { @test public void test(){ long begin = system.currenttimemillis(); connection conn = null; preparedstatement preparedstatement = null; resultset rs = null; try{ // 注册驱动 + 获得连接 conn = org.charl.demo.getconnection(); // 编写sql语句 string sql = "insert into user values(null,?)"; // 预编译 preparedstatement = conn.preparestatement(sql); for (int i =1;i<10000;i++){ preparedstatement.setstring(1,"name"+i); // 添加到批处理 preparedstatement.addbatch(); // 执行批处理 if (i % 1000 == 0){ preparedstatement.executebatch(); // 进行清空防止数据溢出 preparedstatement.clearbatch(); } } }catch (exception e){ e.printstacktrace(); }finally { // 释放资源 org.charl.demo.release(preparedstatement,conn,rs); } long end = system.currenttimemillis(); system.out.println("耗时:"+ (end - begin) + "ms"); } }
执行成功后:
控制台
此时user表中的数据
小结
以上就是jdbc入门的介绍,当然在刚学习jdbc的时候,肯定会出现许多错误,这些错误或许一时间会让你抓狂,但请耐心地解决,相信后面收获肯定满满的。
加油!
时间:2020-04-02 20:57:18