软工实习(三)jdbc基础

引入
  • jdbc是一种用于执行SQL语句的java api(工具). jdbc是java访问数据库标准规范
  • MVC架构:servlet(controller) service(view) dao(model),就是按照不同类的作用来分层,一种作用的类一个层
  • 驱动:两个设备进行交互
    因为jdbc是最基本的标准规范,所以各数据库厂商必须要适应jdbc的格式,而每个数据库厂商都有自己的规范,于是就有了驱动包,驱动包的作用就是让这个数据库能按照jdbc的标准与java交互
  • 驱动包导入位置: WEB-INF/lib目录中
JDBC与数据库连接过程

首先看Navicat和数据库连接步骤:
在这里插入图片描述
类似地,jdbc也有相应过程
在这里插入图片描述注册驱动就是一个反射创建的一个对象,相当于选择数据库

为什么要关闭资源:mysql简单来说就是一个文件系统,文件系统就在磁盘当中,想要从磁盘存取数据就要通过io流,使用io流结束时就必须将其关闭

简单查询例子
package demo;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class JdbcDemo {
	public static void main(String[] args) throws Exception {
		//注册驱动:选择数据库,选的是mysql还是其它数据库
		Class.forName("com.mysql.jdbc.Driver");//反射当前创建对象全路径(包名+类名)
		//获取连接 url:协议://ip:端口/资源位置(数据库名称)     返回一个连接对象
		Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/22_1_6", "root", "root");
		//编写sql,并获取发送sql语句的对象
		String sql = "select * from user";
		Statement st = conn.createStatement();//可以把sql语句发给这个对象,这样数据库就能接收到请求,从而返回结果
		//发送sql,并接收返回结果
		ResultSet rs = st.executeQuery(sql);//执行查询操作,并将返回结果存入rs,返回的是一个表
		//处理结果
		while (rs.next()) {
			//每次循环获取的一行数据
			Integer uid = rs.getInt("uid");
			String username = rs.getString("username");
			String password = rs.getString("password");//这里括号里写的一定是列名
			System.out.println("uid:" + uid + ",username:" + username + ",password:" + password);
		}
		//关闭资源,关闭和mysql有交互的资源
		rs.close();
		st.close();
		conn.close();
	}
}

在这里插入图片描述

增加(插入)
Class.forName("com.mysql.jdbc.Driver");
		Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/22_1_6", "root", "root");
		//增加一条用户信息
		String sql = "insert into user (uid,username,password) values(null, 'mahuateng','1111')";
		Statement st = conn.createStatement();
		int i = st.executeUpdate(sql);
		System.out.println("更新行数为:" + i);
		st.close();
		conn.close();
修改
Class.forName("com.mysql.jdbc.Driver");
		Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/22_1_6", "root", "root");
		//通过uid=1修改username=mayun
		String sql = "update user set username='mayun' where uid=1";
		Statement st = conn.createStatement();
		st.executeUpdate(sql);
		int i = st.executeUpdate(sql);
		System.out.println("更新行数为:" + i);
		st.close();
		conn.close();
删除
Class.forName("com.mysql.jdbc.Driver");
		Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/22_1_6", "root", "root");
		//删除一条用户信息
		String sql = "delete from user where uid=1";//可以在写sql语句之前先放到Navicat里执行一遍
		Statement st = conn.createStatement();
		st.executeUpdate(sql);
		int i = st.executeUpdate(sql);
		System.out.println("更新行数为:" + i);
		st.close();
		conn.close();
代码抽取

注册驱动时加载时机最早,且只需加载一次,符合静态代码块的特点,所以可以把它放到静态代码块里面去
static{ 代码内容...}
获取连接时,需要定义一个带有返回值的方法,返回值Connection
public static Connection getConn(){ return DriverManager.getConnection("地址", "用户名", "密码"); }
关闭资源时,定义一个带参数的方法,ResultSet Statement Connection
如果Resultset不为空,执行关闭.close();
如果Resultset为空,则会出现空指针的错误

package util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Utils {
	
	private static final String DRIVER = "com.mysql.jdbc.Driver";
	private static final String MYSQL_URL = "jdbc:mysql://127.0.0.1:3306/22_1_6";
	private static final String MYSQL_NAME = "root";
	private static final String MYSQL_PASSWORD = "root";
	
	//注册驱动
	static {
		try {
			Class.forName(DRIVER);
		} catch (ClassNotFoundException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
	}
	//获取连接
	public static Connection getConn() {
		Connection conn = null;
		try {
			conn = DriverManager.getConnection(MYSQL_URL, MYSQL_NAME, MYSQL_PASSWORD);
		} catch (SQLException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		return conn;
	}
	//关闭资源
	public static void closeAll(ResultSet rs, Statement st, Connection conn) {
		if(rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
		if (st != null) {
			try {
				st.close();
			} catch (SQLException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
	}

}

进行抽取后的查询代码

package demo;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import util.Utils;


public class JDBCUtilDemo {
	
	public static void main(String[] args) throws SQLException {
		//查询
		Connection conn = Utils.getConn();
		String sql = "select * from user";
		Statement st = conn.createStatement();
		ResultSet rs = st.executeQuery(sql);
		while (rs.next()) {
			Integer uid = rs.getInt("uid");
			String username = rs.getString("username");
			String password = rs.getString("password");
			System.out.println("uid:" + uid + ",username:" + username + ",password:" + password);
		}
		Utils.closeAll(rs, st, conn);
		
	}
}

在这里插入图片描述
修改数据

//修改
		Connection conn = Utils.getConn();
		String sql = "update user set username='111' where uid = 2";
		Statement st = conn.createStatement();
		ResultSet rs = st.executeQuery(sql);
		int i = st.executeUpdate(sql);
		System.out.println(i);
		Utils.closeAll(rs, st, conn);
预处理

使用预处理的原因:安全性较高,没有sql注入攻击的隐患
预处理原理:相当于给密码整体加了一个双引号

private static void after() throws SQLException {
		// 模拟用户输入用户名 密码 执行登录操作
		// 拿着用户名和密码去数据库中查询, 如果有 登录成功 如果没有 登录失败
		//  模拟用户输入 Scanner
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入用户名");
		String username = sc.nextLine();
		System.out.println("请输入密码");
		String password = sc.nextLine();
		
		Connection conn = Utils.getConn();
		String sql = "select * from user where username=? and password=?";
		// 获取预处理对象
		PreparedStatement st = conn.prepareStatement(sql);
		// 给占位符赋值, 赋值通过下标  下标从1开始
		// 第一个参数代表下标 从1开始, 第二个参数代表当前占位符的值
		st.setString(1, username);
		st.setString(2, password);
		
		ResultSet rs = st.executeQuery();
		if(rs.next()) {
			System.out.println("登录成功");
		}else {
			System.out.println("用户名或密码错误");
		}
		
		Utils.closeAll(rs, st, conn);
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值