博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JSP的数据库连接
阅读量:3957 次
发布时间:2019-05-24

本文共 10193 字,大约阅读时间需要 33 分钟。

文章目录

一. JDBC概述

JDBC:Java DataBase Connectivity

可以为多种关系型数据库DBMS提供统一的访问方式,目的就是使用Java来操作数据库

在这里插入图片描述

1. JDBC的API

提供了各种操作、访问接口,

类或接口的名字有:

  • Connection
  • Statmement
  • PreparedStatement
  • ResultSet

(1). Connection产生操作数据库的对象

Connection产生Statement对象:createStatement()

Connection产生PreparedStatement对象:prepareStatement()

Connection产生CallableStatement对象:prepareCall()

(2). Statmement操作数据库

增删改:executeUpdate()

查询:executeQuery()

(3). PreparedStatmement操作数据库

public interface PreparedStatement extends Statement

因此具有Statmement的方法

增删改:executeUpdate()查询:executeQuery()

而且比Statmement还具有赋值操作

setXxx()

(4). ResultSet

保存结果集 select * from xxx

next():光标下移,判断是否有下一条数据:true/false

previous():光标上移,判断是否有下一条数据:true/false
getXxx(字段名|位置):获取具体的字段值

2. JDBC的DriverManager

管理不同的数据库驱动

3. 各种数据库驱动

相应的数据库厂商提供的(第三方提供)

连接、直接操作数据库

使用jdbc操作数据库时,如果对数据库进行了更换,只需要替换:驱动、具体驱动类、连接字符串、用户名、密码

(1). Oracle

驱动jar包

ojdbc-x.jar

具体驱动类

Oracle.jdbc.OracleDriver

连接字符串

jdbc:oracle:thin:@localhost:1521:ORCL

(2). MySQL

驱动jar包

mysql-connector-java-x.jar

具体驱动类

com.mysql.jdbc.Driver

连接字符串

jdbc:mysql://localhost:3306/数据库实例名

(3). SQLserver

驱动jar包

sqljdbc-x.jar

具体驱动类

com.microsoft.sqlserver.jdbc.SQLServerDriver

连接字符串

jdbc:microsoft:sqlserver:localhost:1433;databaseename=数据库实例名

二. JDBC API

1. 主要功能

在这里插入图片描述

2. 具体通过以下类/接口实现

  • DriverManager:管理JDBC驱动
  • Connection:连接数据库(通过DriverManager产生)
  • Statement (子类:PreparedStatement):增删改查(通过Connection产生)
  • CallableStatement:调用数据库中的存储过程/存储函数(通过Connection产生)
  • Result:返回的结果集(上面的Statement等产生)

从上之下,依次产生

3. JDBC访问数据库的具体步骤

(1). 导入驱动,加载具体的驱动类

导入驱动

在这里插入图片描述
加载具体的驱动类
在这里插入图片描述

(2). 与数据库建立连接

通过DriverManager来建立连接

Connection con = DriverManager.getConnection(URL, username, password);

返回值就是与数据库的连接对象

(3). 发送SQL,执行语句(增删改、查询)

执行增删改查需要通过:Statement (或子类:PreparedStatement)

Statement stmt = con.createStatement();

执行增删改语句:

String sql1 = "insert into tb_admins values('张三', '123')";int count = stmt.executeUpdate(sql);//返回值表示增删改几条数据

执行查询语句:

String sql2 = "select fd_username, fd_password from userdb";

(4). 处理结果集(查询)

处理增删改的结果集

if(count>0) {			System.out.println("操作成功!");		}

处理查询的结果集

在这里插入图片描述

(5). 关闭连接

stmt.close();con.close();

(6). 举例理解jdbc增删改查

import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;public class JDBCDemo {
private final static String URL = "jdbc:mysql://localhost:3306/userdb?serverTimezone=GMT%2B8"; private final static String username = "root"; private final static String password = "root"; public static void update() throws ClassNotFoundException, SQLException {
//增删改// 1. 导入驱动,加载具体的驱动类 Class.forName("com.mysql.cj.jdbc.Driver"); //加载具体的驱动类// 2. 与数据库建立连接(通过DriverManager) Connection con = DriverManager.getConnection(URL, username, password);// 3. 发送sql,执行命令(增删改) Statement stmt = con.createStatement(); String sql1 = "insert into tb_admins values('王五', '1234')";// String sql1 = "update tb_admins set fd_password='12345' where fd_username='王五'"// String sql2 = "select fd_username, fd_password from userdb"; // 4. 执行SQL语句 int count = stmt.executeUpdate(sql1); //返回值表示增删改几条数据 // 5. 处理结果 if(count>0) {
System.out.println("操作成功!"); } // 6. 关闭连接 stmt.close();//对象.方法 con.close(); } public static void query() throws ClassNotFoundException, SQLException {
//查询// 1. 导入驱动,加载具体的驱动类 Class.forName("com.mysql.cj.jdbc.Driver"); //加载具体的驱动类// 2. 与数据库建立连接(通过DriverManager) Connection con = DriverManager.getConnection(URL, username, password);// 3. 发送sql,执行命令(查询) Statement stmt = con.createStatement(); String sql2 = "select fd_username, fd_password from tb_admins"; // 4. 执行SQL语句 ResultSet rs = stmt.executeQuery(sql2); //返回值表示查询的结果集 // 5. 处理结果 while(rs.next()) {
int pwd = rs.getInt("fd_password"); String name = rs.getString("fd_username"); // int pwd = rs.getInt(2); 这样的方式也可以,但是不推荐,要对应类型,下标:并且从1开始// String name = rs.getString(1); System.out.println(name+"--"+pwd); } // 6. 关闭连接 //先开的后关,后开的先关 rs.close(); stmt.close();//对象.方法 con.close(); } public static void main(String[] args) throws ClassNotFoundException, SQLException {
// update(); query(); }}

在这里插入图片描述

(7). 举例理解通过PreparedStatement操作数据库

import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;public class JDBCPreparedStatementDemo {
private final static String URL = "jdbc:mysql://localhost:3306/userdb?serverTimezone=GMT%2B8"; private final static String username = "root"; private final static String password = "root"; public static void update(){
//增删改 Connection con = null; PreparedStatement pstmt = null; try {
// 1. 导入驱动,加载具体的驱动类 Class.forName("com.mysql.cj.jdbc.Driver"); //加载具体的驱动类 // 2. 与数据库建立连接(通过DriverManager) con = DriverManager.getConnection(URL, username, password); // 3. 发送sql,执行命令(增删改) /* stmt = con.createStatement(); // String sql1 = "update tb_admins set fd_password='12345' where fd_username='王五'" // String sql2 = "select fd_username, fd_password from userdb"; // 4. 执行SQL语句 int count = stmt.executeUpdate(sql1); //返回值表示增删改几条数据 */ //prepareStatement// String sql = "insert into tb_admins values('阿飞', '12345')"; String sql = "insert into tb_admins values(?, ?)";//通过?来充当占位符 pstmt = con.prepareStatement(sql);//预编译 pstmt.setString(1, "老林");//对占位符进行替换 pstmt.setInt(2, 6666); int count = pstmt.executeUpdate(); // 5. 处理结果 if(count>0) {
System.out.println("操作成功!"); } } catch(Exception e) {
e.printStackTrace(); } finally {
try {
// 6. 关闭连接 if(pstmt!=null) pstmt.close(); if(con!=null) con.close(); }catch(SQLException e) {
e.printStackTrace(); } } } public static void query(){
//查询 Connection con = null; PreparedStatement pstmt = null; ResultSet rs = null; try {
// 1. 导入驱动,加载具体的驱动类 Class.forName("com.mysql.cj.jdbc.Driver"); //加载具体的驱动类 // 2. 与数据库建立连接(通过DriverManager) con = DriverManager.getConnection(URL, username, password); // 3. 发送sql,执行命令(查询)// String sql2 = "select fd_username, fd_password from tb_admins"; String sql2 = "select * from tb_admins where fd_username=?"; pstmt = con.prepareStatement(sql2); pstmt.setString(1, "张三"); // 4. 执行SQL语句 rs = pstmt.executeQuery(); //返回值表示查询的结果集 // 5. 处理结果 while(rs.next()) {
int pwd = rs.getInt("fd_password"); String name = rs.getString("fd_username"); // int pwd = rs.getInt(2); 这样的方式也可以,但是不推荐,要对应类型,下标:并且从1开始 // String name = rs.getString(1); System.out.println(name+"--"+pwd); } } catch(Exception e) {
e.printStackTrace(); } finally {
try {
// 6. 关闭连接 if(rs!=null) rs.close(); if(pstmt!=null) pstmt.close(); if(con!=null) con.close(); }catch(SQLException e) {
e.printStackTrace(); } } } public static void main(String[] args) throws ClassNotFoundException, SQLException {
// update(); query(); }}

在这里插入图片描述

1. PreparedStatement与Statement在使用时的区别

  1. Statement

    sql

    executeUpdate(sql)

  2. PreparedStatement

    sql(可能存在占位符?)

    在创建PreparedStatement对象时,将sql预编译prepareStatement(sql)
    执行executeUpdate()
    setXxx()替换占位符?

2. 推荐使用PreparedStatement

原因如下:

  1. 编码更加简便,避免了字符串的拼接

    String name=“zs”;

    int age = 23;

    stmt方式:

    String sql = "insert into student(stuno,stuname) values(' "+name+" ', "+age+")"; stmt.executeUpdate(sql);

    pstmt方式:

    String sql = "insert into student(stuno,stuname) values(?, ?)"; pstmt = connection.prepareStatement(sql);	//预编译sql pstmt.setString(1,name); pstmt.setString(2,age);
  2. 提高性能(因为有预编译操作,预编译只需要执行一次)

    需要重复增减100次(批处理)

    String name=“zs”;
    int age = 23;

    stmt方式:

    String sql = "insert into student(stuno,stuname) values(' "+name+" ', "+age+")";for(100){
    stmt.executeUpdate(sql);}

    pstmt方式:

    String sql = "insert into student(stuno,stuname) values(?, ?)";pstmt = connection.prepareStatement(sql);	//预编译sqlpstmt.setString(1,name);pstmt.setString(2,age);for(100){
    stmt.executeUpdate(); //此时执行不需要编译,只需要执行就行}
  3. 安全(有效的防止SQL注入)

    sql注入:将客户输入的内容和开发人员的sql语句混为一体

    stmt:存在SQL注入的风险

    例如输入: 	用户名:任意值 ' or 1=1 -- 	密码:任意值  分析: 	select count(*) from login where uname =' "+name+" ' and upwd = ' "+pwd+" '; 	 	等价于:select count(*) from login where uname =' 任意值 ' or 1=1 -- ' and upwd = ' "+pwd+" '; 	 	等价于:select count(*) from login where uname =' 任意值 ' or 1=1 -- '; 	等价于:select count(*) from login;

    pstmt:防止SQL注入

    select count(*) from login where uname =?and upwd =?;

三. JDBC总结(模板、八股文)

1. 模板总结

在这里插入图片描述

jdbc中,除了Class.forName()抛出ClassNotFoundException,其余方法全部抛出SQLException

2. CallableStatement

调用存储过程、存储函数

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

3. 处理CLOB[Text]/BLOB类型

在这里插入图片描述

在这里插入图片描述

四. JSP访问数据库

JSP就是在html里面嵌套的java代码,因此,java代码可以写在jsp中(<%… %>)

导包操作:

java项目:1. jar复制到工程中2. 右键该jar:build path ——>add to build pathweb项目3. jar复制到WEB-INF/lib下
login.jsp页面<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>
通过数据库登录界面
用户名:
密码:
check.jsp页面<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><%@ page import="java.sql.*"%>
检验数据库是否存在登录用户 <% String URL = "jdbc:mysql://localhost:3306/userdb?serverTimezone=GMT%2B8"; String username = "root"; String password = "root"; Connection con = null; Statement stmt = null; ResultSet rs = null; try {
// 1. 导入驱动,加载具体的驱动类 Class.forName("com.mysql.cj.jdbc.Driver"); //加载具体的驱动类 // 2. 与数据库建立连接(通过DriverManager) con = DriverManager.getConnection(URL, username, password); // 3. 发送sql,执行命令(查询) stmt = con.createStatement(); String name = request.getParameter("uname"); String pwd = request.getParameter("upwd"); String sql = "select count(*) from tb_admins where fd_username='"+name+"' and fd_password='"+pwd+"'"; //有这个人返回值就是1,没有返回值就是0 // 4. 执行SQL语句 rs = stmt.executeQuery(sql); //返回值表示查询的结果集 // 5. 处理结果 int count = -1; if(rs.next()) //表示结果集的第一行 {
count = rs.getInt(1);//返回值就1个,所以只需要拿第一个就行 } if(count>0){
out.println("登录成功"); } else{
out.println("登录失败"); } } catch(Exception e) {
e.printStackTrace(); } finally {
try {
// 6. 关闭连接 if(rs!=null) rs.close(); if(stmt!=null) stmt.close(); if(con!=null) con.close(); }catch(SQLException e) {
e.printStackTrace(); } } %>

转载地址:http://nqxzi.baihongyu.com/

你可能感兴趣的文章
图片的三级缓存机制
查看>>
自定义标签库(Tag library)
查看>>
自定义标签库(Tag library)
查看>>
深入Java集合学习系列(一)
查看>>
深入Java集合学习系列(一)
查看>>
深入Java集合学习系列(二):
查看>>
图解Spring AOP
查看>>
性能调优之Weblogic调优
查看>>
性能调优之性能参数指标
查看>>
POJ3009---冰壶游戏(深搜剪枝+回溯)
查看>>
POJ3669---跳炸弹(广搜)
查看>>
POJ---1384Piggy-Bank (完全背包+装满问题)
查看>>
并查集基础知识
查看>>
POJ1182---食物链(带权并查集~技巧性超强的解法)
查看>>
POJ2492---A Bug's Life(做完食物链,再秒这个)
查看>>
POJ2063---Investment(完全背包)
查看>>
POJ1458---(最长公共子序列最基础题)
查看>>
POJ3356---(最长公共子序列)
查看>>
二叉树基础知识大全(核心理解遍历)
查看>>
03-树1 树的同构(25 分) 2017秋 数据结构 陈越、何钦铭
查看>>