Java Web之访问数据库

Java Web之访问数据库
write:2022-5-9

前面我们学习了Java Web自定义JSP标签:Java Web之自定义JSP标签。本文介绍在Java Web中访问数据库的方法,我们通过一个范例来进行讲解,并将前面所涉及的知识点进行融合应用。

1. 安装和配置MySQL数据库服务器

获取MySQL的安装软件。从http://www.mysql.com站点下载MySQL的安装软件和JDBC驱动程序的类库文件。
MySQL安装后(网络上安装教程就有很多),在MySQL安装目录的bin目录下有一个mysql.exe程序,它是MySQL的客户程序。运行它,得到一个命令行界面:
在这里插入图片描述
修改root账户的口令
(1)在DOS命令行输入命令: mysql, 进入MySQL客户程序。
(2)进入mysq|数据库,SQL命 令为: use mysq|。
(3)为root用户重新设置口令,新的口令为: 1234。
SQL命令如下: update USER set PASSWORD=password(‘1234’) where USER='root; flush privileges;
(4)退出mysq|客户程序,SQL命令为: exit。

创建数据库BookDB
(1)在DOS命令行输入命令: nysql, 进入MySQL客户程序。
(2)创建数据库BookDB, SQL命令 如下: create database BookDB;
(3)进入BookDB数据库,SQL命令 为: use BookDB
(4)在BookDB数据库中创建BOOKS表,SQL命令如下:
create table BOOKS(
ID varchar(8) primary key,
NAME varchar(24),
TITLE varchar(96),
PRICE float,
YR int,
DESCRIPTION varchar(128),
SALE_ AMOUNT int);
(5)在BOOKS表中加入一-些记录,SQL命令如下:
insert into BOOKS values(201’, '孙卫琴,‘Java面向对象编程’,65, 2006, ‘让读者由浅入深掌握Java语言’, 20000);

2. JDBC API简介

JDBC是Java DataBase Connectivity(java数据库连接器)的缩写。
JDBC是连接Java程序和数据库服务器的纽带。
在这里插入图片描述

2.1 java.sq|包中的接口和类

Driver接口和DriverManager类:前者表示驱动程序,后者表示驱动程序管理器
Connection接口:表示数据库连接。
Statement接口:负责执行SQL语句。
PreparedStatement接口:负责执行预准备的SQL语句。
ResultSet接口:表示SQL查询语句返回的结果集。

2.2 编写访问数据库程序的步骤

(1)获得要访问的数据库的JDBC驱动程序的类库文件,把它放到classpath中。 eg: 项目名/WEB-INF/lib/mysqldriver.jar
(2) 在程序中加载并注册JDBC驱动程序
//加载MySQL Driver类
Class.forName(“com.mysql.jdbc.Driver”);
//注册MySQL Driver
java.sql.DriverManager. registerDriver( new com.mysqL.jdbc.Driver());
(3)建立与数据库的连接:
Connection con =java.sql.DriverManager .getConnection( dburl,user,password);//连接数据库的url地址,用户名,密码
对于MySQL数据库连接,采用如下URL形式:
jdbc:mysql(指mysql数据库)😕/hostname(主机名):port(端口号)/databasename(数据库名)
在本例中:jdbc:mysql://localhost: 8080/BookDB;
(4)创建Statement对象, 准备执行SQL语句:Statement stmt = con.createStatement();
(5)执行SQL语句:
String sql=" select ID,NAME,TITLE,PRICE from
BOOKS where NAME= ‘Tom’ and PRICE=40";
ResultSet rs=stmt.executeQuery(sq);
(6)访问ResultSet中的记录集
while (rs.next()){
String col1 = rs.getString(1); //访问某条记录里的第一个字段,是String类型,所以用getString()
String col2 = rs.getString(2);
String col3 = rs.getString(3);
float col4 = rs.getFloat(4); //访问某条记录里的第四个字段,是float类型,所以用getFloat()
//打印当前记录
System.out…println(“ID=” +col1 +" NAME=" +col2+’
TITLE= “+col3+” PRICE= "+Col4);
}
(7)访问数据库结束,依次关闭ResultSet、Statement和Connection对象:
rs.close( );
stmt.close( );
con.close();

2.3 创建Statement对象

Connection创建Statement的方式有如下3种:
createStatement():创建基本的Statement对象;
prepareStatement():创建PreparedStatement对象;
prepareCall():创建CallableStatement对象;

(1)Statement接口
Statement接口提供了三个执行SQL语句的方法:
■execute(String sql):执行各种SQL语句。该方法返回一个boolean类型的值,如果为true,表示所执行的SQL语句具有查询结果,可通过Statement的getResultSet()方法获得这一查 询结果
■executeUpdate(String sql):执行SQL的insert、update和delete语句。该方法返回一个int类型的值,表示数据库中受该SQL语句影响的记录的数目
■executeQuery(String sql):执行SQL的select语 句。该方法返回一个表示查询结果的ResultSet对象。

(2)PreparedStatement接口
■PreparedStatement接口继承了Statement接口,所以也具有上面三个方法。
■PreparedStatement用来执行预准备的SQL语句。

什么叫做预准备的SQL语句呢,看一个例子:
在访问数据库时,可能会遇到这样的情况,某条SQL语句被多次执行,仅仅其中的参数不同,例如:
select ID,NAME,TITLE,PRICE from BOOKS where NAME=‘Tom’ and PRICE=40
select ID,NAME,TITLE,PRICE from BOOKS where NAME=‘Mike’ and PRICE=30
select ID,NAME,TITLE,PRICE from BOOKS where NAME=‘Jack’ and PRICE= 50
以上SQL语句的格式为 : select ID,NAME,TITLE,PRICE from BOOKS where NAME=? and PRICE=? 这种形式的SQL语句叫做预准备的SQL语句(格式确定,参数会变)

■在这种情况下,使用PreparedStatement,而不是Statement来执行SQL语句,具有以下优点:
简化程序代码。
提高访问数据库的性能。PreparedStatement执行预准备的SQL语句,数据库只需对这种SQL语句编译一次, 然后就可以多次执行。而每次用Statement来执行SQL语句时,数据库都需要对该SQL语句进行编译。

eg:

String selectStatement = "select ID,NAME,TITLE,PRICE from BOOKS where NAME = ? and PRICE= ?";

//创建PreparedStatement对象
PreparedStatement prepStmt = con.prepareStatement selectStatement);

//调用PreparedStatement的setXXX方法,给参数赋值
String name="Tom;
float price=40;
prepStmt.setString(1, name); //替换SQL语句中的第一个“?”
prepStmt.setFloat(2, price); //替换SQL语句中的第二个“?”

//执行SQL语句
ResultSet rs = prepStmt.executeQuery();

2.4 事务处理

■在数据库操作中,一项事务是指由条或多条操纵数据库的SQL语句所组成的一个不可分割的工作单元。
■只有当事务中的所有操作都正常完成,整个事务才能被提交到数据库:如果有一项操作没有完成,就必须撤销整个事务。

举例:转账事务
例如在银行转账事务中,假定Tom从自己的账号上把100元钱转到Jack的账号上,相关的SQL语句如下:
update ACCOUNT set MONEY = MONEY-100 where NAME= Tom’;
update ACCOUNT set MONEY = MONEY +100 where NAME= Jack’;
在这里插入图片描述
当两个update语句执行完,才成功;

声明事务的API
在Connection接口中提供了3个控制事务的方法:
setAutoCommit( boolean autoCommit):设置是否自动提交事务,默认是true;所谓自动提交事务就是指在此模式下每一条SQL语句都是一个独立的事务,执行完SQL语句,事务也就立即提交;如果不设置为自动模式,就需要手动设置事务开始和提交的边界;
commit():提交事务。
rollback():撤销事务。

eg:

try {
       con = java.sql.DriverManager .getConnection(dbUrI,dbUser ,dbPwd);
       //禁止自动提交
       con.setAutoCommit(false);
       stmt = con.createStatement(;
       //数据库更新操作1
      stmtexecutelUpdate("update ACCOUNT set MONEY=MONEY- 10 where NAME= 'Tom'");
       //数据库更新操作2
        stmtexecuteUpdate("update ACCOUNT set MONEY=MONEY + 100where NAME='Jack'"); 
        con.commit(); //提交事务(上面的两个SQL语句位于同一个事务)
}catch(Exception ex) {
        try{ con.rollback() ;}catch(Exception e){ex .pr intStackTrace();}
}finally{
            try{
                     stmt.close();
                      con.close();
                  } catch(Exception e){
                      e.printStackTrace0;
                   }
}

3. 通过JDBC API访问数据库的范例

dbaccess.jsp:
在这里插入图片描述
在这里插入图片描述
访问结果:
在这里插入图片描述

4. Bookstore应用范例

现在,来开始做一个Bookstore应用:
大致流程图:
在这里插入图片描述
数据库BookDB,里面有一张会访问的BOOKS表:
在这里插入图片描述
bookstore应用的文件清单:
在这里插入图片描述
bookstore应用的对象模型:
在这里插入图片描述
ShoppingCart和ShoppingCartItem:
■例如,某个用户的购物车内包含如下内容:
《Java面向对象编程》两本
《Java网络编程精解》三本
那么在ShoppingCart对象中应该包含两个ShoppingCartItem对象。ShoppingCartItem有两个成员变量:
■Object item; //引|用BookDetails对 象,某本书
■int quantity; //某本书的数量
在这里插入图片描述
访问数据库的BookDB类:
BookDB类负责访问数据库,它提供了操纵数据库的所有方法,包括:
■ public Collection getBooks():从BOOKS表中读取所有书的信息,放在Collection集合中。
■ public int getNumberOfBooks(): 从BOOKS表中获取所有书的销售数里。
■ public BookDetails getBookDetails(String bookId): 根据bookId读取某一本书的详细信息。
■ public void buyBooks( ShoppingCart cart):根据购物车中的内容,更新BOOKS表,该方法调用buyBook(String bookId, int quantity,Connection con)方法,完成实际的SQL操作。
■ public void buyBook( String bookId, int quantity,Connection con):
完成实际购买书的SQL操作,执行的SQL语句为:update, BOOKS set SALE AMOUNT=SALE_ AMOUNT+quantity where ID= bookId;

4. 数据源(DataSource)简介

■在数据源中事先建立了多个数据库连接,这些数据库连接保存在连接池(Connection Pool)中。
■Java程序访问数据库时,只需从连接池中取出空闲状态的数据库连接;当程序访问数据库结束,再将数据库连接放回连接池,这样做可以提高访问数据库的效率,
■javax.sql.DataSource接口表示数据源 方法:DataSource.getConnection()即可得到空闲状态的数据库连接
在这里插入图片描述
通过JNDI API访问数据源
通过javax.naming.Context接口的lookup( )方法来获得数据源的引用,返回DataSource对象
在这里插入图片描述

5. 配置数据源

为了使应用能够访问数据源,需要进行配置;
■在web应用的META-INF\context.xml文 件中加入定义数据源的< Resource>元素;
■在web应用的WEB- INF\web.xm|中加入< resource-ref>元素,该元素声明Web应用引用了特定数据源。

(1)用于定义数据源的context.xml文件
eg:
在这里插入图片描述
< Resource>元素中的每个属性都有特定的用途:
在这里插入图片描述

(2)web.xm|中加入< resource-ref>元素
在这里插入图片描述

6. 程序中访问数据源

在这里插入图片描述
通过上图可以看出,dbaccess1.jsp与dbaccess.jsp的运行结果相同,都是将表中的内容显示出来,但dbaccess1.jsp是通过与数据源连接来获取数据的:
■获得jdbc/BookDB数据源的引用:
Context ctx = new InitialContext( );
DataSource ds=(DataSource )ctx.lookup( “java:comp/env/jdbc/BookDB”);
■通过DataSource的getConnection()方法获得数据库连接对象Connection:
Connection con=ds.getConnection( );
■下面的步骤与JDBC相同了

注意注意注意:访问数据源也要讲数据库驱动文件放到lib目录下

7. 练习题

  1. 问题:以下哪些属于java.sql.DriverManager类的方法?
    选项:
    (A) createStatement()
    (B) getConnection(String url, String user, String pwd)
    © registerDriver(Driver driver)
    (D) execute(String sq|)

答案:BC

  1. 问题:以下哪些属于java.sql.Connection接口的方法?
    选项:
    ■(A) execute(String sq|)
    ■(B) commit()
    ■© createStatement()
    ■(D) getFloat(int columnIndex)

答案:BC

  1. 问题: dbaccess1.jsp范 例通过数据源连接数据库,
    以下哪些说法正确?
    选项:
    (A)数据源由Servlet容器提供。
    (B) dbaccess1.jsp通过JNDI API来得到DataSource对象的引用。
    ©数据源本身的实现不依赖JDBCAPI。
    (D)数据源主要负责为dbaccess1.jsp提供数据库连接。
    (E) DataSource接口位于javax.sql包中。

答案:ABDE

  • 1
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值