Java Web之访问数据库
write:2022-5-9
前面我们学习了Java Web自定义JSP标签:Java Web之自定义JSP标签。本文介绍在Java Web中访问数据库的方法,我们通过一个范例来进行讲解,并将前面所涉及的知识点进行融合应用。
文章目录- 1. 安装和配置MySQL数据库服务器
- 2. JDBC API简介
- 2.1 java.sq|包中的接口和类
- 2.2 编写访问数据库程序的步骤
- 2.3 创建Statement对象
- 2.4 事务处理
- 3. 通过JDBC API访问数据库的范例
- 4. Bookstore应用范例
- 4. 数据源(DataSource)简介
- 5. 配置数据源
- 6. 程序中访问数据源
- 7. 练习题
获取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程序和数据库服务器的纽带。
Driver接口和DriverManager类:前者表示驱动程序,后者表示驱动程序管理器
Connection接口:表示数据库连接。
Statement接口:负责执行SQL语句。
PreparedStatement接口:负责执行预准备的SQL语句。
ResultSet接口:表示SQL查询语句返回的结果集。
(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();
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:
访问结果:
现在,来开始做一个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;
■在数据源中事先建立了多个数据库连接,这些数据库连接保存在连接池(Connection Pool)中。
■Java程序访问数据库时,只需从连接池中取出空闲状态的数据库连接;当程序访问数据库结束,再将数据库连接放回连接池,这样做可以提高访问数据库的效率,
■javax.sql.DataSource接口表示数据源 方法:DataSource.getConnection()即可得到空闲状态的数据库连接
通过JNDI API访问数据源
通过javax.naming.Context接口的lookup( )方法来获得数据源的引用,返回DataSource对象
为了使应用能够访问数据源,需要进行配置;
■在web应用的META-INF\context.xml文 件中加入定义数据源的< Resource>元素;
■在web应用的WEB- INF\web.xm|中加入< resource-ref>元素,该元素声明Web应用引用了特定数据源。
(1)用于定义数据源的context.xml文件
eg:
< Resource>元素中的每个属性都有特定的用途:
(2)web.xm|中加入< resource-ref>元素
通过上图可以看出,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. 练习题- 问题:以下哪些属于java.sql.DriverManager类的方法?
选项:
(A) createStatement()
(B) getConnection(String url, String user, String pwd)
© registerDriver(Driver driver)
(D) execute(String sq|)
答案:BC
- 问题:以下哪些属于java.sql.Connection接口的方法?
选项:
■(A) execute(String sq|)
■(B) commit()
■© createStatement()
■(D) getFloat(int columnIndex)
答案:BC
- 问题: dbaccess1.jsp范 例通过数据源连接数据库,
以下哪些说法正确?
选项:
(A)数据源由Servlet容器提供。
(B) dbaccess1.jsp通过JNDI API来得到DataSource对象的引用。
©数据源本身的实现不依赖JDBCAPI。
(D)数据源主要负责为dbaccess1.jsp提供数据库连接。
(E) DataSource接口位于javax.sql包中。
答案:ABDE
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)