JDBC简介,MySQL连接,PreparedStatement 预处理命令,通配符



  何须浅碧轻红色,自是花中第一流。 —李清照的《鹧鸪天·桂花》


  • JDBC 简介

    • 我实验的MySQL数据库
    • 配置连接MySQL驱动
    • 数据库连接工具类
  • JDBC API
    • Driver 接口
    • Connection 接口
    • DriverManager 类
    • Statement 接口
    • PreparedStatement 接口
    • CallableStatement 接口
    • ResultSet 接口
  • JDBC 数据库操作
    • 测试连接示例
    • 添加数据
    • 查询信息
    • 修改数据
    • 删除数据
    • 批处理
    • 调用存储过程

JDBC 简介

JDBC 全称为 Java Data Base Connectivity ,是 Java 程序与数据库系统通信的标准 API,它定义在 JDK 的 API 中。

JDBC 就像一座 Java 运用和数据库连接的桥梁。

1 我实验的MySQL数据库

数据库名:db_book

表名:tb_book

建表语句

DROP TABLE IF EXISTS `tb_book`;
CREATE TABLE `tb_book` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) DEFAULT NULL,
  `price` float DEFAULT NULL,
  `bookCount` int(11) DEFAULT NULL,
  `author` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2 配置连接MySQL驱动

MySQL驱动 mysql-connector-java-5.1.39 下载http://download.csdn.net/detail/peng_hong_fu/9645521

在 Project 新建 lib目录,然后如图

3 数据库连接工具类

DBUtil.java

//package com.peng.db;

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

public class DBUtil {
    private static final String URL = "jdbc:mysql://127.0.0.1:3306/db_book?characterEncoding=utf8&useSSL=false";
    private static final String USER = "root";
    private static final String PASSWORD = "root";

    private static Connection conn = null;

    static {// 加载类时会执行这些静态的代码块
        try {
            // 1.加载驱动程序
            Class.forName("com.mysql.jdbc.Driver");
            // 2.获得数据库连接
            conn = DriverManager.getConnection(URL, USER, PASSWORD);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }

    }

    public static Connection getConn() {
        return conn;
    }
}

JDBC API

1 Driver 接口

每种数据库的驱动程序都应该提供一个实现java.sql.Driver接口的类,简称 Driver 类,在加载 Driver 类时,应该创建自己的实例并向 java.sql.DriverManager 类注册该实例。

// 1.加载驱动程序
Class.forName("com.mysql.jdbc.Driver");

2 Connection 接口

Connection 接口位于java.sql包中,负责与特定数据库的连接。在数据库应用开发时,只有获得了特定数据库的连接对象,才能访问数据库,操作数据库中的数据表、视图和存储过程等。

void close() 立即释放此 Connection 对象的数据库和 JDBC 资源,而不是等待它们被自动释放。

void commit() 使所有上一次提交/回滚后进行的更改成为持久更改,并释放此 Connection 对象当前持有的所有数据库锁。

Statement createStatement() 创建一个 Statement 对象来将 SQL 语句发送到数据库。

boolean getAutoCommit()获取此 Connection 对象的当前自动提交模式。

void setAutoCommit(boolean autoCommit) 将此连接的自动提交模式设置为给定状态。默认为true 自动提交

void rollback()  取消在当前事务中进行的所有更改,并释放此 Connection 对象当前持有的所有数据库锁。

PreparedStatement prepareStatement(String sql) 创建一个 PreparedStatement 对象来将参数化的 SQL 语句发送到数据库。
.
.

更多方法http://www.apihome.cn/api/java/Connection.html

3 DriverManager 类

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

static void deregisterDriver(Driver driver) 从 DriverManager 的列表中删除一个驱动程序。

static Connection getConnection(String url) 试图建立到给定数据库 URL 的连接。

static Connection getConnection(String url, Properties info)试图建立到给定数据库 URL 的连接。

static Connection getConnection(String url, String user, String password)试图建立到给定数据库 URL 的连接。

static Driver   getDriver(String url) 试图查找能理解给定 URL 的驱动程序。
.
.

更多方法:http://www.apihome.cn/api/java/DriverManager.html

4 Statement 接口

在创建数据库连接之后,就可以通过程序来调用 SQL 语句来对数据库进行操作了,在 JDBC 中 Statement 接口封装了这些操作。Statement 接口提供了执行语句和获取查询结果的基本方法。

boolean execute(String sql) 执行指定的 SQL 语句。如果SQL语句返回执行结果,返回true

ResultSet executeQuery(String sql) 执行查询类型(SELECT)的 SQL 语句。此方法返回查询获得的结果集 ResultSet 对象

Connection getConnection() 获取生成此 Statement 对象的 Connection 对象
.
.

更多方法http://tool.oschina.net/apidocs/apidoc?api=jdk_7u4

5 PreparedStatement 接口

PreparedStatement 接口继承于 Statement,它拥有 Statement 接口中的方法,而且针对带参数 SQL 语句的执行操作进行了扩展,解决了SQL语句需要将程序中的变量作为查询条件的参数的问题,而且更加安全,可以使用占位符 ? 来代替 SQL 语句中的参数,然后在对其进行赋值。

Java 提供了高效的数据库操作机制,那就是 PreparedStatement 对象,该对象被习惯地称作预处理语句对象。

向数据库发送一个 SQL 语句时,如 " select * from goods"数据库中的SQL 解释器负责把SQL 语句生成底层的内部命令,然后执行该命令,完成有关的数据操作。如果不断向数据库 SQL 语句势必增加数据库中 SQL 解释器的负担,影响执行的速度。如果应用程序能针对连接的数据库,事先就将 SQL语句解释为数据库底层的命令,然后直接让数据库执行这个命令,显然不仅减轻了数据库的负担,而且也提高了访问数据库的速度。

对于 JDBC ,如果使用 Connection 和某个数据库建立了连接对象 conn , 那么 con 就可以调用

PreparedStatement prepareStatement(String sql)
        throws SQLException

方法对参数 sql 指定的 SQL 语句进行预编译处理,生成该数据库底层的命令,并将该命令封装在 PreparedStatement 对象中,那么该对象调用下列方法都可以使得该底层内部命令被数据库执行。

boolean execute(String sql) 执行指定的 SQL 语句。如果SQL语句返回执行结果,返回true

ResultSet executeQuery(String sql) 执行查询类型(SELECT)的 SQL 语句。此方法返回查询获得的结果集 ResultSet 对象

Connection getConnection() 获取生成此 Statement 对象的 Connection 对象

void setDate(int parameterIndex, Date x) 使用运行应用程序的虚拟机的默认时区将指定参数设置为给定 java.sql.Date 值。

void setDouble(int parameterIndex, double x) 将指定参数设置为给定 Java double 值。

void setFloat(int parameterIndex, float x) 将指定参数设置为给定 Java REAL 值。

void setInt(int parameterIndex, int x) 将指定参数设置为给定 Java int 值。

void setLong(int parameterIndex, long x) 将指定参数设置为给定 Java long 值。

void setTimestamp(int parameterIndex, Timestamp x) 将指定参数设置为给定 java.sql.Timestamp 值。
.
.

6 CallableStatement 接口

CallableStatement 继承于 PreparedStatement 接口,是 PreparedStatement 接口的扩展,用来执行 SQL 的存储过程。

若数据库有存储过程select_count()

BEGIN
    SELECT count(*) INTO counts FROM tb_book;
END
/**
     * 带输出参数的存储过程
     *
     * @return
     * @throws SQLException
     */
    public static Integer select_count() throws SQLException {
        Integer count;
        // 获取连接
        Connection conn = DBUtil.getConn();
        // 获取CallableStatement
        CallableStatement cs = conn.prepareCall("call select_count(?)");
        cs.registerOutParameter(1, Types.INTEGER);
        cs.execute();
        count = cs.getInt(1);
        return count;
    }

7 ResultSet 接口

执行 SQL 语句的查询语句会返回查询的结果集, 在 JDBC API 中,使用 ResultSet 对象接收查询结果集。

ResultSet 对象包含了符合 SQL 语句的所有行,针对 Java 的数据类型提供了一套 getter 方法,通过这些方法可获取每一行的数据,ResultSet 还提供了光标的功能,通过光标可以自由定位到某一行的数据。

byte getByte(int columnIndex) 以 Java 编程语言中 byte 的形式获取此 ResultSet 对象的当前行中指定列的值。

Reader getCharacterStream(int columnIndex) 以 java.io.Reader 对象的形式获取此 ResultSet 对象的当前行中指定列的值。

Date getDate(int columnIndex) 以 Java 编程语言中 java.sql.Date 对象的形式获取此 ResultSet 对象的当前行中指定列的值。

double getDouble(int columnIndex) 以 Java 编程语言中 double 的形式获取此 ResultSet 对象的当前行中指定列的值。

float getFloat(int columnIndex) 以 Java 编程语言中 float 的形式获取此 ResultSet 对象的当前行中指定列的值。

int getInt(int columnIndex) 以 Java 编程语言中 int 的形式获取此 ResultSet 对象的当前行中指定列的值。

long getLong(int columnIndex) 以 Java 编程语言中 long 的形式获取此 ResultSet 对象的当前行中指定列的值。

String  getString(int columnIndex) 以 Java 编程语言中 String 的形式获取此 ResultSet 对象的当前行中指定列的值。

Time getTime(int columnIndex) 以 Java 编程语言中 java.sql.Time 对象的形式获取此 ResultSet 对象的当前行中指定列的值。

Timestamp getTimestamp(int columnIndex) 以 Java 编程语言中 java.sql.Timestamp 对象的形式获取此 ResultSet 对象的当前行中指定列的值。

boolean next() 将光标从当前位置向前移一行。如果新行有效则返回true

更多方法:http://www.apihome.cn/api/java/ResultSet.html

JDBC 数据库操作

1 测试连接示例

使用预处理命令处理 MySQL 数据库查询命令

数据库名:db_book

user: root

password:root

表名 :tb_book

JavaBean 类

Book.java

//package com.jdbc.model;
/**
 * Title: Book
 * Description: Book实体类
 * @author Peng
 * @date 上午9:53:46
 */
public class Book {
    private int id;// 编号
    private String name;// 图书名称
    private double price;// 定价
    private int bookCount;// 数量
    private String author;// 作者
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    public int getBookCount() {
        return bookCount;
    }
    public void setBookCount(int bookCount) {
        this.bookCount = bookCount;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
    @Override
    public String toString() {
        return "Book [id=" + id + ", name=" + name + ", price=" + price + ", bookCount=" + bookCount + ", author="
                + author + "]";
    }
}

TestConn.java

//package com.jdbc.test;

public class TestConn {
       public static void main(String args[]) {
         PrepareQuery query=new PrepareQuery();
         query.setTablename("db_book");
         query.setUser("root");
         query.setPassword("root");
         query.setSql("select name,price,author from tb_book");
         query.inputQuery();
       }
}

PrepareQuery.java

//package com.jdbc.test;

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

public class PrepareQuery {
    // private static final String URL =
    // "jdbc:mysql://127.0.0.1:3306/peng?characterEncoding=utf8&useSSL=false";
    // private static final String USER = "root";
    // private static final String PASSWORD = "root";
    private static Connection conn = null;
    private String tablename;
    private String sql;
    private String user;
    private String password;

    public void setSql(String sql) {
        this.sql = sql;
    }

    public void setTablename(String tablename) {
        this.tablename = tablename;
    }

    public void setUser(String user) {
        this.user = user;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void inputQuery() {
        try {
            // 1.加载驱动程序
            Class.forName("com.mysql.jdbc.Driver");
            // 2.获得数据库连接
            String URL = "jdbc:mysql://127.0.0.1:3306/" + tablename + "?characterEncoding=utf8&useSSL=false";
            conn = DriverManager.getConnection(URL, user, password);

            PreparedStatement ptmt = conn.prepareStatement(sql);
            ResultSet rs = ptmt.executeQuery();

            while (rs.next()) {
                System.out.println(rs.getString("name") + "," + rs.getDouble("price")+rs.getString("author"));
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
JSP开发指南,45.0刘德华
SQL Server,56.0张学友
HTML+CSS,36.0黎明

2 添加数据

Insert [INTO] table_name [(column_list)] values (data_values)

这里有两个 jsp 页面,一个供用户输入图书信息,另一个接收图书信息,并执行添加数据操作,实际开发过程中,jsp页面是不负责任何逻辑业务的,这种和数据库交互业务是在 servlet 中处理的,这里只是测试。

封装数据库连接

DBUtil.java

//package com.jdbc.db;

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

public class DBUtil {
    private static final String URL = "jdbc:mysql://127.0.0.1:3306/db_book?characterEncoding=utf8&useSSL=false";
    private static final String USER = "root";
    private static final String PASSWORD = "root";

    private static Connection conn = null;

    static {// 加载类时会执行这些静态的代码块
        try {
            // 1.加载驱动程序
            Class.forName("com.mysql.jdbc.Driver");
            // 2.获得数据库连接
            conn = DriverManager.getConnection(URL, USER, PASSWORD);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }

    }

    public static Connection getConn() {
        return conn;
    }
}

indexAdd.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.sql.*"%>
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>添加图书信息</title>
<script type="text/javascript">
    function check(form) {
        if (form.name.value == "") {
            alert("图书名称不能为空");
            return false;
        }
        if (form.price.value == "") {
            alert("定价不能为空");
            return false;
        }
        if (form.author.value == "") {
            alert("作者不能为空");
            return false;
        }
        return true;
    }
</script>
<style type="text/css">
ul {
    list-style: none; /*设置不显示项目符号*/
    margin: 0px; /*设置外边距*/
    padding: 5px; /*设置内边距*/
}

li {
    padding: 5px; /*设置内边距*/
}
</style>
</head>
<body>
    <form action="addBook.jsp" method="post" onsubmit=" return check(this)">
        <ul>
            <li>图书名称:<input type="text" name="name" /></li>
            <li>价  格:<input type="text" name="price" /></li>
            <li>数  量:<input type="text" name="bookCount" /></li>
            <li>作  者:<input type="text" name="author" /></li>
            <li><input type="submit" value="添 加"></li>
        </ul>
    </form>
</body>
</html>

addBook.jsp

<%@page import="com.jdbc.db.DBUtil"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<%request.setCharacterEncoding("UTF-8"); %>
<jsp:useBean id="book" class="com.jdbc.model.Book"></jsp:useBean>
<jsp:setProperty property="*" name="book"/>

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>保存图书信息</title>
</head>
<body>
<%
    try {
        Connection conn= DBUtil.getConn();
        String sql = "insert into tb_book(name,price,bookCount,author) values(?,?,?,?)"; // 添加图书信息的SQL语句
        PreparedStatement ps = conn.prepareStatement(sql); // 获取PreparedStatement
        ps.setString(1, book.getName()); // 对SQL语句中的第1个参数赋值
        ps.setDouble(2, book.getPrice()); // 对SQL语句中的第2个参数赋值
        ps.setInt(3, book.getBookCount()); // 对SQL语句中的第3个参数赋值
        ps.setString(4, book.getAuthor()); // 对SQL语句中的第4个参数赋值
        int row = ps.executeUpdate(); // 执行更新操作,返回所影响的行数
        if (row > 0) { // 判断是否更新成功
            out.print("成功添加了 " + row + "条数据!"); // 更新成输出信息
        }
        ps.close(); // 关闭PreparedStatement,释放资源
        conn.close(); // 关闭Connection,释放资源
    } catch (Exception e) {
        out.print("图书信息添加失败!");
        e.printStackTrace();
    }
%>
<br>
<a href="index.jsp">返回</a>
</body>
</html>

3 查询信息

SELECT [ALL|DISTINCT] <目标列表表达式>[,<目标列表表达式>]...
FORM <表名或视图名>[,<表名或视图名>]
[WHERE <条件表达式>]
[GROUP BY<列名> [HAVING <条件表达式>]]
[ORDER BY <列名2>[ASC| DESC]]

如:

嵌入算术表达式
SELECT name,2016-age FROM Student
去掉重复行(默认为 ALL)
SELECT DISTINCT age FROM Student
选择
SELECT name,age FROM Student WHERE age<20
确定范围
SELECT name,age FROM Student WHERE age  BETWEEN 20 AND 23
SELECT name,age FROM Student WHERE age NOT BETWEEN 20 AND 23
确定集合
SELECT name,age FROM Student WHERE age NOT IN(19,20,23)
字符匹配 "%"任意长度 "_"任意当个字符
SELECT * FROM Student WHERE name LIKE ‘刘%‘
SELECT * FROM Student WHERE name LIKE ‘刘_‘
SELECT * FROM Student WHERE name LIKE ‘_刘%‘
SELECT * FROM Student WHERE name MOT LIKE ‘刘%‘
去除通配符的影响"\" 匹配DB_Design字符
SELECT * FROM Student WHERE name ‘DB\_Design‘ ESCAPE‘\‘
涉及空值的查询
SELECT * FROM Student WHERE score IS NOT NULL
多重查询
SELECT * FROM Student WHERE Sdept="信工系" AND age<20
排序ORDER BY ASC升序 DESC降序
SELECT * FROM Student ORDER BY mumber,age DESC 按mumber降序排列,相同按年龄降序排列

聚集函数(只能用于SELECT子句和 group by 中的 having 子句)
COUNT(*) 统计元组个数
COUNT([DISTINCT|ALL] <列名>) 统计一列中值的个数
SUM([DISTINCT|ALL]<列名>) 计算一列值的总和(必须此列为数组型)
AVG([DISTINCT|ALL]<列名>) 计算一列值的平均值(必须此列为数组型)
MAX([DISTINCT|ALL]<列名>) 求一列值的最大值
MIN([DISTINCT|ALL]<列名>)
SELECT SUM(Score) FROM Student WHERE id=2010

GROUP BY子句
SELECT Cno,COUNT(Cno) FROM Student GROUP BY Cno 查询结果按Cno分组,计算每组人数
SELECT id FROM Student GROUP BY Sno HAVING COUNT(*)>3 选修了三门以上课程(Sno)的学号(id)

index.jsp 页面请求 FindServlet 在 servlet 里执行 SQL 语句,请求数据库数据,获取 Book对象的 list 集合,再携带数据跳转到 bookList.jsp ,通过request 获取数据,利用嵌入的java 的 for 循环,在页面上输出。

因为与数据库连接时 一个工具 JavaBean 类,getconn方法是一个 static 方法,所以不能再servlet 里关闭 conn 连接。

这里的连接数据库业务,执行 SQL 语句的任务,其实应该放到 dao 层

indexCha.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.sql.*"%>
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>首页</title>
</head>
<body>
<a href="FindServlet">查看图书列表</a>
</body>
</html>

FindServlet.java

//package com.jdbc.servlet;

import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.jdbc.db.DBUtil;
import com.jdbc.model.Book;

/**
 * Title: FindServlet
 * Description: Servlet实现类FindServlet
 * @author Peng
 * @date 上午11:11:40
 */
@WebServlet("/FindServlet") // 配置Servlet
public class FindServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public FindServlet() {
        super();
    }

    /**
     * 执行POST请求的方法
     */
    protected void doPostt(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

    /**
     * 执行GET请求的方法
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        try {
            // 创建Connection连接
            Connection conn = DBUtil.getConn();
            Statement stmt = conn.createStatement(); // 获取Statement
            String sql = "select * from tb_book"; // 添加图书信息的SQL语句
            ResultSet rs = stmt.executeQuery(sql); // 执行查询
            List<Book> list = new ArrayList<>(); // 实例化List对象
            while (rs.next()) { // 光标向后移动,并判断是否有效
                Book book = new Book(); // 实例化Book对象
                book.setId(rs.getInt("id")); // 对id属性赋值
                book.setName(rs.getString("name")); // 对name属性赋值
                book.setPrice(rs.getDouble("price")); // 对price属性赋值
                book.setBookCount(rs.getInt("bookCount")); // 对bookCount属性赋值
                book.setAuthor(rs.getString("author")); // 对author属性赋值
                list.add(book); // 将图书对象添加到集合中
            }
            request.setAttribute("list", list); // 将图书集合放置到request中
            rs.close(); // 关闭ResultSet
            stmt.close(); // 关闭Statement
            //conn.close();这里不能关闭
        } catch (SQLException e) {
            e.printStackTrace();
        }
        // 请求转发到bookList.jsp
        request.getRequestDispatcher("bookList.jsp").forward(request, response);
    }
}

bookList.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.*"%>
<%@ page import="com.jdbc.model.Book"%>
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>显示图书列表</title>
<style type="text/css">
td,th {
    padding: 5px;
    background-color: #FFFFFF;
}
div{
    width: 98%;
    text-align: center;
}
table{
    width:98%;
    background-color: #666666;

}
tr{
    text-align: center;
}
</style>
</head>
<body>
    <div>
        <h2>所有图书信息</h2>
    </div>
    <table cellspacing="1">
        <tr>
            <th>ID</th>
            <th>图书名称</th>
            <th>价格</th>
            <th>数量</th>
            <th>作者</th>
        </tr>
        <%
            // 获取图书信息集合
            List<Book> list = (List<Book>) request.getAttribute("list");
            // 判断集合是否有效
            if (list == null || list.size() < 1) {
                out.print("<tr><td bgcolor=‘#FFFFFF‘ colspan=‘5‘>没有任何图书信息!</td></tr>");
            } else {
                // 遍历图书集合中的数据
                for (Book book : list) {
        %>
        <tr >
            <td><%=book.getId()%></td>
            <td><%=book.getName()%></td>
            <td><%=book.getPrice()%></td>
            <td><%=book.getBookCount()%></td>
            <td><%=book.getAuthor()%></td>
        </tr>
        <%
            }
        }
        %>
    </table>
</body>
</html>

3 修改数据

UPDATE table_name
SET <column_name>=<expression>
    [...,<last column_name>=<last expression>]
[WHERE <search_condition>]

更新了 bookList.jsp ,添加一个 UpdateServlet,进行更新处理后跳转到 FindServlet 实现数据的刷新显示

bookList.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.*"%>
<%@ page import="com.jdbc.model.Book"%>
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>显示图书列表</title>
<style type="text/css">
tr {
    height:30px;
}
</style>
<script type="text/javascript">
    function check(form){
        if(form.bookCount.value == ""){
            alert("请输入更新数量!");
            form.bookCount.focus();
            return false;
        }
        if(isNaN(form.bookCount.value)){
            alert("格式错误!");
            form.bookCount.focus();
            return false;
        }
        return true;;
    }
</script>
<style type="text/css">
td,th {
    padding: 5px;
    background-color: #FFFFFF;
}
div{
    width: 98%;
    text-align: center;
}
table{
    width:98%;
    background-color: #666666;

}
tr{
    text-align: center;
}
</style>
</head>
<body>
    <div>
        <h2>所有图书信息</h2>
    </div>
    <table cellspacing="1">
        <tr>
            <th>ID</th>
            <th>图书名称</th>
            <th>价格</th>
            <th>数量</th>
            <th>作者</th>
            <th>修改数量</th>
        </tr>
        <%
            // 获取图书信息集合
            List<Book> list = (List<Book>) request.getAttribute("list");
            // 判断集合是否有效
            if (list == null || list.size() < 1) {
                out.print("<tr><td  colspan=‘5‘>没有任何图书信息!</td></tr>");
            } else {
                // 遍历图书集合中的数据
                for (Book book : list) {
        %>
        <tr >
            <td><%=book.getId()%></td>
            <td><%=book.getName()%></td>
            <td><%=book.getPrice()%></td>
            <td><%=book.getBookCount()%></td>
            <td><%=book.getAuthor()%></td>
            <td>
            <!-- 在表单中加上onsubmit="return false;"可以阻止表单提交。 -->
                <form action="UpdateServlet" method="post" onsubmit="return check(this);">
                    <input type="hidden" name="id" value="<%=book.getId()%>">
                    <input type="text" name="bookCount" size="3">
                    <input type="submit" value="修 改">
                </form>
            </td>
        </tr>
        <%
            }
        }
        %>
    </table>
</body>
</html>

UpdateServlet.java

//package com.jdbc.servlet;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.jdbc.db.DBUtil;

/**
 * Title: UpdateServlet
 * Description: Servlet实现类UpdateServlet
 * @author Peng
 * @date 下午3:55:35
 */
@WebServlet("/UpdateServlet")   //配置Servlet
public class UpdateServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    public UpdateServlet() {
        super();
    }

    /**
     * 处理POST请求
     */
    protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        int id = Integer.valueOf(request.getParameter("id"));
        int bookCount = Integer.valueOf(request.getParameter("bookCount"));
        try {
            // 创建Connection连接
            Connection conn = DBUtil.getConn();
            String sql = "update tb_book set bookcount=? where id=?";// 更新SQL语句
            PreparedStatement ps = conn.prepareStatement(sql);// 获取PreparedStatement
            ps.setInt(1, bookCount); // 对SQL语句中的第一个参数赋值
            ps.setInt(2, id); // 对SQL语句中的第二个参数赋值
            ps.executeUpdate(); // 执行更新操作
            ps.close(); // 关闭PreparedStatement
            //conn.close();不能关闭Connection
        } catch (Exception e) {
            e.printStackTrace();
        }
        response.sendRedirect("FindServlet"); // 重定向到FindServlet
    }
}

4 删除数据

DELETE FROM <table_name>[WHERE <search condition>]

增加了修改一栏 和 DeteServlet

bookList.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.*"%>
<%@ page import="com.jdbc.model.Book"%>
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>显示图书列表</title>
<style type="text/css">
tr {
    height:30px;
}
</style>
<script type="text/javascript">
    function check(form){
        if(form.bookCount.value == ""){
            alert("请输入更新数量!");
            form.bookCount.focus();
            return false;
        }
        if(isNaN(form.bookCount.value)){
            alert("格式错误!");
            form.bookCount.focus();
            return false;
        }
        return true;;
    }
    function deleteone(form){
        var r=confirm("确认删除id为"+form.id.value+"的数据吗?");
        return r;
    }
</script>
<style type="text/css">
td,th {
    padding: 5px;
    background-color: #FFFFFF;
}
div{
    width: 98%;
    text-align: center;
}
table{
    width:98%;
    background-color: #666666;

}
tr{
    text-align: center;
}
</style>
</head>
<body>
    <div>
        <h2>所有图书信息</h2>
    </div>
    <table cellspacing="1">
        <tr>
            <th>ID</th>
            <th>图书名称</th>
            <th>价格</th>
            <th>数量</th>
            <th>作者</th>
            <th>修改数量</th>
            <th>删除</th>
        </tr>
        <%
            // 获取图书信息集合
            List<Book> list = (List<Book>) request.getAttribute("list");
            // 判断集合是否有效
            if (list == null || list.size() < 1) {
                out.print("<tr><td  colspan=‘5‘>没有任何图书信息!</td></tr>");
            } else {
                // 遍历图书集合中的数据
                for (Book book : list) {
        %>
        <tr >
            <td><%=book.getId()%></td>
            <td><%=book.getName()%></td>
            <td><%=book.getPrice()%></td>
            <td><%=book.getBookCount()%></td>
            <td><%=book.getAuthor()%></td>
            <td>
            <!-- 在表单中加上onsubmit="return false;"可以阻止表单提交。 -->
                <form action="UpdateServlet" method="post" onsubmit="return check(this);">
                    <input type="hidden" name="id" value="<%=book.getId()%>">
                    <input type="text" name="bookCount" size="3">
                    <input type="submit" value="修 改">
                </form>
            </td>
            <td>
                <form action="DeleteServlet" method="post" onsubmit="return deleteone(this);" >
                <input type="hidden" name="id" value="<%=book.getId()%>">
                <input type="submit" value="删   除">
                </form>
            </td>
        </tr>
        <%
            }
        }
        %>
    </table>
</body>
</html>

DeleteServlet.java

//package com.jdbc.servlet;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.jdbc.db.DBUtil;
/**
 * Title: DeleteServlet
 * Description: 删除一行的数据
 * @author Peng
 * @date 下午4:29:57
 */
@WebServlet("/DeleteServlet")   //配置Servlet
public class DeleteServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    public DeleteServlet() {
        super();
    }

    /**
     * 处理POST请求
     */
    protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        int id = Integer.valueOf(request.getParameter("id"));
        try {
            // 创建Connection连接
            Connection conn = DBUtil.getConn();
            String sql = "DELETE FROM tb_book where id=?";// 更新SQL语句
            PreparedStatement ps = conn.prepareStatement(sql);// 获取PreparedStatement
            ps.setInt(1, id); // 对SQL语句中的第一个参数赋值
            ps.executeUpdate(); // 执行更新操作
            ps.close(); // 关闭PreparedStatement
            //conn.close();不能关闭Connection
        } catch (Exception e) {
            e.printStackTrace();
        }
        response.sendRedirect("FindServlet"); // 重定向到FindServlet
    }
}

5 批处理

新建一个 db_student 数据库来测试

主要是这两句,每次的sql语句,存起来,一起提交而已

ps.addBatch()

ps.executeBatch()

这里的Batch.java 居然不用遵守JavaBean类的规范,可以通过动作标识来引用

DROP TABLE IF EXISTS `tb_student`;
CREATE TABLE `tb_student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) DEFAULT NULL,
  `sex` tinyint(4) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;

Batch.java

//package com.mingrisoft;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Random;

public class Batch {
    /**
     * 获取数据库连接
     *
     * @return Connection对象
     */
    public Connection getConnection() {
        Connection conn = null; // 数据库连接
        try {
            Class.forName("com.mysql.jdbc.Driver"); // 加载数据库驱动,注册到驱动管理器
            // 数据库连接字符串
            String url = "jdbc:mysql://localhost:3306/db_student";
            String username = "root"; // 数据库用户名
            String password = "root"; // 数据库密码
            // 创建Connection连接
            conn = DriverManager.getConnection(url, username, password);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn; // 返回数据库连接
    }

    /**
     * 批量添加数据
     *
     * @return 所影响的行数
     */
    public int saveBatch() {
        int row = 0; // 行数
        Connection conn = getConnection(); // 获取数据库连接
        try {
            // 插入数据的SQL语句
            String sql = "insert into tb_student(name,sex,age)  values(?,?,?)";
            // 创建PreparedStatement
            PreparedStatement ps = conn.prepareStatement(sql);
            Random random = new Random(); // 实例化Random
            for (int i = 0; i < 10; i++) { // 循环添加数据
                ps.setString(1, "学生" + i); // 对SQL语句中的第1个参数赋值
                // 对SQL语句中的第2个参数赋值
                ps.setBoolean(2, i % 2 == 0 ? true : false);
                ps.setInt(3, random.nextInt(5) + 10); // 对SQL语句中的第3个参数赋值
                ps.addBatch(); // 添加批处理命令
            }
            int[] rows = ps.executeBatch(); // 执行批处理操作并返回计数组成的数组
            row = rows.length; // 对行数赋值
            ps.close(); // 关闭PreparedStatement
            conn.close(); // 关闭Connection
        } catch (Exception e) {
            e.printStackTrace();
        }
        return row; // 返回添加的行数
    }

}

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<jsp:useBean id="batch" class="com.mingrisoft.Batch"></jsp:useBean>
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>首页</title>
</head>
<body>
<%
    // 执行批量插入操作
    int row = batch.saveBatch();
    out.print("批量插入了【" + row + "】条数据!");
%>
</body>
</html>

6 调用存储过程

如何创建存储过程看这里:http://blog.csdn.net/peng_hong_fu/article/details/52737402

存储过程findAllBook()

新建一个servlet FindServlet2,让 indexCha.jsp 调用FindServlet2 而不是FindServlet。

存储过程就是存放在数据库上的 SQL 语句,调用的时候,数据库查询返回结果。

CallableStatement cs = conn.prepareCall("call findAllBook()");

引入sql包import java.sql.CallableStatement;

BEGIN
    SELECT * FROM tb_book ORDER BY id DESC;
END

调用输入参数的存储过程,输出参数的存储过程,看我的这篇:http://blog.csdn.net/peng_hong_fu/article/details/52742846#t12

FindServlet2.java

//package com.jdbc.servlet;

import java.io.IOException;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.jdbc.db.DBUtil;
import com.jdbc.model.Book;

/**
 * Title: FindServlet
 * Description: Servlet实现类FindServlet2
 * @author Peng
 * @date 上午11:11:40
 */
@WebServlet("/FindServlet2") // 配置Servlet
public class FindServlet2 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public FindServlet2() {
        super();
    }

    /**
     * 执行POST请求的方法
     */
    protected void doPostt(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

    /**
     * 执行GET请求的方法
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        try {
            // 创建Connection连接
            Connection conn = DBUtil.getConn();
            CallableStatement cs = conn.prepareCall("call findAllBook()");
            ResultSet rs = cs.executeQuery(); // 执行查询
            List<Book> list = new ArrayList<>(); // 实例化List对象
            while (rs.next()) { // 光标向后移动,并判断是否有效
                Book book = new Book(); // 实例化Book对象
                book.setId(rs.getInt("id")); // 对id属性赋值
                book.setName(rs.getString("name")); // 对name属性赋值
                book.setPrice(rs.getDouble("price")); // 对price属性赋值
                book.setBookCount(rs.getInt("bookCount")); // 对bookCount属性赋值
                book.setAuthor(rs.getString("author")); // 对author属性赋值
                list.add(book); // 将图书对象添加到集合中
            }
            request.setAttribute("list", list); // 将图书集合放置到request中
            rs.close(); // 关闭ResultSet
            cs.close(); // 关闭CallableStatement
            //conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        // 请求转发到bookList.jsp
        request.getRequestDispatcher("bookList.jsp").forward(request, response);
    }
}
时间: 2024-10-06 03:23:33

JDBC简介,MySQL连接,PreparedStatement 预处理命令,通配符的相关文章

十三周四次课 更改root密码、mysql连接、常用命令

设置更改root密码 这里我们需要注意的是mysql的root用户和系统的root用户不是一回事.默认情况下mysql的root用户是空的,这样很不安全,所以我们要给他设置一个密码.要想更改mysql的root密码,首先我们输入一条命令[[email protected] ~]# mysql -uroot-bash: mysql: 未找到命令但是系统提示我们没有找到这条命令,这是因为这条命令要在/usr/local/mysql/bin/下才能生效,所以,我们要先将/usr/local/mysql

java jdbc 与mysql连接的基本步骤

Java与mysql链接的基本步骤: 第一步:注册驱动 方法一: [java] view plain copy DriverManager.registerDriver(new com.mysql.jdbc.Driver()); 方法二:设置属性 [java] view plain copy System.setProperty("jdbc.drivers", "com.mysql.jdbc.Driver"); 方法三: [java] view plain copy

网络协议 finally{ return问题 注入问题 jdbc注册驱动问题 PreparedStatement 连接池目的 1.2.1DBCP连接池 C3P0连接池 MYSQL两种方式进行实物管理 JDBC事务 DBUtils事务 ThreadLocal 事务特性 并发访问 隔离级别

1.1.1 API详解:注册驱动 DriverManager.registerDriver(new com.mysql.jdbc.Driver());不建议使用 原因有2个: >导致驱动被注册2次. >强烈依赖数据库的驱动jar 解决办法: Class.forName("com.mysql.jdbc.Driver"); 1.1.2 API详解:java.sql.Statement接口: 操作sql语句,并返回相应结果 String sql = "某SQL语句&qu

shell命令批量杀死MySQL连接进程

(1)将所有的MySQL连接进程杀掉 for i in `mysql -uroot -pzhangyun -Bse "show processlist" | grep -v "show processlist" | awk '{print $1}'` do mysql -uroot -pzhangyun -e "kill $i" done 注:这里将自身命令的show processlist进程过滤掉 (2)删除指定用户的连接进程 for i i

eclipse下jdbc数据源与连接池的配置及功能简介

今天在做四则运算网页版的时候遇到了一个困惑,由于需要把每个产生的式子存进 数据库,所以就需要很多次重复的加载驱动,建立连接等操作,这样一方面写程序不方便,加大了程序量,另一方面,还有导致数据库的性能急剧下降,那么怎么解决这个问题呢? 我所学到的方法就是通过JDBC数据源和连接池的方式来解决这个问题.利用DataSource来建立数据库的连接不需要加载JDBC驱动,也不需要DriverManager类,通过向一个JNDI服务器查询来得到DataSource对象,然后调用DataSource对象的g

JDBC入门之一--连接Mysql实验

工具:mysql-connector-java-5.1.40.eclipse 1)首先要将mysql-connector-java包整合到eclipse中,右击项目,然后选择build path,出现如此,然后OK就可以了! 2)创建一个测试类,测试连接,代码如下 1 import java.sql. 2 //Connection这个类在Mysql-connector-java中也有,但是我们是在java虚拟机中跑的,所以用的是java.sql包中的内容.   1 import java.sql

mysql的设置更改root密码、连接、常用命令

13.1 设置更改root密码 更改环境变量PATH ,增加mysql绝对路径首次直接使用mysql会提示'该命令不存在',原因是还没有将该命令加入环境变量,如果要使用该命令,需要使用其绝对路径:/usr/local/mysql/bin/mysql,为了方便,先将其加入系统环境变量: [[email protected] ~]# export PATH=$PATH:/usr/local/mysql/bin/ mysql命令路径暂时加入环境变量,系统重启后该变量会失效,若要永久生效,需要将其加入环

JDBC简介

JDBC简介: JDBC全称为java database connectivity,是sun公司指定的java数据库连接技术的简称. 他是sun公司和数据库开发商共同开发出来的独立于DBMS的应用程序接口,它为java程序员进行数据库编程提供了统一的API. JDBC实际上有两组API,一组面向java应用程序开发人员,另一组是面向数据库驱动程序开发人员的,一般都是数据驱动程序开发人员利用后面一组API开发出供应程序开发人员使用的API. 我们需要熟悉包java.sql.*中定义的类(class

JDBC—01—JDBC简介;JDBC常用接口与类;

一. JDBC 简介 1 什么是 JDBC JDBC(Java DataBase Connectivity)java 数据库连接 是 JavaEE 平台下的技术规范 定义了在 Java 语言中连接数据,执行 SQL 语句的标准(标准即是接口:) 可以为多种关系数据库提供统一访问 2 什么是数据库驱动程序 数据库厂商对 JDBC 规范的具体实现,是接口的实现类: 不同数据产品的数据库驱动名字有差异 在程序中需要依赖数据库驱动来完成对数据库的操作 3 程序操作数据库流程 定义了在 Java 语言中连