JDBC操作数据库

package com.lxz;

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

public class StringAndDate2 {
	// 创建一个以JDBC连接数据库的方法
	public ResultSet getResultSet(String sql) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		String url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8";
		String user = "root";
		String password = "123456";
		try {
			// 1.加载驱动类
			Class.forName("com.mysql.jdbc.Driver");
			// 或 new com.mysql.jdbc.Driver();
			// 2.创建连接
			conn = DriverManager.getConnection(url, user, password);
			// 3.创建PreparedStatement对象
			// 要执行sql语句,必须获得java.sql.Statement实例,Statement实例分为以下三种
			// (1)执行静态sql语句。通常通过Statement实例实现
			// Statement stmt = conn.createStatement();
			// (2)执行动态sql语句。通常通过PreparedStatement实例实现
			// PreparedStatement ps = conn.prepareStatement(sql);
			// (3)执行数据库存储过程。通常通过CallableStatement实例实现
			// CallableStatement cs = conn.prepareCall("{CALL demoSp(?,?)}");
			ps = conn.prepareStatement(sql);
			// 4.执行sql语句
			// Statement接口提供了三种执行sql语句的方法,executeQuery,executeUpdate,execute
			// (1) ResultSet executeQuery(String sqlString):执行查询数据库的SQL语句,返回一个
			// ResultSet对象
			// ResultSet rs = ps.executeQuery("SELECT * FROM ...");
			// (2) int executeUpdate(String
			// sqlString):用于执行INSERT/UPDATE/DELETE语句以及
			// sql DDL语句,如: CREATE TABLE和DROP TABLE等
			// int rows = ps.executeUpdate("INSERT INTO ...");
			// (3) execute(sqlString):用于执行返回多个结果集、多个更新或二者组合的语句
			// boolean flag = ps.execute(String sql);
			rs = ps.executeQuery();
			// 5.处理结果
			// (1) 执行更新等操作返回的是本次操作影响到的记录数
			// (2) 执行查询返回的结果是一个ResultSet对象
			// ResultSet包含sql语句中条件的所有行,通过get进行访问
			// while(rs.next()){
			// String name = rs.getString("name");
			// String pwd = rs.getString(1); //比较高效,从左右到编号,从1开始
			// }
		} catch (ClassNotFoundException e) {
			System.out.println("找不到驱动类");
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			// 5.关闭jdbc对象
			if (rs != null) {
				try {
					rs.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			if (ps != null) {
				try {
					ps.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			if (conn != null) {
				try {
					conn.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
		return rs;
	}

	// PreparedStatement与Statement的区别?
	// 1.代码的可读性和可维护性
	// stmt.executeUpdate("insert into tb_test(col1,col2,col3) values('"+var1+"','"+var2+"','"+var3+"')");
	// PreparedStatement
	// ps = conn.prepareStatement("insert into tb_test(col1,col2,col3) values(?,?,?)");
	// ps.setString(1,var1);
	// ps.setString(2,var2);
	// ps.setString(3,var3);
	// 2.PreparedStatement尽最大提高性能
	/*每一种数据库都会尽最大努力对预编译语句提供最大的性能优化,因为预编译语句有可能重复调用,所以语句在被数据库
	的编译器编译后,执行代码会被缓存下来,那么下次调用时只要是相同的预编译语句就不需要再编译,只要将参数直接传入编译过的
	语句执行代码中(相当于一个函数)就会得到执行,这并不是说只有一个Connection中多次执行的预编译语句被缓存,而是对整个
	数据库,只要预编译的语句语法和缓存在匹配,那么在任何时候就可以不需要再次编译而可以直接执行。而statement
	的语句中,即使是相同的同一操作,而由于每次操作的数据不同,所以使整个语句相匹配的机会极小,几乎不太可能匹配,比如:
	insert into tb_test(col1,col2) values('11','22');
	insert into tb_test(col1,col2) values('11','23');
	即使是相同操作但因为数据内容不一样,所以整个个语句本身不能匹配,没有缓存语句的意义.事实是没有数据库会对普通语句
	编译后的执行代码缓存.这样每执行一次都要对传入的语句编译一次.
	当然并不是所以预编译语句都一定会被缓存,数据库本身会用一种策略,比如使用频度等因素来决定什么时候
	不再缓存已有的预编译结果.以保存有更多的空间存储新的预编译语句.*/
	// 3.提高安全性
	// String sql = "select * from tb_test where username='"+username+"' and password='"+password+"'";
	// 如果把(' or '1'='1)传入,则会查到所有信息
	// 甚至把(';drop table tb_test where '1'='1)传入,而恰恰有些数据库中这样就会执行
	// 如果使用预编译语句,则传入的任何内容就不会和原来的语句发生任何匹配的关系.(前提是数据库本身支持预编译)
	// 另:执行效率:Statement 采取直接编译 SQL 语句的方式,扔给数据库去执行,而 PreparedStatement 则先将 SQL语句预编译一遍,再填充参数,这样效率会高一些。
	// JDK文档说:SQL 语句被预编译并且存储在 PreparedStatement 对象中,其后可以使用该对象高效地多次执行该语句。
	// Statement 由于可能需要采取字符串与变量的拼接,很容易进行 SQL注入攻击,而 PreparedStatement 由于是预 
	// 编译,再填充参数的,不存在 SQL 注入问题。 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值