当前位置:   article > 正文

JSP的数据库连接_jsp一般通过什么连接数据库?并简述连接过程。

jsp一般通过什么连接数据库?并简述连接过程。

一. 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()
  • 1
  • 2

而且比Statmement还具有赋值操作

setXxx()
  • 1

(4). ResultSet

保存结果集 select * from xxx

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

2. JDBC的DriverManager

管理不同的数据库驱动

3. 各种数据库驱动

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

连接、直接操作数据库

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

(1). Oracle

驱动jar包

ojdbc-x.jar
  • 1

具体驱动类

Oracle.jdbc.OracleDriver
  • 1

连接字符串

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

(2). MySQL

驱动jar包

mysql-connector-java-x.jar
  • 1

具体驱动类

com.mysql.jdbc.Driver
  • 1

连接字符串

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

(3). SQLserver

驱动jar包

sqljdbc-x.jar
  • 1

具体驱动类

com.microsoft.sqlserver.jdbc.SQLServerDriver
  • 1

连接字符串

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

二. 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);
  • 1

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

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

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

Statement stmt = con.createStatement();
  • 1

执行增删改语句:

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

执行查询语句:

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

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

处理增删改的结果集

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

处理查询的结果集
在这里插入图片描述

(5). 关闭连接

stmt.close();
con.close();
  • 1
  • 2

(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();
	}

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79

在这里插入图片描述

(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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132

在这里插入图片描述

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);
    
    • 1
    • 2

    pstmt方式:

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

    需要重复增减100次(批处理)
    String name=“zs”;
    int age = 23;

    stmt方式:

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

    pstmt方式:

    String sql = "insert into student(stuno,stuname) values(?, ?)";
    pstmt = connection.prepareStatement(sql);	//预编译sql
    pstmt.setString(1,name);
    pstmt.setString(2,age);
    for(100){
    	stmt.executeUpdate();	//此时执行不需要编译,只需要执行就行
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    pstmt:防止SQL注入

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

三. 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 path

web项目
3. jar复制到WEB-INF/lib下
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
login.jsp页面


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>通过数据库登录界面</title>
</head>
<body>
	<form action="check.jsp" method="post">
		用户名:<input type="text" name="uname"><br/>
		密码:<input type="password" name="upwd"><br/>
		<input type="submit" value="登录"><br/>
	</form>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
check.jsp页面


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.sql.*"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>检验数据库是否存在登录用户</title>
</head>
<body>
	<%
		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();
			}
		}
	%>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/559158
推荐阅读
相关标签
  

闽ICP备14008679号