目录
8.1 MySQL数据库管理系统
MySQL数据库管理系统,简称MySQL,是目前流行的开源数据库管理系统,其社区版(MySQL Community Edition)是可免费下载的开源数据库管理系统。MySQL最初由瑞典MySQL AB公司开发,目前由Oracle公司负责源代码的维护和升级。Oracle将MySQL分为社区版和商业版,并保留MySQL开放源码这一特点。目前许多Web开发项目都选用社区版MySQL,其主要原因是社区版MySQL的性能卓越,满足许多Web应用已经绰绰有余,而且社区版MySQL是开源数据库管理系统,可以降低软件的开发和使用成本。
8.1.2 启动MySQL数据库服务器
1.启动
初始化后,必须用管理员身份(在cmd.exe上单击鼠标右键,选择以管理员身份运行cmd)启动命令行窗口,然后进入MySQL安装目录的bin子目录下键入mysqld或 mysqld -nt ,回车确认启动MySQL数据库服务器(以后再启动MySQL就不要再初始化了,以免引起系统混乱),MySQL服务器占用的端口是3306(3306是MySQL服务器默认使用的端口号)。启动成功后(无任何提示信息),MySQL数据库服务器将占用当前MS-DOS窗口
2.root用户
MySQL8.0版本必须对root用户进行身份确认,否则将导致MySQL 8.0自带的mysql客户端程序,以及其他的客户端程序,如Navicat for MySQL等无法访问MySQL 8.0数据库服务器。 再用管理员身份打开另一个命令行窗口(在cmd.exe上单击鼠标右键,选择以管理员身份运行cmd)
8.1.3 MySQL客户端管理工具
所谓MySQL客户端管理工具,就是专门让客户端在MySQL服务器上建立数据库的软件。
1.命令行客户端
打开一个新的命令行窗口(不必管理员身份),进入MySQL安装目录下的bin子目录。运行mysql:
mysql -h ip -u root -p
启动命令行客户端后就可以使用SQL语句进行创建数据库、建表等操作。在MS-DOS命令行窗口输入SQL语句需要用“;”号结束,在编辑SQL语句的过程中可以使用\c终止当前SQL语句的编辑。需要提醒的是,可以把一个完整的SQL语句命令分成几行来输入,最后用分号作结束标志即可。
2. 创建数据库
create database bookDatabase;
删除已有数据库:
drop database bookDatabase;
3.建表
为了在数据库中创建表,必须首先进入该数据库(即使用数据库),命令格式是:“user 数据库名;”或“user 数据库名”。在当前命令行客户端管理工具占用的命令行窗口输入: use bookDatabase
创建bookList表:
create table bookList(
ISBN varchar(100) not null,
name varchar(100) character set gb2312,
price float,
publishDate date,
primary key(ISBN)
);
创建bookList表之后就可以使用SQL语句对bookList表进行添加、更新和查询等操作(如果已经退出数据库,需要再次进入数据库)。在当前命令行客户端占用的窗口键入插入记录的SQL语句(,记录之间用逗号分隔:
insert into bookList values('7302014655','高等数学',28.67,'2020-12-10'),
('7352014658','大学英语',58.5,'1999-9-10'),
('7987302464259','Java2实用教程第5版',59.5,'2017-5-1');
4.导入.sql文件中的SQL语句
在使用命令行客户端时,如果觉得在命令行输入SQL语句不方便,那么可以事先将需要的SQL语句保存在一个扩展名是.sql的文本文件中,然后在命令行客户端占用的命令行窗口使用source命令导入.sql文件中的SQL语句。
5. 删除数据库或表
删除数据库的命令:drop database <数据库名>,例如:删除名为tiger的数据库:
drop database tiger;
删除表的命令:drop table <表名>,例如,使用bookDatabase数据库后,执行:
drop table booklist;
8.2 连接MySQL数据库
为了使Java编写的程序不依赖于具体的数据库,Java提供了专门用于操作数据库的API,即JDBC(Java Data Base Connectivity)。JDBC操作不同的数据库仅仅是加载的数据库连接器不同以及和数据库建立连接的方式不同而已,使用JDBC的应用程序和数据库建立连接之后,就可以使用JDBC提供的API操作数据库。
加载JDBC-MySQL数据库连接器:
try{ Class.forName("com.mysql.cj.jdbc.Driver ");
}
catch(Exception e){}
DBC操作不同的数据库仅仅是加载的数据库连接器不同以及和数据库建立连接的方式不同而已,使用JDBC的应用程序和数据库建立连接之后,就可以使用JDBC提供的API操作数据库.
3.连接数据库
Connection con;
String url =
"jdbc:mysql://192.168.100.1:3306/bookDatabase?useSSL=false&serverTimezone=GMT";
String user ="root";
String password ="";
try{
con = DriverManager.getConnection(url,user,password); //连接代码
}
catch(SQLException e){
System.out.println(e);
}
需要特别注意的是,如果数据库的表中的记录有汉字,那么在建立连接时需要额外多传递一个参数characterEncoding,并取值gb2312或utf-8
8.3 查询记录
和数据库建立连接后,就可以使用JDBC提供的API与数据库交互信息,比如查询、修改和更新数据库中的表等。JDBC与数据库表进行交互的主要方式是使用SQL语句)。JDBC提供的API可以将标准的SQL语句发送给数据库,实现和数据库的交互。
8.3.1 结果集与查询
对一个数据库中的表进行查询,然后将查询结果返回到一个ResultSet对象中,习惯称ResultSet对象为结果集对象。SQL查询语句与结果集 连接对象con调用方法createStatement()返回SQL语句对象,代码如下:
try{ Statement sql=con.createStatement();
}
catch(SQLException e ){
System.out.println(e);
}
无论列(字段)是何种属性,总可以使用getString(int columnIndex)或getString(String columnName)方法返回列(字段)值的串表示。
8.3.2 随机查询
默认的ResultSet结果集使用next()方法顺序地查询记录,但有时候需要在结果集中前后移动、显示结果集指定的一条(一行)记录或随机显示若干条记录等。这时,必须返回一个可滚动的结果集(结果集的游标可以上下移动)。
Statement stmt=con.createStatement(int type,int concurrency);
ResultSet re=stmt.executeQuery(SQL语句);
type:
ResultSet.TYPE_FORWORD_ONLY
ResultSet.TYPE_SCROLL_INSENSITIVE:结果集的游标可以上下移动,当数据库变化时,当前结果集不变。
ResultSet.TYPE_SCROLL_SENSITIVE:结果集的游标可以上下移动,当数据库变化时,当前结果集同步改变。
Concurrency:
ResultSet.CONCUR_READ_ONLY:不能用结果集更新数据库中的表。
ResultSet.CONCUR_UPDATABLE:能用结果集更新数据库中的表。
8.3.3 条件查询
1. where子语句
在SQL语句中,WHERE子句用于筛选符合条件的记录。可以在WHERE子句中使用条件运算符(如等于、大于、小于等)来指定条件。WHERE子句的语法如下:
SELECT column1, column2, ... FROM table_name WHERE condition;
其中,condition是条件语句,可以使用AND、OR、NOT等逻辑运算符组合多个条件。例如:
SELECT * FROM employees WHERE age > 30 AND gender = 'female';
以上语句会返回所有年龄大于30且性别为女性的员工记录。
2. 排序
用order by子语句对记录排序,
select * from 表名 order by 字段名(列名)
select * from 表名 where 条件 order by 字段名(列名)
8.4 更新、添加与删除记录
1.更新
update 表 set 字段 = 新值 where <条件子句>
2.添加
insert into 表(字段列表) values (对应的具体的记录)
或
insert into 表 values (对应的具体的记录)
3.删除
delete from 表名 where <条件子句>
8.5 用结果集操作数据库中的表
1.更新记录
(1)游标移动到第n行: rs.absolute(n);
(2)结果集rs将第n行的column列的列值更新。 rs.updateDate(int column, Date x);
(3)更新数据库中的表。最后,结果集rs调用updateRow()方法用结果集中的第n行更新数据库表中的第n行记录。 rs.updateRow();
2.插入记录
(1)将结果集rs的游标移动到插入行。 rs.moveToInsertRow();
(2)更新插入行的列值。设置插入行的列值: rs.updateString(1, "7307014659"); rs.updateString(2, "数据结构"); rs.updateFloat(3,58); rs.updateDate(4, '2020-08-10');
(3) 最后,结果集调用insertRow()方法用结果集中的插入行向数据库表中插入一行新记录: rs.insertRow()
8.6 预处理语句
Java提供了更高效率的数据库操作机制,就是PreparedStatement对象。
8.6.1 预处理语句优点
减轻数据库的负担,也提高了访问数据库的速度。
1. Connection连接对象con调用prepareStatement(String sql)方法: PreparedStatement pre=con.prepareStatement(String sql); 对参数sql指定的SQL语句进行预编译处理,生成该数据库底层的内部命令,并将该命令封装在PreparedStatement对象pre中。
2. pre对象调用下列方法都可以使得该底层内部命令被数据库执行: ResultSet executeQuery() boolean execute() (执行成功返回false) int executeUpdate() (执行成功返回1) 只要编译好了PreparedStatement对象pre,那么pre可以随时执行上述方法,显然提高了访问数据库的速度
8.6.2 使用通配符
在对SQL进行预处理时可以使用通配符?(英文问号)来代替字段的值,只要在预处理语句执行之前再设置通配符所表示的具体值即可
pre=con.prepareStatement("SELECT * FROM bookList WHERE price < ? ");
在sql对象执行之前,必须调用相应的方法设置通配符?代表的具体值,
8.7 事务
1.事务
事务由一组SQL语句组成。所谓“事务处理”是指应用程序保证事务中的SQL语句要么全部都执行,要么一个都不执行。
2.事务处理
事务处理是保证数据库中数据完整性与一致性的重要机制。应用程序和数据库建立连接之后,可能使用多条SQL语句操作数据库中的一个表或多个表。一个管理资金转账的应用程序为了完成一个简单的转账业务可能需要两条SQL语句,比如,有户geng给另一个用户zhang转帐50元,那么需要一条SQL语句完成将用户geng的userMoney的值由原来的100更改为50(减去50的操作),另一条SQL语句完成将zhang的用户的userMoney的值由原来的20更新为70(增加50的操作)。应用程序必须保证这两条SQL语句要么全都执行,要么全都不执行。
3.事务处理步骤
1)用setAutoCommit(booean b)方法关闭自动提交模式
con.setAutoCommit(false);
2)用commit()方法处理事务
con.commit()
; Statement对象(PreparedStatement对象)提交多个SQL语句,这些SQL语句就是一个事务。事务中的SQL语句不会立刻生效,直到连接con调用commit()方法。
3)用rollback()方法处理事务失败
con.rollback()
; 连接con调用commit()方法进行事务处理时,只要事务中任何一个SQL语句没有生效,就抛出SQLException异常。在处理SQLException异常时,必须让con调用rollback()方法,其作用是:撤消事务中成功执行过的SQL语句对数据库数据所做的更新、插入或删除操作,即撤消引起数据发生变化的SQL语句操作,将数据库中的数据恢复到commit()方法执行之前的状态。
8.8 分页显示记录
可以使用二维数组table存放表的记录,即用二维数组table中的行(一维数组table[i])存放一条记录。 如果一个表中有许多记录,那么二维数组table就有多行。 为避免长时间占用数据库的连接,应当将全部记录存放到二维数组中,然后关闭数据库连接。 假设table存放了m行记录,准备每页显示n行,那么,总页数的计算公式是:
●如果m除以n的余数大于0,总页数等于m除以n的商加1;
●如果m除以n的余数等于0,总页数等于m除以n的商。
即 总页数=(m%n)==0?(m/n):(m/n+1); 如果准备显示第p页的内容,应当从table第(p-1)*n行开始,连续输出n行(最后一页可能不足n行)。
1.bean(模型)
bean的id是recordList,是session bean,用于存储从数据库的表中查询到的记录。 用命令行进入save\data的父目录classes,编译Record_Bean.java(见本章开始的约定):
classes> javac save\data\BookList_Bean.java
2.JSP页面(视图)
视图部分由两个JSP页面构成,其中example8_8_input.jsp页面负责提供输入数据的视图,即用户可以在该页面输入数据库的名、表名、密码等信息,然后提交给名字是query的servlet。query负责查询数据库,并将结果存储到id为recordBean的session bean中,然后请求视图中的example8_8_show.jsp页面显示recordBean的数据(分页显示)。
3.servlet(控制器)
Servlet是Java Web开发中的一种服务器端组件,用于处理客户端请求并返回响应。Servlet通常被称为控制器(Controller),因为它们用于控制Web应用程序的行为。
Servlet是Java编写的,它们可以在支持Servlet规范的Web服务器上运行。Servlet可以通过Java类来实现,它们的主要任务是处理HTTP请求和响应,包括读取请求参数、执行业务逻辑、生成响应内容等。
Servlet通常被用作Web应用程序的中央控制器,它们接收客户端请求并将其传递给适当的业务逻辑组件进行处理。Servlet还可以处理会话管理、安全性、错误处理等方面的任务。
Servlet可以使用Java Servlet API来开发,该API提供了处理HTTP请求和响应的标准接口。Servlet还可以使用JavaServer Pages(JSP)技术来生成动态Web页面。
4.web.xml(部署文件)
web.xml(也称为部署描述符)是Java Web应用程序的配置文件,它位于Web应用程序的WEB-INF目录下,用于提供有关Web应用程序的配置信息。Web容器(如Tomcat)会在部署Web应用程序时读取web.xml文件并根据其中的配置进行相关行为的设置和管理。
web.xml文件中包含了以下一些常用的配置信息:
1. Servlet的映射信息:可以指定URL模式、Servlet的类名、Servlet的初始化参数等信息。
2. 过滤器的映射信息:可以指定URL模式、过滤器的类名、过滤器的初始化参数等信息。
3. 错误页面的映射信息:可以指定错误码(如404、500等)、异常类型、错误页面的URL等信息。
4. 上下文参数的配置: 可以配置应用的一些自定义参数,并且可以在servlet和jsp页面中使用getServletContext().getInitParameter(paramName)获取。
5. Session配置: 可以配置Session超时时间、Session Cookie的名称等。
6. 安全权限配置:可以配置安全策略、角色名称、用户信息等。
7. Welcome File List配置:可以指定默认的访问页面,一般是index.html 或 index.jsp
8. Listener: 可以配置监听器,用于在Web应用程序的生命周期(如容器启动和关闭、Session创建和销毁等)中执行一些操作。
通过web.xml文件,我们可以为Web应用程序提供多种不同类型的配置,帮助Web应用程序更好地运行和管理。
总结:
在JSP中使用数据库时,可以将上述代码放在JSP页面的Java代码块中,或者将其封装为JavaBean或DAO类,然后在JSP页面中调用。需要注意的是,为了保证安全性和可维护性,应该将数据库连接信息配置在配置文件中,而不是硬编码在代码中。