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

来源:互联网 发布:追回前男友的套路知乎 编辑:程序博客网 时间:2024/05/20 16:43

------- 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并赋值给statementstatement = 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();// 加载输入流到propertiesproperties.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     birthday1 刘德华56 2014-10-172张学友54 1991-02-1610  夏天 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并赋值给PreparedStatementpreparedStatement = 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表:
idnameagebirthday1刘德华562014-10-172张学友54 1991-02-1610夏天 23   1991-02-1511王宝强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) {//打印sqlSystem.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
原创粉丝点击