Java Web的数据库操作(一)

一、JDBC技术

1、JDBC简介

JDBC是Java程序与数据库系统通信的标准API,它定义在JDK的API中,通过JDBC技术,Java程序可以非常方便地与各种数据库交互,JDBC在Java程序与数据库系统之间假期了一座桥梁。

JDBC由一组用Java语言编写的类和接口组成,它对数据库的操作提供了基本方法,但由于数据库种类跟多且多有不同,所以对数据库的细节操作由数据库厂商进行实现,且厂商需要提供数据库的驱动程序,下图为Java程序与数据库相交互的示意图:

Java Web的数据库操作(一)

2、JDBC连接数据库的过程

l  下载驱动包

在JDK中,不包含数据库的驱动程序,使用JDBC操作数据库需要实现下载数据库厂商提供的驱动包,并导入到开发环境中。

l  注册数据库驱动

连接数据库前,需要将数据库厂商提供的数据库驱动注册到JDBC的驱动管理器中,一般是通过将数据库驱动类加载到JVM来实现的,例如连接MYSQL数据库:

Class.forName(“com.mysql.jdbc.Driver”);

l  构建数据库连接URL

URL由数据库厂商制定,不同数据库它的URL有所区别,但都符合一个基本的格式,即“JDBC协议+IP地址或域名+端口+数据库名称”,例如MYSQL数据库为”jdbc:mysql://localhost:8080/test”。

前两步中不同数据库有所差别,不同数据库连接请参考这篇文章:

http://blog.csdn.net/zhai56565/article/details/8959184

l  获取Connection对象

通过驱动管理器获得数据库的连接Connection,只有创建此对象后才可以对数据库进行操作,方法如下:

DriverManager.getConnection(url , username , password);

下面是一个完整的连接数据库的例子:

  1. try {
  2. //加载数据库驱动,注册到去送管理器
  3. Class.forName("com.mysql.jdbc.Driver");
  4. String url = "jdbc:mysql://localhost:8080/test";
  5. String username = "admin";
  6. String password = "123456";
  7. Connection conn = DriverManager.getConnection(url , username , password);
  8. if (conn != null)
  9. System.out.println("数据库连接成功!");
  10. else
  11. System.out.println("数据库连接失败!");
  12. //完成后记得关闭数据库连接
  13. conn.close();
  14. } catch (ClassNotFoundException e) {
  15. e.printStackTrace();
  16. } catch (SQLException e) {
  17. e.printStackTrace();
  18. }

二、JDBC API

JDBC是Java程序操作数据库的标准,它由一组用Java语言编写的类和接口组成,Java通过JDBC可以对多种关系数据库进行统一访问。下面介绍主要类和接口的作用,详细方法请参考J2SE的API。

1、 Connection接口

与特定数据库的连接会话,只有获得特定数据库的连接对象才能访问数据库,操作数据库中的数据表、视图和存储过程等。

方法声明

说明

Close()

立即释放Connection对象的数据库连接占用的JDBC资源

Commit()

提交事务,并释放Connection对象当前持有的所有数据库锁

createStatement()

创建Statement对象来将SQL语句发送到数据库

PreparedStatement

将参数化的SQL语句预编译并存储在PreparedStatement对象中

2、DriverManager类

主要作用与用户及驱动程序之间,它是JDBC中的管理层,通过它可以管理数据库厂商提供的驱动程序,并建立应用程序与数据库之间的连接。

方法声明

说明

getConnection(String url)

根据指定数据库连接URL,建立Connection

getConnection(String url , Properties info)

根据指定数据库连接URL及数据库连接属性信息建立数据库连接Connection,参数info为数据库连接属性

getConnection(url,un,pwd)

根据指定数据库连接URL,用户名和密码连接数据库

getDrivers()

获取当前DriverManager中已加载的所有驱动程序

3、 Statement接口

Statement接口封装了执行SQL语句和获取查询接口的基本方法。

方法声明

说明

AddBatch(String sql)

将SQL语句添加到Statement对象的当前命令列表中,用于SQL命令的批处理

clearBatch()

清空Statement对喜爱那个的命令列表

Close()

立即释放Statement对象的数据库和JDBC资源,而不是等待该对象自动关闭时执行

Execute(String sql)

执行指定的SQL语句,若SQL返回结果,该方法返回true,否则返回false

executeBatch()

将一批SQL命令提交给数据库执行,返回更新计数组成的数据

executeQuery(String sql)

执行查询类型的sql语句,该方法返回查询所获取的结果集ResultSet

executeUpdate(String sql)

执行SQL语句中DML类型(insert、update、delete)的SQL语句,返回更新所影响的行数

getConnection()

获取生成Statement对喜爱那个的Connection对象

4、PreparedStatement接口

Statement接口封装了JDBC执行SQL语句的方法,但在实际开发过程中,SQL语句往往需要将程序中的变量做查询条件参数等。使用Statement接口进行操作过于繁琐且存在安全缺陷。而PreparedStatement接口继承与Statement接口,且对带有参数SQL语句的执行操作进行了扩展。应用于PreparedStatement接口中的SQL语句可以使用占位符”?”来代替SQL语句中的参数,然后再对其进行赋值。

方法声明

说明

setBinaryStream(int x , InputStream s)

将输入流s作为SQL语句中的参数值,x为参数位置索引

setBoolean(int x , Boolean b)

将布尔值b作为SQL语句中的参数值,x为参数位置索引

SetByte

……

setInt

……

等等。。。。。。

……

5、ResultSet接口

ResultSet对象封装了数据查询的结果集,它包含了符合SQL语句的所有行,针对Java中的数据类型提供了一套getXXX()的方法,通过这些方法可以获取每一行中的数据。ResultSet还提供了光标的功能,通过光标可以*定位到某一行中的数据。

方法声明

说明

Absolute(int row)

光标移动到ReulstSet对象的给定行编号

afterLast()

光标移动到最后一行后,如果结果集中不包含任何行,则该方法无效

beforFirst()

立即释放ResultSet对喜爱那个的数据库和JDBC资源

deleteRow()

删除当前行

First()

光标移动到第一行

getString(String columnLable)

以String的方式获取ResultSet对象当前行中指定列的值,参数为列名称

getBinaryStream(String colunmLable)

你懂得

getInt(String columnLable)

你懂得

isClosed()

判断ResultSet对喜爱那个是否已关闭

Last()

移动到最后一行

Next()

移动到下一行,若新行无效则返回false

Previous()

移动到上一行,若新行无效则返回false

三、JDBC操作数据库

上一篇介绍了JDBC API,之后就可以通过API来操作数据库,实现对数据库的CRUD操作了。

http://blog.csdn.net/zhai56565/article/details/9794225

下面仅以示例 的方式对数据库操作进行说明

1、 添加数据

使用PreparedStatement添加数据:

  1. String sql = "INSERT INTO tb_books(name,price,count,author)valuse(?,?,?,?)";
  2. PreparedStatement ps = conn.prepareStatement(sql);
  3. ps.setString(1, "西游记");
  4. ps.setDouble(2, 66.0);
  5. ps.setInt(3, 200);
  6. ps.setString(4, "吴承恩");
  7. int row = ps.executeUpdate();
  8. if(row > 0)
  9. System.out.println("成功添加了" + row + "条数据");

使用Statement添加数据:

  1. String sql = "INSERT INTO tb_books(name,price,count,author)valuse(" + "西游记" + "," + 66.0 + "," + 200 + "," + "吴承恩" + ")";
  2. ps.close();
  3. Statement ps = conn.createStatement();
  4. int row = ps.executeUpdate(sql);
  5. if(row > 0)
  6. System.out.println("成功添加了" + row + "条数据");
  7. ps.close();

2、查询数据

查询数据是通过一个Web项目来演示,通过JDBC查询图书信息表中的图书信息数据,并将其显示在JSP页面中:

创建Book类:

  1. package com;
  2. public class Book {
  3. private int id;
  4. private String name;
  5. private double price;
  6. private int count;
  7. private String author;
  8. public Book(int id , String name , double price , int count , String author) {
  9. this.id = id;
  10. this.name = name;
  11. this.price = price;
  12. this.count = count;
  13. this.author = author;
  14. }
  15. public int getId(){
  16. return id;
  17. }
  18. public void setId(int id){
  19. this.id = id;
  20. }
  21. public String getName(){
  22. return name;
  23. }
  24. public void setName(String name){
  25. this.name = name;
  26. }
  27. public double getPrice(){
  28. return price;
  29. }
  30. public void setPrice(double price){
  31. this.price = price;
  32. }
  33. public int getCount(){
  34. return count;
  35. }
  36. public void setCount(int count){
  37. this.count = count;
  38. }
  39. public String getAuthor(){
  40. return author;
  41. }
  42. public void setAuthor(String author){
  43. this.author = author;
  44. }
  45. }

创建Servlet对象FindServlet:

  1. @WebServlet("/FindServlet")
  2. public class FindServlet extends HttpServlet {
  3. private static final long serialVersionUID = 1L;
  4. public FindServlet() {
  5. super();
  6. }
  7. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  8. doPost(request, response);
  9. }
  10. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  11. try {
  12. Class.forName("com.mysql.jdbc.Driver");
  13. String url = "jdbc:mysql://localhost:8080/db_test";
  14. String username = "admin";
  15. String password = "123456";
  16. Connection connection = DriverManager.getConnection(url, username, password);
  17. Statement statement = connection.createStatement();
  18. String sql = "SELECT * FROM tb_books";
  19. ResultSet rs = statement.executeQuery(sql);
  20. ArrayList<Book> list = new ArrayList<Book>();
  21. while (rs.next()) {
  22. Book book = new Book(rs.getInt("id") , rs.getString("name") ,
  23. rs.getDouble("price") , rs.getInt("count") , rs.getString("author"));
  24. list.add(book);
  25. }
  26. request.setAttribute("list", list);
  27. rs.close();
  28. statement.close();
  29. connection.close();
  30. } catch (ClassNotFoundException e) {
  31. e.printStackTrace();
  32. } catch (SQLException e) {
  33. e.printStackTrace();
  34. }
  35. //将请求转发到book_list.jsp
  36. request.getRequestDispatcher("book_list.jsp").forward(request, response);
  37. }
  38. }

创建book_list.jsp页面:

  1. <body>
  2. <table align="center" width="450" border="2">
  3. <tr>
  4. <td align="center" colspan="2"><h2>所有图书信息</h2></td>
  5. </tr>
  6. <tr align="center">
  7. <td><b>ID</b></td>
  8. <td><b>图书名称</b></td>
  9. <td><b>价格</b></td>
  10. <td><b>数量</b></td>
  11. <td><b>作者</b></td>
  12. </tr>
  13. <%
  14. //获取图书信息集合
  15. ArrayList<Book> list = (ArrayList<Book>)request.getAttribute("list");
  16. if(list == null || list.size() < 1)
  17. out.print("没有数据!");
  18. else{
  19. for(Book book : list){
  20. %>
  21. <tr align="center">
  22. <td><%= book.getId() %></td>
  23. <td><%= book.getName() %></td>
  24. <td><%= book.getPrice() %></td>
  25. <td><%= book.getCount() %></td>
  26. <td><%= book.getAuthor() %></td>
  27. </tr>
  28. <%
  29. }
  30. }
  31. %>
  32. </table>
  33. </body>

创建index.jsp页面:

  1. <body>
  2. <a href="FindServlet">查看所有图书</a>
  3. </body>

3、修改数据

修改数据的方法,除了SQL语句外其它都与添加数据相同,其SQL语句为:

UPDATE 表 SET 属性=xxx WHERE 属性=xxx

在实际开发中,通常都是由程序传递SQL语句中的参数,所以修改数据也需要使用PreparedStatement对象进行操作。

4、删除数据

修改数据的方法,除了SQL语句外其它都与添加数据相同,其SQL语句为:

DELETE FROM 表 WHERE 属性=xxx

在实际开发中,通常都是由程序传递SQL语句中的参数,所以删除数据也需要使用PreparedStatement对象进行操作。

5、批处理

JDBC中批处理的原理是将批量的SQL语句一次性发送到数据库中进行执行,从而解决多次与数据库连接所产生的速度瓶颈。下面是一个使用批处理添加数据的方法:

  1. public int saveBatch() {
  2. int row = 0;
  3. try {
  4. String sql = "INSERT INTO tb_books(id,name,price,count,anthor) VALUES(?,?,?,?,?)";
  5. PreparedStatement ps = connection.prepareStatement(sql);
  6. for (int i = 0; i < 10; i++) {
  7. ps.setInt(1, i);
  8. ps.setString(2, "书" + i);
  9. ps.setDouble(3, i*10.5);
  10. ps.setInt(4, i*20);
  11. ps.setString(5, "作者" + i);
  12. //添加批处理命令
  13. ps.addBatch();
  14. }
  15. //执行批处理操作并返回计数组成的数据
  16. int[] rows = ps.executeBatch();
  17. row = rows.length;
  18. ps.close();
  19. connection.close();
  20. } catch (SQLException e) {
  21. e.printStackTrace();
  22. }
  23. return row;
  24. }

6、调用存储过程

在JDBC API中提供了调用存储过程的方法,通过CallableStatement对象进行操作。CallableStatement对象位于java.sql包中,它继承于Statement对象,主要用于执行数据库中定义的存储过程,其调用方法如下:

{call <procedure-name>[(<arg1>,<arg2>,…)]}

其中arg1、arg2为存储过程中的参数,如果存储过程中需要传递参数,可以对其进行赋值操作。

存储过程是一个SQL语句和可选控制流语句的预编译集合。编译完成后存放在数据库中,这样就省去了执行SQL语句时对SQL语句进行编译所花费的时间。在执行存储过程时只需要将参数传递到数据库中,而不需要将整条SQL语句都提交给数据库,从而减少了网络传输的流量,提高了程序的运行速度。

各种数据库创建存储过程的方法并非一致,下面以SQL Server 2012调用存储过程的方法做讲解,其他数据库请参考其帮助文档:

首先打开 SQL Server Management Studio,依次打开实例、数据库、你的数据库、可编程性、存储过程,右键存储过程选择新建存储过程。这是会弹出文本窗口,内有许多文本,鉴于初学者,将文本内容全部删掉,以下面的代码代替之:

  1. USE [test]
  2. GO
  3. CREATE PROCEDURE findAllBooks
  4. AS
  5. BEGIN
  6. SELECT * from tb_books
  7. END
  8. GO

在程序中关键代码如下:

    1. CallableStatement cs = connection.prepareCall("{call findAllBook()}");
    2. ResultSet resultSet = cs.executeQuery();
    3. 前面介绍了JDBC技术和JDBC API及API的使用示例,下面详细介绍JDBC在Web中的应用。

      Java Web----Java Web的数据库操作(一)

      Java Web----Java Web的数据库操作(二)

      四、JDBC在Java Web中的应用

      通常情况下,Web程序操作数据库都是通过JDBC实现,即使目前数据库方面的开源框架有许多,但其底层实现都离不开JDBC API。

      1、开发模式

      在Java Web开发中使用JDBC,应遵循MVC的设计思想,从而使Web程序拥有一定的健壮性、可扩展性。每个Java Web程序员都应该深谙MVC的设计思想,下面对其简单介绍。

      MVC(Model-View-Controller)是一种设计理念,该理念将软件分成3层结构,分别为模型层、视图层和控制层。

      •  模型层泛指程序中的业务逻辑,用于处理真正的业务操作;
      •  视图层是指程序与用户交互的界面,对用户呈现出视图,但不包括业务逻辑;
      •  控制层是对用户各种请求的分发处理,将制定的请求分配给制定的业务逻辑进行处理。

      JDBC应用于Java Web开发中,处于MVC中的模型层位置,如图所示:

      Java Web的数据库操作(一)

      客户端通过JSP页面与程序进行交互,对于数据的增、删、改、查请求由Servlet对其进行分发处理,如Servlet接收到添加数据请求,就会分发给增加数据的JavaBean对象,而真正的数据库操作是通过JDBC封装的JavaBean进行实现。

      2、分页查询

      分页查询用于在数据库量非常大,不适合将所有数据显示在一页中的情况。通过JDBC实现分页查询的方法有很多种,而且不同的数据库机制也提供了不同的分页方式,在这里介绍两种非常典型的分页方法:

             1)、通过ResultSet的光标实现分页

      ResultSet为查询结果集对象,在该对象中有一个“光标”的概念(可以参考第一篇中的JDBC API介绍),光标通过上下移动定位查询结果集中的行,从而获取数据。所以通过移动“光标”,可以设置ResultSet对象中记录的起始位置和结束为止,来实现数据的分页显示。

             2)、通过数据库机制进行分页

      很多数据库自身都提供了分页机制,如SQL Server中提供的top关键字,MySQL中提供的limit关键字,他们都可以设置数据返回的记录数。

      下面是MYSQL数据库提供的分页机制,关键代码如下:

      1. String sql = "SELECT * FROM tb_book ORDER BY id DESC LIMIT ?,?";
      2. PreparedStatement ps = connection.prepareStatement(sql);
      3. ps.setInt(1, (page - 1)*Book.PAGE_SIZE);//page为页数
      4. ps.setInt(2, Book.PAGE_SIZE);
      5. ResultSet rs = ps.executeQuery();

      Limit关键字能够控制查询数据结果集起始位置及返回记录的数量,它的两个参数分别用于指定查询记录的其实位置和所返回的记录数。而返回总记录数可以使用以下方法:

      1. int count = 0;
      2. String sql = "SELECT count(*) FROM tb_book";
      3. Statement statement = connection.createStatement();
      4. ResultSet resultSet = statement.executeQuery(sql);
      5. if (resultSet.next())
      6. count = resultSet.getInt(1);

      下面是一个使用MySQL数据库实现分页查询的源码,可以参考下:

      http://download.csdn.net/detail/zhai56565/5885775

上一篇:Boostrap入门(一)


下一篇:用configmap管理配置