目录
8.9.1连接microsoft sql server数据库
前言
本章主要内容是MySQL数据库管理系统、连接MySQL数据库、查询记录、更新、添加与删除记录、用结果集操作数据库中的表、预处理语句、事务、分页显示记录、连接SQL Server与 Access 数据库和使用连接池。难点是分页显示记录和使用连接池。
8.1mysql数据库管理系统
MySQL数据库管理系统,简称MySQL,是目前流行的开源数据库管理系统,其社区版(MySQL Community Edition)是可免费下载的开源数据库管理系统。MySQL最初由瑞典MySQL AB公司开发,目前由Oracle公司负责源代码的维护和升级。Oracle将MySQL分为社区版和商业版,并保留MySQL开放源码这一特点。目前许多Web开发项目都选用社区版MySQL,其主要原因是社区版MySQL的性能卓越,满足许多Web应用已经绰绰有余,而且社区版MySQL是开源数据库管理系统,可以降低软件的开发和使用成本。
8.1.1连接mysql
为了使Java编写的程序不依赖于具体的数据库,Java提供了专门用于操作数据库的API,即JDBC(Java Data Base Connectivity)。JDBC操作不同的数据库仅仅是加载的数据库连接器不同以及和数据库建立连接的方式不同而已,使用JDBC的应用程序和数据库建立连接之后,就可以使用JDBC提供的API操作数据库。
8.1.2下载jdbc-mysql数据库连接器表
https://dev.mysql.com/downloads/connector/j/
下载的是mysql-connector-java-8.0.18.zip(linux系统可下载tar.gz格式文件),将该zip文件解压至硬盘,在解压目录下的mysql-connector-java-8.0.18.jar
文件就是连接MySQL数据库的JDBC-MySQL数据库连接器(作者也将该文件放在了教学资源的源代码文件夹中)。
- 将MySQL数据库的JDBC-MySQL数据库连接器
mysql-connector-java-8.0.18.jar
保存到Tomcat安装目录下的lib文件夹中(例如D:\apache-tomcat-9.0.26\lib). - 重新启动Tomcat服务器。
8.1.3加载jdbc-mysql数据库连接器
try{ Class.forName("com.mysql.cj.jdbc.Driver ");
}
catch(Exception e){}
-
MySQL数据库驱动是mysql-connector-java-8.0.18.jar文件中的Driver类,该类的包名是com.mysql.cj.jdbc.Driver(包名和以前的版本: com.mysql.jdbc.Driver不同)。Driver类不是Java运行环境类库中的类,是连接器mysql-connector-java-8.0.18.jar中的类
-
JDBC操作不同的数据库仅仅是加载的数据库连接器不同以及和数据库建立连接的方式不同而已,使用JDBC的应用程序和数据库建立连接之后,就可以使用JDBC提供的API操作数据库.
8.1.4连接数据库
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);
}
8.1.5注意汉字问题
需要特别注意的是,如果数据库的表中的记录有汉字,那么在建立连接时需要额外多传递一个参数characterEncoding,并取值gb2312或utf-8
String url =
"jdbc:mysql://localhost/bookDatabase?"+
"useSSL=false&serverTimezone=GMT&characterEncoding=utf-8";
con = DriverManager.getConnection(url, "root","");
8.2连接mysql数据库
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);
}
-
结果集
sql对象就可以调用相应的方法查询数据库中的表,并将查询结果存放在一个ResultSet结果集中。ResultSet结果集由以列(也称字段)为结构的数据行组成。例如,对于 -
ResultSet rs=sql.executeQuery("SELECT * FROM bookList");
内存中的结果集对象rs的列数是4列,刚好和bookList表的列数相同,第1列至第4列分别是ISBN、name、price和publishDate列;而对于
ResultSet rs=sql.executeQuery("SELECT name,price FROM bookList");
结果集对象rs只有两列,第1列是name列,第2列是price列。
-
ResultSet结果集一次只能看到一个数据行,使用next()方法可走到下一数据行。获得一行数据后,ResultSet结果集可以使用getXxx(int columnIndex)或getXxx(String columnName)方法获得字段值(列值)
-
无论列(字段)是何种属性,总可以使用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条件查询
where子语句
一般格式:
select 字段 from 表名 where 条件
(1)字段值和固定值比较,例如:
select name,price from bookList where name='高等数学'
(2)字段值在某个区间范围,例如:
select * from bookList where price>28.68 and price<=87.7
select * from bookList where price>56 and name != '月亮湾'
使用某些特殊的日期函数,如year,month,day:
select * from bookList where year(publishDay)<1980
select * from bookList where year(publishDay) between 2015 and 2020
(3)用操作符like进行模式般配,使用%代替0个或多个字符,用一个下划线_代替一个字符。例如查询name含有“程序”二字的记录:
select * from bookLidt where name like '%程序%'
排序
用order by子语句对记录排序,
select * from 表名 order by 字段名(列名)
select * from 表名 where 条件 order by 字段名(列名)
例如:
select * from bookList order by price
select * from bookList where name like '%编程%' order by name
8.4更新、添加与删除记录
通过参数sqlStatement指定的方式实现对数据库表中记录的更新、添加和删除操作
public int executeUpdate(String sqlStatement);
8.4.1更新
update 表 set 字段 = 新值 where <条件子句>
例如:
sql.executeUpdate
("update bookList set publishDate ='2019-12-26' where name='大学英语'");
8.4.2添加
insert into 表(字段列表) values (对应的具体的记录)
或
insert into 表 values (对应的具体的记录)
insert into bookList values ('2306084657','春天', 35.8,'2020-3-20'),
('5777564629','冬日', 29.9,'2019-12-23')
8.4.3删除
delete from 表名 where <条件子句>
例如:
delete from bookList where ISBN = '9352914657'
8.5用结果集操作数据库中的表
8.5.1更新记录
- 游标移动到第n行:
rs.absolute(n);
- 结果集rs将第n行的column列的列值更新。
rs.updateDate(int column, Date x);
- 更新数据库中的表。最后,结果集rs调用updateRow()方法用结果集中的第n行更新数据库表中的第n行记录。
例如:rs.updateRow();
rs.absolute(3); rs.updateString(2, "操作系统"); rs.updateRow();
8.5.2插入记录
- 将结果集rs的游标移动到插入行。
- 更新插入行的列值。设置插入行的列值:
- 最后,结果集调用insertRow()方法用结果集中的插入行向数据库表中插入一行新记录:
1.rs.moveToInsertRow(); 2.rs.updateString(1, "7307014659"); rs.updateString(2, "数据结构"); rs.updateFloat(3,58); rs.updateDate(4, '2020-08-10'); 3.rs.insertRow();
8.6预处理语句
Java提供了更高效率的数据库操作机制,就是PreparedStatement对象
。
8.6.1预处理语句优点
减轻数据库的负担,也提高了访问数据库的速度。
- 步骤
- Connection连接对象con调用prepareStatement(String sql)方法:
PreparedStatement pre=con.prepareStatement(String sql);
对参数sql指定的SQL语句进行预编译处理,生成该数据库底层的内部命令,并将该命令封装在PreparedStatement对象pre中。 -
- pre对象调用下列方法都可以使得该底层内部命令被数据库执行:
ResultSet executeQuery()
boolean execute() (执行成功返回false)
int executeUpdate() (执行成功返回1)
只要编译好了PreparedStatement对象pre,那么pre可以随时执行上述方法,显然提高了访问数据库的速度。
- pre对象调用下列方法都可以使得该底层内部命令被数据库执行:
8.6.2使用通配符
在对SQL进行预处理时可以使用通配符?(英文问号)来代替字段的值,只要在预处理语句执行之前再设置通配符所表示的具体值即可。例如:
pre=con.prepareStatement("SELECT * FROM bookList WHERE price < ? ");
在sql对象执行之前,必须调用相应的方法设置通配符?代表的具体值,比如:
pre.setFloat(1,65);
指定上述预处理语句pre中通配符?代表的值是65。通配符按照它们在预处理的“SQL语句”中从左至右依次出现的顺序分别被称作第1个、第2个…… 第m个通配符。
8.7事务
事务由一组SQL语句组成。所谓“事务处理”是指应用程序保证事务中的SQL语句要么全部都执行,要么一个都不执行。
8.7.1事务处理
事务处理是保证数据库中数据完整性与一致性的重要机制。应用程序和数据库建立连接之后,可能使用多条SQL语句操作数据库中的一个表或多个表。一个管理资金转账的应用程序为了完成一个简单的转账业务可能需要两条SQL语句,比如,有户geng给另一个用户zhang转帐50元,那么需要一条SQL语句完成将用户geng的userMoney的值由原来的100更改为50(减去50的操作),另一条SQL语句完成将zhang的用户的userMoney的值由原来的20更新为70(增加50的操作)。应用程序必须保证这两条SQL语句要么全都执行,要么全都不执行。
8.7.2事务处理步骤
- 用setAutoCommit(booean b)方法关闭自动提交模式
con.setAutoCommit(false);
- 用commit()方法处理事务
Statement对象(PreparedStatement对象)提交多个SQL语句,这些SQL语句就是一个事务。事务中的SQL语句不会立刻生效,直到连接con调用commit()方法。con.commit();
- 用rollback()方法处理事务失败
连接con调用commit()方法进行事务处理时,只要事务中任何一个SQL语句没有生效,就抛出SQLException异常。在处理SQLException异常时,必须让con调用rollback()方法,其作用是:撤消事务中成功执行过的SQL语句对数据库数据所做的更新、插入或删除操作,即撤消引起数据发生变化的SQL语句操作,将数据库中的数据恢复到commit()方法执行之前的状态。con.rollback();
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行)。
8.9连接sql server与access数据库
8.9.1连接microsoft sql server数据库
- 登录www.micsosoft.com下载Microsoft JDBC Driver 6.0 for SQL Server,即下载sqljdbc_6.0.8112.200_chs.tar.gz。在解压目录的sqljdbc_6.0\chs\jre8子目录中可以找到JDBC-SQLServer连接器:
sqljdbc42.jar
将SQLServer 数据库的JDBC-SQLServer数据库连接器sqljdbc42.jar保存到Tomcat安装目录下的lib文件夹中(例如D:\apache-tomcat-9.0.26\lib),并重新启动Tomcat服务器。
应用程序加载JDBC-SQLServer数据库连接器的代码如下:
try { Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
}
catch(Exception e){
}
- 建立连接
try{ String url= "jdbc:sqlserver://192.168.100.1:1433;DatabaseName=warehouse"; String user="sa"; String password="dog123456"; con=DriverManager.getConnection(url,user,password); } catch(SQLException e){ }
8.9.2连接microsoft access数据库
- 登录:
http://www.hxtt.com/access.zip
下载JDBC-Access连接器。解压下载得access.zip,在解压目录下\lib子目录中的Access_JDBC30.jar就是JDBC-Access连接器,将Access_JDBC30.jar保存到Tomcat安装目录下的lib文件夹中,并重新启动Tomcat服务器。
加载Access数据库连接器程序的代码是:Class.forName("com.hxtt.sql.access.AccessDriver");
- 建立连接
将bookDatabase.accdb数据库保存在启动Tomcat服务器的当前目录下,即Tomcat安装目录的bin中。String path = "./bookDatabase.accdb"; String loginName =""; String password =""; con = DriverManager.getConnection("jdbc:Access://"+path,loginName,password);
8.10使用连接池
8.10.1连接池简介
连接池的思想是,
- 由一个管理者,比如Tomcat服务器,事先建立好若干个连接放在一起(存放在一个实现DataSource接口的对象中),称作一个连接池。
- 当Web应用程序需要连接数据库时,只需到连接池中获得一个Connection对象即可。
- 当Web应用程序不再需要Connection对象时,就让Connection对象调用close()方法,这样就可以把这个Connection对象再返回到连接池中,以便其他Web应用程序使用这个Connection对象。
- 需要注意的是,Tomcat服务器提供的连接池中的Connection对象调用close()方法不会关闭和数据库的TCP连接,其作用仅仅是把Connection对象返回到连接池(这一点和Web应用程序自己创建的Connection对象不同,其原理不必深究)。
- 简单地说,连接池可以让Web应用程序方便地使用Connection对象(用完务必放回),再用再取,节省了创建Connection的时间,提高了Web应用程序访问数据库的效率。。
8.10.2建立连接池
连接池配置文件
context.xml
- name:设置连接池的名字(命名一个喜欢的名字即可),例如gxy,该名字是连接池的id,context.xml文件中,如果有多个Resource标记(一个Resource标记对应一个连接池),必须保证这些Resource标记中的name互不相同,即context.xml文件可以给出多个不同连接池的配置信息。
- type: 设置连接池的类型,这里必须是javax.sql.DataSource
- driverClassName:设置数据库连接器,即数据库驱动的类。
- url:设置连接数据库的URL,注意url要小写。需要注意的是对于url中的 &字符要写成“&”,这是XML文件对特殊字符的一个特殊规定。
- username:给出可以访问数据库的用户名,例如root。
- password :给出访问数据库的密码,比如,root用户的默认密码是无密码。
- maxActive:设置连接池的大小,即连接池中处于活动状态Connection对象的数目。
- maxIdle :设置连接池中可处于空闲状态的Connection对象的最大数目。
- maxWait :设置连接池中没有空闲状态Connection对象可用时,用户请求获得连接池中Connection对象需要等待的最长时间(单位是毫秒)。
使用连接池
步骤如下:
- Context接口
首先创建一个实现Context(上下文)接口的对象:
然后让context去寻找Tomcat服务器曾绑定在运行环境中的另一个Context对象:Context context = new InitialContext();
Context contextNeeded = (Context)context.lookup("java:comp/env");
- 其中的java:comp/env是Tomcat服务器绑定这个Context对象时使用的资源标志符(不可以写错)。
2.得到连接池连接池绑定在Context对象contextNeeded中。绑定用的资源标志符是连接池配置文件context.xml中name给的值,比如gxy。DataSource ds = (DataSource)contextNeeded.lookup("gxy");
- 从连接池中获得连接
(4)将连接返回连接池Connection con = ds.getConnnection();
con.close();
总结
JSP 使用JDBC 提供的 API和数据库进行交互信息。JDBC 技术在数据库开发中占很重要的地位,JDBC 操作不同的数据库仅仅是连接方式上的差异而已,使用JDBC的应用程序一旦和数据库建立连接,就可以使用JDBC 提供的 API操作数据库》当查询 ResultSet 对象中的数据时,不可以关闭和数据库的连接。
使用 PreparedStatement 对象可以提高操作数据库的效率.
使用数据库连接池可以提高连接数据库的效率。
以上就是本章内容。