JDBC基础操作

JDBC:是Java程序访问数据库的一系列标准接口。Java程序访问数据库不是通过与TCP建立连接,而是通过Java接口建立连接访问数据库的,Java接口通过Java驱动实现与数据库的连接。Java驱动是数据库开发商提供的一套实现Java接口的实现类,要连接某个数据库只需将其Java驱动导入,通过Java接口进行访问数据库。

JDBC连接

JDBC是一套标准接口,位于java.sql包中,这里面都是接口,并不能被实例化,所以就需要引入对这些接口进行实例化的实现类,Java驱动就是对这些接口进行实例化的实现类。Java接口提供访问数据库的统一接口,具体咋样去实现对数据库的连接,就需要根据不同的数据库厂商提供实现类去实现了。

JDBC中提供了与数据库连接的接口:Connection接口,通过DriverManager中的getConnection()传入参数"数据库连接符(包含数据库名,主机地址,端口号数据库,配置参数)",“用户名”,“密码”,返回一个Connection,DriverManager驱动管理类会找到所有的驱动,并根据传入的"数据库连接字符串"找到对应的数据库驱动。

1、建立数据库连接
public static void main(String[] args) {
		//低版本的驱动类,需要手动加载驱动类
		//反射的方式加载驱动类
		//Class.forName("com.myssql.cj.jdbc.Driver");
		
		//驱动管理类
		//(高版本中)DriverManager会自动加载驱动包中“驱动类”:com.myssql.cj.jdbc.Driver
		//并返回驱动包中Connection接口的实现类对象
		
		final String url = "jdbc:mysql://localhost:3306/test_db";//数据库连接字符串
		final String db_user_name = "用户名";//用户名
		final String db_user_pass = "密码";//密码
		
		//创建MySQL数据库连接(需要释放数据库连接)
		try(Connection con = DriverManager.getConnection(url, db_user_name,db_user_pass)){
			//输出
			System.out.println("数据库连接:"+con);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
2、JDBC查询
创建Statement对象,执行数据库操作

通过Connection提供的createStatement()创建Statement对象,用于执行数据库操作。

再通过Statement对象中executeQuery()并给其传入sql语句,获取ResultSet结果集。

再通过调用next()获取数据库表中得每一行数据。

最后,按照字段编号或字段名称读取字段值。

public static void main(String[] args) {
	final String db_url = "jdbc:mysql://localhost:3306/test_db";//数据库连接字符串
	final String db_user_name = "用户名"; 
	final String db_user_pass = "密码"; 
	//1.创建JDBC连接
	try(Connection con = DriverManager.getConnection(db_url, db_user_name,db_user_pass)){
		//2.创建Statement对象,执行数据库操作
		try(Statement st = con.createStatement();){
			//3.执行查询,并获取ResultSet结果集
			try(ResultSet rs = st.executeQuery("select * from website");){
				//4.遍历结果集
				while(rs.next()) {
					//方式1
					//读取当前行的每个字段值
					//按照字段编号读取:从1开始
					int id = rs.getInt(1);
    				String name = rs.getString(2);
					
					//方式2
					//按照字段名称读取
					int id = rs.getInt("id");
					String name = rs.getString("name");
					String url = rs.getString("url");
					
					//输出
					System.out.println("编号:"+id);
					System.out.println("网站名称:"+name);
					System.out.println("网站地址:"+url);
					System.out.println();
				}
			}
		}
	} catch (SQLException e) {
		e.printStackTrace();
		}
	}
SQL注入

创建Statement对象执行数据库查询时,sql语句是拼接出来的,这样就很容易使有些别有用心的用户编造一个特殊的字符串(用户名或密码)拼接到sql语句中,拼接出一个正确的sql语句。此时就会引发SQL注入问题。

public static void main(String[] args) {
		final String db_url = "jdbc:mysql://localhost:3306/test_db";//数据库连接字符串
		final String db_user_name = "用户名"; 
		final String db_user_pass = "密码"; 
		//1.创建JDBC连接
		try(Connection con = DriverManager.getConnection(db_url, db_user_name,db_user_pass)){
			//2.创建Statement对象,执行数据库操作
			try(Statement st = con.createStatement();){
				
				String phoneName = "12387346789";
                //特殊的字符串
				String loginPassword = "'or 1=1 or'";
				
				//拼接sql语句
				StringBuilder sql = new StringBuilder();
				sql.append("select * from user_info where phone_number = '");
				sql.append(phoneName);
				sql.append("' and login_password = '");
				sql.append(loginPassword);
				sql.append("'");
				System.out.println("完整的SQL语句:"+sql);
				//3.执行查询,并获取ResultSet结果集
				try(ResultSet rs = st.executeQuery(sql.toString());){
					//4.处理查询结果集
					String realName = "";
					if(rs.next()) {
						realName = rs.getString("user_real_name");
					}else {
						realName = "登录失败!";
					}
					System.out.println(realName);
				}
			}
		} catch (SQLException e) {
			e.printStackTrace();
			}
	}
PreparedStatement对象

要想解决SQL注入的问题,可以使用PreparedStatement

使用PreparedStatement对象,执行数据库操作时,是将完整的sql语句传给PreparedStatement对象的,要传入的数据使用?作为占位符,这样就可以保证每次传给数据库都是完整的sql语句,只是占位符处的数据不一样,还能提高SQL预编译的执行效率。

public static void main(String[] args) {
		final String db_url = "jdbc:mysql://localhost:3306/test_db";//数据库连接字符串
		final String db_user_name = "用户名"; 
		final String db_user_pass = "密码"; 
		//1.创建JDBC连接
		try(Connection con = DriverManager.getConnection(db_url, db_user_name,db_user_pass)){
			//2.创建PreparedStatement对象,执行数据库操作
			//作用1:避免SQL注入
			//作用2:SQL预编译提高执行效率
			String sql = "select * from user_info where phone_number = ? and login_password = ?";
			try(PreparedStatement pst = con.prepareStatement(sql);){
				
				//3.处理问号占位符
				String phoneName = "12387346789";
				String loginPassword = "abc";
				//设置?处的数据
                //数据类型与数据库一致
				pst.setString(1, phoneName);
				pst.setString(2, loginPassword);
				
				System.out.println("完整的SQL语句:"+sql);
				//4.执行查询,并获取ResultSet结果集
				try(ResultSet rs = pst.executeQuery()){
					//5.处理查询结果集
					String realName = "";
					if(rs.next()) {
						realName = rs.getString("user_real_name");
					}else {
						realName = "登录失败!";
					}
					System.out.println(realName);
				}
			}
		} catch (SQLException e) {
			e.printStackTrace();
			}
	}
3、向数据库插入数据

将"插入"sql语句传给PreparedStatement对象,再处理占位符,最后调用executeUpdate()返回影响行数。

执行查询sql语句用executeQuery(),执行增加(删除、修改)sql语句用executeUpdate()。
public static void main(String[] args) {
		final String db_url = "jdbc:mysql://localhost:3306/test_db";//数据库连接字符串
		final String db_user_name = "root"; 
		final String db_user_pass = "123456"; 
		//1.连接
		try(Connection con = DriverManager.getConnection(db_url,db_user_name,db_user_pass);){
			//2.数据库操作(SQL语句)
			String sql = "insert into user_info(user_real_name,phone_number,login_password,last_login_time) values(?,?,?,now())";
			
			try(PreparedStatement pst = con.prepareStatement(sql)){
				//处理问号占位符
				pst.setString(1, "刘三");
				pst.setString(2, "12356897854");
				pst.setString(3, "abc123");
				//3.执行(返回影响行数)
				int row = pst.executeUpdate();
				//插入一条数据,所以返回的行数为1
				if(row == 1) {
					System.out.println("添加成功!");
				}else {
					System.out.println("添加失败!");
				}
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
4、向数据库插入数据并获取自增主键值

将prepareStatement()方法中的参数"autoGeneratedKeys"设置为"Statement.RETURN_GENERATED_KEYS",再调用PreparedStatement对象中的getGeneratedKeys()获取自增主键值。

public static void main(String[] args) {
		final String db_url = "jdbc:mysql://localhost:3306/test_db";//数据库连接字符串
		final String db_user_name = "用户名"; 
		final String db_user_pass = "密码"; 
		//1.连接数据库
		try(Connection con = DriverManager.getConnection(db_url,db_user_name,db_user_pass);){
			//2.数据库操作(SQL)
			String sql = "insert into user_info(user_real_name,phone_number,login_password,last_login_time) values(?,?,?,now())";
			//设置PreparedStatement允许返回自动生成的主键值
			try(PreparedStatement pst = con.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS)){
				//3.执行
				//处理问号占位符
				pst.setString(1, "光头强");
				pst.setString(2, "18169873256");
				pst.setString(3, "123456abc");
				int row = pst.executeUpdate();
				//如果添加成功,获取自增主键值
				if(row == 1) {
					//查询自动生成的主键值
					try(ResultSet rs = pst.getGeneratedKeys()){
						//指向新添加的那一行,并获取值
						if(rs.next()) {
							int id = rs.getInt(1);
							System.out.println("添加成功!");
							System.out.println("新用户的主键值为:"+id);
						}
					}
				}else {
					System.out.println("添加失败!");
				}
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
5、修改、删除

修改(删除)操作与添加操作差不多的执行过程,只是sql语句不一样,PreparedStatement 对象调用executeUpdate()执行sql语句,并返回影响的行数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值