黑马程序员--利用JDBC访问数据库

------- android培训java培训、期待与您交流! ---------


利用JDBC访问数据库

前面我们讲了如何利用JDBC连接数据库,那么连接数据库之后我们能干些什么事呢?

我们连接数据库的目的就是:

1.把用户的数据保存在数据库里面,这是更新操作(包括数据库的更新,插入,删除).例如修改密码,注册账号.

2.把数据库的数据提取出来,这就是查询操作,例如查询火车票的信息.


访问数据库: 数据库连接被用于向数据库服务器发送命令和 SQL 语句,在连接建立后,需要对数据库进行访问,执行 sql 语句

Statement:调用 Connection对象的 createStatement方法创建该对象,该对象用于执行静态的 SQL语句,并且返回执行结果

Statement 接口中用于执行 SQL语句的方法:

ResultSet excuteQuery(Stringsql)

int excuteUpdate(String sql)


一个简单的利用statement对象访问数据库的例子:

<span style="font-size:14px;">import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class TestStatement {

	public void testUpdate(String sql) {
		// 创建Connection和Statement对象
		System.out.println(sql);
		Connection conn = null;
		Statement statement = null;

		try {// 利用静态方法获取链接
			conn = TestJDBC1.getConnection();
			// 利用conn对象创建Statement并赋值给statement
			statement = conn.createStatement();
			// 执行更行操作
			statement.executeUpdate(sql);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {//关闭资源
			try {
				if (statement != null) {
				conn.close();
				}
				if(statement!=null){
					statement.close();
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {
		// 拼接sql语句
		String sql = "insert into student (name,age,birthday)values (" + "'"
				+ "夏天" + "'" + "," + "23" + "," + "'" + "1991-2-15" + "'" + ")";
		TestStatement test = new TestStatement();
		test.testUpdate(sql);
	}
}

class TestJDBC1 {

	public static Connection getConnection() throws SQLException, IOException,
			InstantiationException, IllegalAccessException,
			ClassNotFoundException {
		// 初始化连接所需的四个变量
		String driverClass = null;
		String url = null;
		String user = null;
		String password = null;

		// 利用反射获取properties输入流
		InputStream inputStream = TestJDBC1.class.getClassLoader()
				.getResourceAsStream("jdbc.properties");
		Properties properties = new Properties();
		// 加载输入流到properties
		properties.load(inputStream);

		// 从properties中取出连接需要四个条件
		driverClass = properties.getProperty("driver");
		url = properties.getProperty("url");
		password = properties.getProperty("password");
		user = properties.getProperty("user");

		// 利用反射创建相应数据库Driver的对象
		Driver driver = (Driver) Class.forName(driverClass).newInstance();
		Properties info = new Properties();
		info.put("user", user);
		info.put("password", password);
		// 通过driver对象调用connect方法获取数据库连接
		Connection connection = driver.connect(url, info);
		return connection;
	}
}</span>

运行结果:
控制台:insert into student (name,age,birthday)values ('夏天',23,'1991-2-15')
数据库中student表新增了一行
id   name  age     birthday
1 刘德华56 2014-10-17
2张学友54 1991-02-16
10  夏天 23   1991-02-15

这里我们发现:虽然只有三个字段,但我们在拼接sql字符串的话很辛苦,也很容易出现错误,如果数据库表中有10几个列名,我们的拼接起来肯定很麻烦,

那么有没有一种更好的方法呢?通过PreparedStatement!

PreparedStatement:

  • 通过调用 Connection 对象的 preparedStatement()方法获取 PreparedStatement对象
  • PreparedStatement 接口是 Statement 的子接口,它表示一条预编译过的 SQL语句
  • PreparedStatement 对象所代表的 SQL 语句中的参数用问号(?)来表示,调用 PreparedStatement对象的 setXXX() 方法来设置这些参数. setXXX() 方法有两个参数,第一个参数是要设置的 SQL 语句中的参数的索引(从 1 开始),第二个是设置的 SQL语句中的参数的值
通过改用PreparedStatement对象我们再来看一下这段代码:
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class TestPreparedStatement {
	public void testUpdate(String sql, Object... args) 
		// 创建Connection和PreparedStatement对象
		System.out.println(sql);
		Connection conn = null;
		PreparedStatement preparedStatement = null;

		try {// 利用静态方法获取链接
			conn = TestJDBC1.getConnection();
			// 利用conn对象创建Statement并赋值给PreparedStatement
			preparedStatement = conn.prepareStatement(sql);
			// 循环填充占位符,从1开始
			for (int i = 0; i < args.length; i++) {
				preparedStatement.setObject(i + 1, args[i]);
			}
			// 执行更新
			preparedStatement.executeUpdate();

		} catch (Exception e) {
			e.printStackTrace();
		} finally {// 关闭资源
			try {
				if (preparedStatement != null) {
					conn.close();
				}
				if (preparedStatement != null) {
					preparedStatement.close();
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {
		// 拼接sql语句
		String sql = "insert into student (name,age,birthday)values (?,?,?)";
		TestPreparedStatement test = new TestPreparedStatement();
		test.testUpdate(sql, "王宝强", 39, "1887-2-3");
	}
}
执行结果:控制台insert into student (name,age,birthday)values (?,?,?)
数据库student表:
idnameagebirthday
1刘德华562014-10-17
2张学友54 1991-02-16
10夏天 23   1991-02-15
11王宝强391887-02-03

分析以上代码我们可以发现几个优点:
1.我们不用再辛苦的去拼接sql语句了,再多的列名我们只需要用?代替.
2.我们对testUpdate()方法改进,让其接受两个参数:sql和可变长数组args,无论sql语句有多少个占位符,我们都能让其一一对应填充,也就是说无论sql语句是什么,更新的是哪张表,这个表需要插入那些字段,这个代码都是通用的,充分体现了代码的灵活性.
3.使用PreparedStatement还能有效的防止Sql注入攻击.sql注入就是用户输入数据中注入非法的 SQL 语句段或命令,从而利用系统的 SQL引擎完成恶意行为的做法.


sql查询

ResultSet:结果集
1.通过调用 Statement对象的 excuteQuery() 方法创建该对象
2.ResultSet 对象维护了一个指向当前数据行的游标,初始的时候,游标在第一行之前,可以通过 ResultSet 对象的 next() 方法移动到下一行

下面是利用ResultSet进行查询的例子:
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class TestResultSet {

	public void testSearch(String sql,Object...args) {
		//打印sql
		System.out.println(sql);
		//创建Connection preparedStatement ,ResultSet对象
		Connection conn = null;
		PreparedStatement preparedStatement = null;
		ResultSet resultSet = null;

		try {
			//获取连接
			conn = TestJDBC1.getConnection();
			preparedStatement = conn.prepareStatement(sql);
			//填充占位符
		for (int i = 0; i < args.length; i++) {
			preparedStatement.setObject(i+1, args[i]);
		}	//执行查询,得到resultSet结果集
			resultSet = preparedStatement.executeQuery();
			System.out.println("name\t"+"age\t"+"birthday");
			
		//遍历结果集
			while (resultSet.next()) {
				String name = resultSet.getString("name");
				int age = resultSet.getInt("age");
				Date birthday = resultSet.getDate("birthday");
				System.out.println(name + "\t" + age + "\t" + birthday);
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (resultSet != null) {
					resultSet.close();
				}
				if (preparedStatement != null) {
					preparedStatement.close();
				}
				if (conn != null) {
					conn.close();
				}
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {
			String sql="select * from student where name=?";
			String sql2="select * from student";
			TestResultSet trs=new TestResultSet();
			trs.testSearch(sql,"王宝强");
			System.out.println("--------------------------------------------");
			trs.testSearch(sql2);
	}

}

运行结果:
select * from student where name=?
name age birthday
王宝强 39 1887-02-03
--------------------------------------------
select * from student
name age birthday
刘德华 56 2014-10-17
张学友 54 1991-02-16
李小明 10 1991-02-16
韩梅梅 11 1991-02-16
李刚 43 1991-02-16
夏天 23 1991-02-15
王宝强 39 1887-02-03


------- android培训java培训、期待与您交流! ----------







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值