文章目录

  • JDBC
    • 概念
    • 使用步骤
    • idea 创建项目并导入jar包
    • 入门案例
    • SQL注入
    • SQL注入的解决方案
  • JDBC常见问题
    • Class.forName这句话有用没?
    • 驱动版本
    • 中文乱码
    • SQL注入
    • PreparedStatement 语句
  • 常见错误
    • java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
    • Unknown database mydb;
    • Access denied for user 'root123'@'localhost' (using password: YES)
    • Table 'py-school-db.mydb' doesn't exist

JDBC

概念

我们学习了数据库,数据库实现了数据的持久化,但我们最终要在程序里处理数据啊,那java代码中怎么去访问数据库读写数据呢?

这就要用到sun公司设定的一套数据库标准了,这套标准就是JDBC(Java Database Connectivity)。但它只是规范,不做具体实现。于是数据库厂商又根据JDBC标准,实现自家的驱动Driver。如:mysql驱动com.mysql.cj.jdbc.Driver,Oracle的驱动oracle.jdbc.OracleDriver。有了这套解决方案,java就可以访问数据库中的数据了。

public interface Connection extends Wrapper, AutoCloseable {}public interface Statement extends Wrapper, AutoCloseable {}public interface PreparedStatement extends Statement {}public interface CallableStatement extends PreparedStatement {}public interface ResultSet extends Wrapper, AutoCloseable {}

Java中提倡面向接口开发,而最经典的接口设计莫过于JDBC数据库接口。

Connection链接、Statement语句、PreparedStatement预处理语句、CallableStatement存储过程、ResultSet结果集。

调用方式有三种:Statement语句、PreparedStatement预处理语句、CallableStatement存储过程,推荐使用第二种PreparedStatement,防止SQL注入,其也是预编译性能高。

使用步骤

导入jar包(丰富的工具类)

获取和数据库的连接(用户名、密码)

通过程序执行SQL

通过程序处理结果

idea 创建项目并导入jar包

  • 创建stage2 Java工程
  • 创建lib目录,拷贝驱动objbc6-11.1.0.7.0到lib目录下
  • 项目引用这个外部jar包

入门案例

package cn.tedu.jdbc;import java.sql.*;//测试 jdbc
//需求:查询cgb2104库里的students表里的所有数据
public class Test1 {public static void main(String[] args) throws Exception {//1,注册驱动Class.forName("com.mysql.jdbc.Driver");//2,获取和数据库的连接
//String url= "jdbc:mysql://localhost:3306/cgb2104?characterEncoding=utf8";//指定要连接哪个数据库
String url= "jdbc:mysql:///cgb2104?characterEncoding=utf8";//指定要连接哪个数据库String user= "root" ; //使用的用户名String pwd= "root" ; //使用的密码Connection conn = DriverManager.getConnection(url, user, pwd);//3,获取传输器,执行SQLStatement st = conn.createStatement();//4,执行SQLResultSet rs = st.executeQuery("select * from students");//5,解析结果集while( rs.next() ){//next()判断结果集中是否有数据for (int i = 1; i <= 5 ; i++) {//获取每列的值并打印System.out.println( rs.getString(i) );}}//6,释放资源rs.close(); //关闭结果集st.close();//关闭传输器conn.close();//关闭连接}
}

SQL注入

/*自己准备user2表(id/name/password),准备数据CREATE TABLE `user2` (`id` int(11)  PRIMARY KEY  auto_increment,`name` varchar(10) default NULL,`password` varchar(10) default NULL) ;*/
//需求:利用jdbc,根据用户名和密码查询cgb2104库里的user表
//SQL注入攻击问题
private static void login() {try{Class.forName("com.mysql.jdbc.Driver");String url="jdbc:mysql:///cgb2104?characterEncoding=utf8";Connection conn = DriverManager.getConnection(url, "root", "root");Statement st = conn.createStatement();
// String sql ="select * from user2 where name='jack' and password='123456'";//写死了String user = new Scanner(System.in).nextLine();//用户输入jack'#String pwd = new Scanner(System.in).nextLine();//SQL注入攻击问题:本质上是因为SQL语句中出现了特殊符号#,改变了SQL语义
String sql ="select * from user2 where name='"+user+"' and password='"+pwd+"'";ResultSet rs = st.executeQuery(sql);//执行查询的SQL,返回结果集if(rs.next()){System.out.println("登录成功~");}else{System.out.println("登录失败~");}st.close();conn.close();}catch(Exception e){e.printStackTrace();//有异常,直接打印异常信息//System.out.println("执行失败。。。");//上线}}

SQL注入的解决方案

//解决SQL注入攻击的方案
private static void login2() {try{Class.forName("com.mysql.jdbc.Driver");String url="jdbc:mysql:///cgb2104?characterEncoding=utf8";Connection conn = DriverManager.getConnection(url, "root", "root");
//            Statement st = conn.createStatement();不行,不安全,会被SQL攻击String user = new Scanner(System.in).nextLine();//用户输入jack'#String pwd = new Scanner(System.in).nextLine();//?叫占位符 ,SQL的骨架
String sql ="select * from user2 where name=? and password=?";//先把SQL骨架发给数据库执行PreparedStatement ps = conn.prepareStatement(sql);//给SQL里的? 设置参数ps.setString(1,user);//给第一个?设置值是userps.setString(2,pwd);//给第二个?设置值是pwdResultSet rs = ps.executeQuery();//执行拼接好的SQL,返回结果集if(rs.next()){System.out.println("登录成功~");}else{System.out.println("登录失败~");}ps.close();conn.close();}catch(Exception e){e.printStackTrace();//有异常,直接打印异常信息//System.out.println("执行失败。。。");//上线}
}

JDBC常见问题

Class.forName这句话有用没?

Class.forName可以指定class类路径进行动态创建对象实例,可JDBC这句话没有返回对象啊,那写这句有什么作用呢?看看java.sql.Driver.class的源码就找到真相了,原来它用了静态代码块创建对象。

    static {try {DriverManager.registerDriver(new Driver());} catch (SQLException var1) {throw new RuntimeException("Can't register driver!");}}

写了创建了,那不写呢?怎么不写也能执行呢?

Java提供了SPI机制,用户可以自行配置类,JDBC高版本驱动就都引入了这个支持。如果用户使用了Class.forName方式就自己指定了驱动,如果未写这句话,则Java自动去META-INF/services/java.sql.Driver文件中找启动类。

驱动版本

不同版本的mysql需要不同版本的驱动

Mysql5.0x mysql-connector-java-5.1.32.jarMysql8.0x mysql-connector-java-8.0.21.jar
  • Driver变成了: com.mysql.cj.jdbc.Driver,中间多了cj
  • url必须加时区参数: serverTimezone=Asia/Shanghai

中文乱码

url增加参数:characterEncoding=utf8防止中文乱码

String url ="jdbc:mysql://localhost:3306/mydb?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false";

SQL注入

String condition = "陈强";
String condition = "陈强' or 1=1 or '";
String condition = "陈强' or true or '";String sql = "select * from teachers where tname='" + condition+"'";

利用sql中'单撇是字符串的结束符,or只要一个条件成立其它就不用再判断,而恶意造成sql查询失效,本应该只展示一条数据,结果全部展现。

注入后形成的SQL:

SELECT * FROM teachers WHERE tname='陈强' OR 1=1 OR ''

大家试想如果是一个财务表,本你只能看自己的信息,结果你看了所有人的信息。结果新员工比你工资高,你说气人不。

PreparedStatement 语句

SQL注入解决方案:

Statement对象换为PreparedStatement对象

sql = "select * from teachers where tname=?";            #参数使用问号
PreparedStatement stat = cn.prepareStatement(sql);         #对象换掉
stat.setString(1, condition);                   #对应参数类型,第几个问号
ResultSet rs = stat.executeQuery();            #去掉sql参数

PS后的结果:

SELECT * FROM teachers WHERE tname='陈强\' or 1=1 or \''

利用转义字符,屏蔽了SQL中的恶意字符。不仅解决了sql注入问题,使系统变的安全,PreparedStatement还有个极大的好处,它是预编译的语句,其主干部分mysql进行预编译后缓存,下次这部分就无需在解析,只把条件拼入,这样执行效率远高于statement每次都要编译sql语句。

常见错误

java.lang.ClassNotFoundException: com.mysql.jdbc.Driver

错误原因:

1)jar没有导入,没有builder path

2)Class.forName("com.mysql.jdbc.Driver"); 字符串拼写错误

Unknown database mydb;

错误原因:

数据库名称拼写错误

Access denied for user ‘root123’@‘localhost’ (using password: YES)

错误原因:

数据库用户名或者密码错误

Table ‘py-school-db.mydb’ doesn’t exist

错误原因:

表不存在,也可能表名写错了

JDBC从入门到精通相关推荐

  1. Mybatis从入门到精通(全)

    目录 前言 1. idea软件小技巧 2. mybatis优势 3. mybatis入门项目 3.1 项目具体步骤 3.2 创建数据表 3.3 创建maven项目 3.4 pom.xml配置文件 3. ...

  2. java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全)

    目录 前言 1. 学习路线 2. 学习方法 前言 这篇文章主要总结我之前所学过的框架以及学习路线 从实打实的零基础到框架再到项目 之后实习工作 也在这篇博客中记录我的学习笔记 以及在笔记中遇到的配置安 ...

  3. java从入门到精通_想要开始学java?你要的java从入门到精通布列如下!

    java从入门到精通,让我来告诉你! 毫无疑问,java是当下最火的编程语言之一.对于许多未曾涉足计算机编程的领域「小白」来说,深入地掌握java看似是一件十分困难的事.其实,只要掌握了科学的学习方法 ...

  4. Java学习从入门到精通

    Java Learning Path (一).工具篇 一. JDK (Java Development Kit) JDK是整个Java的核心,包括了Java运行环境(Java Runtime Envi ...

  5. Mybatis从入门到精通下篇

    Mybatis从入门到精通下篇: 输入类型: 输出类型: ResultMap: 动态sql: if标签: where标签: sql片段: foreach标签: 关联查询: 以订单作为主体: 一对一查询 ...

  6. Oracle 从入门到精通视频教程(11G版本)

    <Oracle 从入门到精通>中的视频教程和PPT资料. 下载地址 Oracle 11G从入门到精通视频的PPT http://down.51cto.com/data/376701 第1章 ...

  7. @aspect注解类不生效_Spring Boot从入门到精通(三)常用注解含义及用法分析总结...

    Spring Boot是目前非常流行的框架,而注解是Spring Boot的核心功能,接下来主要说一说Spring Boot常用注解的含义以及部分注解在项目中的使用方法. @RestControlle ...

  8. Java学习从入门到精通[转]

    Java Learning Path (一).工具篇   一. JDK (Java Development Kit) JDK是整个Java的核心,包括了Java运行环境(Java Runtime En ...

  9. mybatis 存储过程 tmp_count_MyBatis从入门到精通

    MyBatis是一款优秀的持久层框架,它支持定制化SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis可以使用简单的 XML或注解 ...

最新文章

  1. ExecutorService 的理解与使用
  2. IIS日志清理CMD版,VBS版,JS版,WSH版
  3. 拖动改变Table的列宽度
  4. RabbitMQ消息手动应答生产者
  5. 【转】国密加密算法SM系列的C#实现方法
  6. 力扣 验证二叉搜索树
  7. ajax请求上传数组
  8. spring.net 对象创建 几种情况
  9. C++ std::condition_variable 是什么 有什么用 条件变量 线程同步 wait wait_for notify_one notify_all
  10. CRT和LCD显示器的区别
  11. Xcode:iOS崩溃日志分析方法
  12. 阿里云RDS数据库与自建数据库做主从同步
  13. 验证方法学的发展历程及比较
  14. 百面机器学习 自学笔记
  15. FPGA基础实验:点亮LED
  16. python实现将图像合成GIF图
  17. 【通信原理| OFDM技术的最简讲解(上)】窄带、宽带与频分复用、多载波调制的讲解
  18. Keystone 认证服务
  19. linux18安装anyconnect4.9遇到I/O问题
  20. 软驱光碟安装linux系统,无光驱和软驱安装debian的方法

热门文章

  1. 爱创课堂每日一题第二十三天- Expires和Cache-Control?
  2. 淘系自研前端研发工具 AppWorks 正式发布
  3. 基于matlab毕业设计题目,matlab毕业设计题目.doc
  4. Mixed Content: The page was loaded over HTTPS,blocked the content must be served over HTTPS.
  5. 从小白踏上程序员之路
  6. 手机用户对手机游戏的偏好调查
  7. 一文读懂GPU服务器
  8. 国庆福利赠书,书籍全部包邮送!
  9. 高仿网易评论列表效果之界面分析
  10. java 地图坐标转换_百度地图经纬度和地址互转(Java代码)