JDBC的定义和作用

  DBC(Java DataBase Connectivity) Java数据库连接, 其实就是利用Java语言/程序连接并访问数据库的一门技术。

   之前我们可以通过cmd或者navicat等工具连接并访问数据库,但是在企业开发中,我们更多的是通过程序连接并访问数据库。如果通过Java程序访问数据库,就必须要使用JDBC这门技术!!

JDBC访问数据库操作

  创建一个 jt_db 数据库,在库中创建一个account表,并插入三条记录,然后利用Java程序查询出account表中所有的记录,并打印在控制台上。

快速人门程序了解:

创建Java类并实现JDBC程序(大致分为六个步骤)

package com.tedu;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement; //JDBC快速入门程序
public class JdbcDemo1 {
public static void main(String[] args) throws Exception {
/*
* 通过Java程序查询jt_db.account表中的所有记录
* 将查询的结果输出到控制台上
*/
// 1.注册数据库
Class.forName("com.mysql.jdbc.Driver");
// 2.获取数据库连接
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/jt_db",
"root", "root");
// 3.获取传输器
Statement stat = conn.createStatement();
// 4.发送SQL语句到数据库执行,并返回执行结果
String sql="select * from account";
ResultSet r = stat.executeQuery(sql);
// 5.处理结果
// r.next();判断是否指向记录,最开始指向表头的,用一次指向下一行记录,有记录返回true
while (r.next()) {//进去循环,指向第一行数据,获取数据
int id=r.getInt("id");
String name=r.getString("name");
double money=r.getDouble("money");
System.out.println(id+", "+name+", "+money);
}
// 6.释放资源
r.close();
stat.close();
conn.close();
}
}

JDBC快速入门细节

1.注册数据驱动

//注册数据库驱动
Class.forName("com.mysql.jdbc.Driver");

上面这行代码是根据传入的类的全路径(包名+类名)加载一个类到内存中。

在Driver类中有一个静态代码块,静态代码块中包含着注册驱动的代码。

因此上面这行代码本身其实并不能注册驱动,但是可以让注册驱动的代码执行!

2.获取数据库连接

//获取数据库连接块
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/jt_db",
"root", "root");

后面传入的两个参数分别是连接数据库的用户名和密码,这里不再过多描述

第一个参数是连接数据库的url地址(描述连接的是哪一个位置的哪一个库)。其中URL地址的结构如下:

jdbc:mysql://localhost:3306/jt_db

————  —————— -----------

协议名     主机名+端口    数据库的名字

其结构类似于平时访问的网址:

http://www.baidu.com:80/index.html?user=zhangfei

另外在URL后面可以通过问号拼接参数:

jdbc:mysql:///jt_db?characterEncoding=utf-8

characterEncoding=utf-8 可以预防JDBC乱码

(可以避免通过JDBC往数据库插入中文数据时乱码

同时也可以避免通过JDBC从数据库查询数据时出现中文乱码问题)

3.Statement传输器对象

Stat.executeQuery( sql ) – 执行查询类的SQL语句, 执行的结果是一个ResultSet对象, 其中包含了查询的结果

Stat.executeUpdate( sql ) – 执行增删改类型的SQL语句, 执行的结果是一个int值, 表示影响的记录行数。

4.ResultSet结果集对象

ResultSet结果集其中包含了SQL查询后的结果, 该对象上提供了遍历数据的方法和获取数据的方法:

(1)遍历数据行的方法

Rs.next() – 将指向数据行的箭头往下挪动一行, 如果挪动一行后指向了一行记录, 方法将返回true, 否则返回false。

(2)获取数据的方法

Rs.getInt( colName )

Rs.getString( colName )

Rs.getDouble( colName )

Rs.getObject( colName )

...

5.释放资源

Rs.close();

Stat.close();

Conn.close();

释放时遵循一个顺序, 越晚获取的越先关闭!!

JDBC增删改查

1、新增:往account表中插入一条新的记录,name为 "john",money为3000

@Test

    public void add() throws Exception{
/*
* 新增:往account表中插入一条新纪录,name为"join",money为30000
*/
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/jt_db",
"root", "root");
Statement stat = conn.createStatement();
String sql="insert into account values (null,'john',3000)";
int r = stat.executeUpdate(sql);//返回影响的行数
System.out.println("影响的行数:"+r);
stat.close();
conn.close();
}

2修改:修改account表中name为 "john" 的记录,将金额改为1500

@Test
public void update() throws Exception{
/*
* 修改account表中name为 "john" 的记录,将金额改为1500
*/
Connection conn = JDBCUtil.getConn();
Statement stat = conn.createStatement();
String sql="Update account set money =1500 where
name='john' ";
int r = stat.executeUpdate(sql);
System.out.println("影响行数:"+r);
JDBCUtil.close(conn, stat, null);
}

3删除:删除account表中name为 "john" 的记录

@Test
public void delete() throws Exception{
/*
* 删除:删除account表中name为 "john" 的记录
*/
Connection conn = JDBCUtil.getConn();
Statement stat = conn.createStatement();
String sql="delete from account where name='John'";
int r = stat.executeUpdate(sql);
System.out.println("影响行数:"+r);
JDBCUtil.close(conn, stat, null);
}

4、查询:查询account表中id为1的记录

@Test
public void find() throws Exception{
/*
* 查询account表中id为1的记录
*/
Connection conn = JDBCUtil.getConn();
Statement stat = conn.createStatement();
String sql="select * from account where id=1";
ResultSet r = stat.executeQuery(sql);
// while (r.next()) {
// int id=r.getInt("id");
// String name=r.getString("name");
// double money=r.getDouble("money");
// System.out.println(id+","+name+","+money);
// }
if(r.next()){
int id=r.getInt("id");
String name=r.getString("name");
double money=r.getDouble("money");
System.out.println(id+","+name+","+money);
}
JDBCUtil.close(conn, stat, r);
}

上面代码中调用了工具类中注册,连接数据库和释放资源的方法

package com.tedu.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement; /** JDBC工具类 */
public class JDBCUtil {
/**
* 获取数据库连接对象并返回
* @return Connection对象
* @throws Exception
*/
public static Connection getConn() throws Exception{
//1.注册驱动
Class.forName( "com.mysql.jdbc.Driver" );
//2.获取连接
Connection conn = DriverManager.getConnection(
"jdbc:mysql:///jt_db?characterEncoding=utf-8",
"root",
"root");
return conn;
} /**
* 释放JDBC程序中的资源
* @param conn 连接对象
* @param stat 传输器对象
* @param rs 结果集对象
*/
public static void close(Connection conn,
Statement stat, ResultSet rs){
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;
}
}
}
}

模拟用户登录案例

创建LoginUser类,提供mian方法和login方法

public static void main(String[] args) {

    /* 提示用户在控制台输入用户名和密码,并接收用户名和密码

     * 根据用户名和密码查询user表, 如果查询到记录, 则证明

     * 用户名密码正确, 模拟登录, 否则提示用户名密码错误!!*/

    Scanner in = new Scanner( System.in );

    //1.提示用户输入用户名和密码,并接收

    System.out.println("请登录...");

    System.out.println("请输入用户名:");

    String user = in.nextLine();

    System.out.println("请输入密码:");

    String pwd = in.nextLine();

    //2.调用login方法, 传入用户名和密码进行登录操作

    login( user, pwd );

}

/**

 * 根据用户名和密码进行登录

 * @param user 用户名

 * @param pwd 密码

 */

private static void login(String user, String pwd) {

    Connection conn = null;

    Statement stat = null;

    ResultSet rs = null;

    try {

       //1.注册驱动并获取连接

       conn = JdbcUtil.getConn();

       //2.获取传输器并执行sql语句

       stat = conn.createStatement();

       String sql =

              "select * from user where username='"

               +user+"' and password='"+pwd+"'";

       System.out.println( sql );

       rs = stat.executeQuery( sql );

       //3.处理结果

       if( rs.next() ) {//用户名密码正确

           System.out.println("恭喜您登录成功!!");

       }else {

           System.out.println("登录失败! 用户名或密码不正确!!");

       }

    } catch (Exception e) {

       e.printStackTrace();

    }

}

执行时输入:

请登录...
请输入用户名:
张飞'#'
请输入密码: select * from user where username='张飞'#'' and password=''
恭喜您登录成功!!

或输入:

请登录...
请输入用户名:
张飞' or '1=1
请输入密码: select * from user where username='张飞' or '1=1' and password=''
恭喜您登录成功!!

或输入:

请登录...
请输入用户名: 请输入密码:
' or '2=2
select * from user where username='' and password='' or '1=1'
恭喜您登录成功!!

以上在用户名或密码错误的情况下也能登录,就是SQL注入攻击

SQL注入攻击是一种常见的网络攻击方式,其产生的原因是:

由于后台的SQL语句是拼接而来的, 其中的参数是用户提交过来的, 如果用户在提交参数时, 在参数中添加了一些SQL关键字或者特殊符号, 就可能会导致SQL语句语义的改变,从而导致一些意外的操作,比如用户名或密码错误也能登录成功!

解决方案:

(1)通过正则对用户提交的用户名或密码进行检查, 如果其中包含

SQL关键字或者特殊符号, 则提示用户名或密码输入不合法

(2)通过PreparedStatement对象可以防止SQL注入攻击!

防止SQL注入攻击

PreparedStatement对象是如何防止SQL注入攻击的?

先将SQL语句的骨架(包含问号占位符)发送给服务器, 让服务器编译并确定下来。

再将SQL语句中的参数发送给服务器,由于前面服务器已经确定了SQL语句(一旦确定就不能被改变),因此参数中即使再包含SQL关键字或者特殊符号,也不会影响SQL语句的语义,只会被当做普通的文本来对待!

/**

 * 根据用户名和密码进行登录

 * @param user 用户名

 * @param pwd 密码

 */

private static void login(String user, String pwd) {

    Connection conn = null;

    PreparedStatement stat = null;

    ResultSet rs = null;

    try {

       //1.注册驱动并获取连接

       conn = JdbcUtil.getConn();

       //2.获取传输器并执行sql语句

       String sql = "select * from user where"

              + " username=? and password=?";

       stat = conn.prepareStatement( sql );

       //设置sql参数(如果有?占位符)

       stat.setString( 1 ,  user );

       stat.setString( 2, pwd );

       //执行sql语句

       rs = stat.executeQuery( );//不要再传SQL语句!

       //3.处理结果

       if( rs.next() ) {//用户名密码正确

           System.out.println("恭喜您登录成功!!");

       }else {

           System.out.println("登录失败! 用户名或密码不正确!!");

       }

    } catch (Exception e) {

       e.printStackTrace();

    } finally {

       //4.释放资源

       JdbcUtil.close(conn, stat, rs);

    }

}

Javaweb入门 JDBC第一天的更多相关文章

  1. Javaweb入门 数据库第一天

    数据库概述 本菜鸟使用的数据库软件为Mariadb,以下内容都是以Mariadb数据库软件来写的学习总结. 数据库 所谓的数据库就是用于存储.管理数据的仓库,数据库根据底层存储数据结构的不同可以分为很 ...

  2. JavaWeb入门——Tomcat的目录结构

    JavaWeb入门——Tomcat的目录结构 摘要:本文主要了解了Tomcat的目录结构. 目录结构 打开Tomcat的目录,可以看到如下文件和文件夹: bin目录 该目录下存放的是二进制可执行文件. ...

  3. JavaWeb用Jdbc操作MySql数据库(一)

    一.添加开发包.在JavaWeb中用jdbc操作数据库,使用方法与java一样,但是在处理开发包的问题上有点差别.JavaWeb不能将mysql-connector-java-5.1.7-bin.ja ...

  4. Storm入门之第一章

    Storm入门之第一章 1.名词 spout龙卷,读取原始数据为bolt提供数据 bolt雷电,从spout或者其他的bolt接收数据,并处理数据,处理结果可作为其他bolt的数据源或最终结果 nim ...

  5. Entity Framework 6.0 入门系列 第一篇

    Entity Framework 6.0 入门系列 第一篇 好几年前接触过一些ef感觉不是很好用,废弃.但是 Entity Framework 6.0是经过几个版本优化过的产物,性能和功能不断完善,开 ...

  6. JavaWeb入门——在Linux环境下安装Tomcat服务器

    JavaWeb入门——在Linux环境下安装Tomcat服务器 摘要:本文主要学习了如何在Linux环境下安装Tomcat服务器. 准备工作 检查Java环境变量 检查系统是否配置了Java的环境变量 ...

  7. JavaWeb入门——在Windows环境下安装Tomcat服务器

    JavaWeb入门——在Windows环境下安装Tomcat服务器 摘要:本文主要学习如何在Windows环境中下载并安装Tomcat服务器. 下载 获取安装包 推荐去官网上下载Tomcat: htt ...

  8. JavaWeb入门——背景知识

    JavaWeb入门——背景知识 摘要:本文主要介绍了Web服务器的相关知识. 概念 什么是JavaWeb JavaWeb,是用Java技术来解决相关Web互联网领域的技术的总称.Web包括:Web服务 ...

  9. Elasticsearch7.X 入门学习第一课笔记----基本概念

    原文:Elasticsearch7.X 入门学习第一课笔记----基本概念 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https: ...

随机推荐

  1. Hihocoder #1333 : 平衡树·Splay2

    1333 : 平衡树·Splay2 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:好麻烦啊~ 小Hi:小Ho你在干嘛呢? 小Ho:我在干活啊!前几天老师让我帮忙 ...

  2. Qt读写Json格式配置文件

    头文件Config.h #pragma once #include <QVariantMap> class Config { public: Config(const QString &a ...

  3. 查看Oracle表空间使用情况

    1.查询表空间的总容量 as MB from sys.dba_data_files a group by a.TABLESPACE_NAME 2.查询表空间的空闲容量 select b.TABLESP ...

  4. Raspberry Pi 4B 使用OpenCV访问摄像头picamera模块

    目录 1.OpenCV安装 (1)安装依赖 (2)下载OpenCV源码 (3)安装pip (4)安装Python虚拟机 (5)编译OpenCV (6)验证安装 2.使用OpenCV和Python控制摄 ...

  5. SQL Server Management Studio 清除用户名和密码

    SQL Server Management Studio 2018 delete the file C:\Users\%username%\AppData\Roaming\Microsoft\SQL  ...

  6. navicat连接远程数据库报错'client does not support authentication protocol requested by server consider ...'解决方案

    [1.cmd终端连接远程mysql数据库方法] mysql -uhello -pworld   -h192.168.1.88 -P3306 -Dmysql_oa mysql -u用户名 -p密码 -h ...

  7. tomcat 启动报错org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].xxx

    今天在写完一个非常简单的servlet页面跳转的web项目后,启动tomcat报错org.apache.catalina.LifecycleException: Failed to start com ...

  8. Flutter移动电商实战 --(17)首页_楼层区域的编写

    1.楼层标题组件 该组件非常简单,只接收一个图片地址,然后显示即可: class FloorTitle extends StatelessWidget { final String picture_a ...

  9. DBeaver 客户端中时间显示问题解决

    最近工作使用了一段时间的macOS,换了新的数据库客户端 DBeaver,无意中发现客户端显示时间不正确.时间保存之后显示比实际时间多13个小时整.可以判断是时区没有配置正确.无意中发现是DBeave ...

  10. (六)爬虫之使用selenium

    selenium是使用javascript编写,主要用来进行web应用程序测试,在python爬虫中可以用来进行动态网页爬取,解决爬虫中的javascript渲染(执行js语句).总结记录下,以备后面 ...