Java进阶学习第十九天dbutils与案例
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java进阶学习第十九天dbutils与案例,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含16612字,纯文字阅读大概需要24分钟。
内容图文
![Java进阶学习第十九天dbutils与案例](/upload/InfoBanner/zyjiaocheng/567/6216400459b14ea6b7adf4dd907ab568.jpg)
文档版本 开发工具 测试平台 工程名字 日期 作者 备注 V1.0 2016.05.15 lutianfei none 元数据 元数据(metaData) 指数据库中 库 、 表 、 列 的定义信息 DataBaseMetaData 数据库元数据 获取一个DataBaseMetaData Connection接口中定义了一个方法 getMetaDat
文档版本 | 开发工具 | 测试平台 | 工程名字 | 日期 | 作者 | 备注 |
---|---|---|---|---|---|---|
V1.0 | 2016.05.15 | lutianfei | none |
元数据
- 元数据(metaData) 指数据库中 库、表、列的定义信息
DataBaseMetaData 数据库元数据
获取一个DataBaseMetaData
- Connection接口中定义了一个方法 getMetaData();
- Connection.getMetaData()
通过DataBaseMetaData获得 数据库连接的基本参数
- getURL():返回一个String类对象,代表数据库的URL。
- getUserName():返回连接当前数据库管理系统的用户名。
- getDriverName():返回驱动驱动程序的名称。
- getPrimaryKeys(String catalog, String schema, String table):返回指定表主键列的结果集
获得数据库、表、列、主键、外键 定义信息
- getTables
- getColumns
- getPrimaryKeys
常用API
- String driverName = dmd.getDriverName(); //获取驱动名称
- String userName = dmd.getUserName();//获取用户名
- String url = dmd.getURL();//获取url
- String databaseProductName = dmd.getDatabaseProductName(); //获取数据库名称
- String databaseProductVersion = dmd.getDatabaseProductVersion();//获取数据库版本.
- ResultSet getPrimaryKeys(String catalog,String schema,String table)
- 获取表中主键相关描述,每个主键列描述都有以下列:
- TABLE_CAT String => 表类别(可为 null)
- TABLE_SCHEM String => 表模式(可为 null)
- TABLE_NAME String => 表名称
- COLUMN_NAME String => 列名称
- KEY_SEQ short => 主键中的序列号(值 1 表示主键中的第一列,值 2 表示主键中的第二列)。
- PK_NAME String => 主键的名称(可为 null)
- 获取表中主键相关描述,每个主键列描述都有以下列:
ParameterMetaData 参数元数据
参数元数据主要用于获取:sql语句中占位符的相关信息.
PreparedStatement . getParameterMetaData()
- 获得代表PreparedStatement元数据的ParameterMetaData对象。
常用API
- getParameterCount():获得指定参数的个数
- getParameterTypeName(int param) :获得指定参数的sql类型
注意:在获取参数类型时会产生异常
- java.sql.SQLException: Parameter metadata not available for the given statement
- 解决方案:
- 在url后添加参数:jdbc : mysql:///day18?generateSimpleParameterMetadata=true
- 原因:是mysql驱动的支持问题。
ResultSetMetaData 结果集元数据(重点)
ResultSet. getMetaData()
- 获得代表ResultSet对象元数据的ResultSetMetaData对象。
常用API
- getColumnCount() 返回resultset对象的列数
- getColumnName(int column) 获得指定列的名称
- getColumnTypeName(int column) 获得指定列的类型
public static void main(String[] args) throws SQLException {
Connection con = JdbcUtils.getConnection();
ResultSet rs = con.createStatement().executeQuery(
"select * from account");
// 得到结果集元数据
ResultSetMetaData rsmd = rs.getMetaData();
// System.out.println(rsmd.getColumnCount());//获取结果集中列数量
//
// System.out.println(rsmd.getColumnName(2));//获取结果集中指定列的名称.
//
// System.out.println(rsmd.getColumnTypeName(3));//获取结果集中指定列的类型。
int count = rsmd.getColumnCount();
for (int i = 1; i <= count; i++) {
System.out.print(rsmd.getColumnName(i)+"("+rsmd.getColumnTypeName(i)+")" + "\t");
}
System.out.println();
while (rs.next()) {
for (int i = 1; i <= count; i++) {
System.out.print(rs.getObject(i) + "\t\t");
}
System.out.println();
}
}
dbutils工具
commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能。因此dbutils成为很多不喜欢hibernate的公司的首选。
简单说,它就是一个简单的jdbc封装工具,使用dbutils可以简化操作,要使用dbutils需要导入jar包。
JAR包:
commons.dbutils-1.4.jar
API介绍:
- org.apache.commons.dbutils.QueryRunner — 核心
- org.apache.commons.dbutils.ResultSetHandler
- 工具类
- org.apache.commons.dbutils.DbUtils。
DBUtils学习
1、
QueryRunner
框架核心类 ,所有数据库操作都是必须通过 QueryRunner 进行的,用于执行sql语句的类。- 1.query 用于执行select
- 2.update 用于执行update delete insert
- 3.batch 批处理
2、
ResultSetHandler
结果集封装接口,完成将ResultSet 结果集 封装为一个Java对象- 用于定义结果集的封装
- 它提供九个实现类,可以进行不同的封装。
3、
DbUtils
工具类 提供驱动管理、事务管理、释放资源等一系列公共方法- 它提供关于关闭资源以及事务rollback,commit操作。
- DbUtils里面的所有方法都是静态的。主要方法如下:
- public static void
close(…)
throws java.sql.SQLException
- DbUtils类提供了三个重载的关闭方法。这些方法检查所提供的参数是不是NULL,如果不是的话,它们就关闭Connection、Statement和ResultSet。
- public static void
closeQuietly(…)
- 这一类方法不仅能在Connection、Statement和ResultSet为NULL情况下避免关闭,还能隐藏一些在程序中抛出的SQLException。
- public static void
commitAndCloseQuietly
(Connection conn)
- 用来提交连接,然后关闭连接,并且在关闭连接时不抛出SQL异常。
- public static boolean
loadDriver
(java.lang.String driverClassName):这一方装载并注册*JDBC驱动程序*,如果成功就返回true。使用该方法,你不需要捕捉这个异常ClassNotFoundException。
- public static void
Dbutlis详解
1.QueryRunner怎样获取
- 1.new QueryRunner()
- 如果是使用这种构造创建的QueryRunner,它的事务是手动控制。
- 2.new QueryRunner(DataSource ds);
- 如果是使用这种构造,它的事务是自动事务,简单说,一条sql一个事务。
- 1.new QueryRunner()
2.QueryRunner中的三个核心方法
- query
- update
- batch
- 对于上述三个方法,它们提供很多重载。
- 如果QueryRunner在创建时,没有传递DataSource参数,那么在使用query,update,batch方法时,要传递Connection参数
- 如果QueryRunner在创建时,传递了Dataource参数,那么在使用query,update,batch方法时,不需要传递Connection参数。
总结:
怎样配套使用:
- QueryRunner runner=new QueryRunner();
- runner.query(Connection,sql,ResultSetHandler,Object… param);
- runner.update(Connection,sql,Object…param);
- runner.batch(Connection con,sql,Object[][] objs);
- QueryRunner runner=new QueryRunner(DataSource ds);
- runner.query(sql,ResultSetHandler,Object… param);
- runner.update(sql,Object…param);
- runner.batch(sql,Object [][] objs);
- QueryRunner runner=new QueryRunner();
模仿QueryRunner
- 1.query方法模仿
public T query(Connection con, String sql, MyResultSetHandler mrs,Object... params) throws SQLException {
PreparedStatement pst = con.prepareStatement(sql); // 得到一个预处理的Statement.
// 问题:sql语句中可能存在参数,需要对参数赋值。
ParameterMetaData pmd = pst.getParameterMetaData();
// 可以得到有几个参数
int count = pmd.getParameterCount();
for (int i = 1; i <= count; i++) {
pst.setObject(i, params[i - 1]);
}
ResultSet rs = pst.executeQuery(); // 得到了结果集,要将结果集封装成用户想要的对象,但是,工具不可能知道用户需求。
return mrs.handle(rs);
}
- 2.update方法模仿
public int update(Connection con, String sql, Object... params) throws SQLException {
PreparedStatement pst = con.prepareStatement(sql); // 得到一个预处理的Statement.
// 问题:sql语句中可能存在参数,需要对参数赋值。
ParameterMetaData pmd = pst.getParameterMetaData();
// 可以得到有几个参数
int count = pmd.getParameterCount();
for (int i = 1; i <= count; i++) {
pst.setObject(i, params[i - 1]);
}
int row = pst.executeUpdate();
// 关闭资源
pst.close();
return row;
}
ResulsetHandler九个实现类
- ResultSetHandler接口:用于封装结果集.
该接口用于处理
java.sql.ResultSet
,将数据按要求转换为另一种形式。- ResultSetHandler 接口提供了一个单独的方法:Object handle (java.sql.ResultSet .rs)。
ArrayHandler
, 将结果集中第一条记录封装到Object[]数组,数组中的每一个元素就是记录中的字段值。ArrayListHandler
, 将结果集中每一条记录封装到Object[],数组中的每一个元素就是记录中的字段值。在将这些数组装入到List集合。BeanHandler
(重点), 将结果集中第一条记录封装到一个javaBean中。BeanListHandler
(重点), 将结果集中每一条记录封装到javaBean中,在将javaBean封装到List集合。ColumnListHandler
, 将结果集中指定列的值封装到List集合.MapHandler
, 将结果集中第一条记录封装到Map集合中,集合的 key就是字段名称,value就是字段值MapListHandler
, 将结果集中每一条记录封装到Map集合中,集合的 key就是字段名称,value就是字段值,在将这些Map封装到List集合KeyedHandler
,在使用指定的列的值做为一个Map集合的key,值为每一条记录的Map集合封装。ScalarHandler
进行单值查询 select count(*) from account;
//介绍ResultSetHandler的九个实现类.
public class ResultSetHandlerImplTest {
// ArrayHandler
@Test
public void fun1() throws SQLException {
QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource());
Object[] obj = runner
.query("select * from account", new ArrayHandler());
System.out.println(Arrays.toString(obj));
}
// ArrayListHandler
@Test
public void fun2() throws SQLException {
QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource());
List
实现BeanHandler
public class MyBeanHandler implements MyResultSetHandler {
private Class clazz;
public MyBeanHandler(Class clazz) {
this.clazz = clazz;
}
public Object handle(ResultSet rs) throws SQLException {
Object obj = null;
Map map = new HashMap();
ResultSetMetaData md = rs.getMetaData();
int count = md.getColumnCount();
if (rs.next()) {
try {
obj = clazz.newInstance();
for (int i = 1; i <= count; i++) {
map.put(md.getColumnName(i),
new String[] { rs.getString(md.getColumnName(i)) });
}
BeanUtils.populate(obj, map);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
return obj;
}
// 从结果集的方向去封装数据
// public Object handle(ResultSet rs) throws SQLException {
// Object obj = null;
// // 1.得到结果集元数据
// ResultSetMetaData md = rs.getMetaData();
// // 2.得到所有字段名称
// int count = md.getColumnCount();
//
// if (rs.next()) {//遍历结果集
// try {
// BeanInfo bif = Introspector.getBeanInfo(clazz); //得到BeanInfo
// PropertyDescriptor[] pds = bif.getPropertyDescriptors();
// //得到javaBean的所有属性描述器
// obj = clazz.newInstance();
// for (int i = 1; i <= count; i++) {
// String name = md.getColumnName(i); //得到每一列的名称
//
// for(PropertyDescriptor pd:pds){
// if(name.equals(pd.getName())){ //与javaBean的属性比较
//
// pd.getWriteMethod().invoke(obj,
// rs.getObject(name));//使用setXxx方法将结果集中的字段值封装到JavaBean的对应属性上。
// }
// }
// }
// } catch (InstantiationException e) {
// e.printStackTrace();
// } catch (IllegalAccessException e) {
// e.printStackTrace();
// } catch (IntrospectionException e) {
// e.printStackTrace();
// } catch (IllegalArgumentException e) {
// e.printStackTrace();
// } catch (InvocationTargetException e) {
// e.printStackTrace();
// }
//
// }
// return obj;
// }
// 从javaBean 的方向去封装数据
// public Object handle(ResultSet rs) throws SQLException {
//
// Object obj = null;
// // 1.得到clazz所有bean属性.
// try {
//
// BeanInfo bif = Introspector.getBeanInfo(clazz);
//
// PropertyDescriptor[] pds = bif.getPropertyDescriptors();
// if (rs.next()) {
// obj = clazz.newInstance();
// for (PropertyDescriptor pd : pds) {
//
// // 得到所有属性名称
// String name = pd.getName();
// System.out.println(name);
// // 得到所有属性对应的set方法
// Method setMethod = pd.getWriteMethod();
// if (setMethod != null) { // 就可以将class对应的写方法去掉
//
// setMethod.invoke(obj, rs.getObject(name));
// }
// }
//
// }
//
// } catch (IntrospectionException e) {
// e.printStackTrace();
// } catch (InstantiationException e) {
// e.printStackTrace();
// } catch (IllegalAccessException e) {
// e.printStackTrace();
// } catch (IllegalArgumentException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (InvocationTargetException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
//
// return obj;
// }
}
dbutils综合练习
- 以下均为项目
day19_2
代码说明。 登录成功后,访问到一个页面success.jsp,在页面上添加一个连接,就是客户信息的CRUD操作。
1.客户信息
字段名 | 说明 | 类型 |
---|---|---|
Id | 编号 | varchar(40) |
name | 客户姓名 | varchar(20) |
gender | 性别 | varchar(10) |
birthday | 生日 | date |
cellphone | 手机 | varchar(20) |
电子邮件 | varchar(40) | |
preference | 客户爱好 | varchar(100) |
type | 客户类型 | varchar(40) |
description | 备注 | varchar(255) |
create table customer(
id varchar(40) primary key,
name varchar(20),
gender varchar(10),
birthday date,
cellphone varchar(20),
email varchar(40),
preference varchar(100),
type varchar(40),
description varchar(255)
);
2.搭建环境
- JavaEE 三层结构
- Servlet + JSP + JavaBean+jstl + DBUtils+ DAO + MySQL
- 导入jar包 :JSTL 、BeanUtils、DBUtils、C3P0、mysql驱动
- 创建包结构
- cn.itcast.customer.web 表现层
- cn.itcast.customer.service 业务层
- cn.itcast.customer.dao 持久层
- cn.itcast.customer.utils 工具包
- cn.itcast.customer.domain 实体类 javaBean
应用的jar文件
- mysql驱动包
- dbutils包
- BeanUtil包
- JSTL包
- c3p0的配置文件
编写代码:
- 1.创建Customer这个javaBean
private String id;
private String name;
private String gender;
private Date birthday;
private String cellphone;
private String email;
private String preference;
private String type;
private String description;
- 2.为了测试方便,向customer表中插入数据
insert into customer values("a11","tom","男","2010-10-10","13888888888","tom@163.com","吃,喝,玩","vip","good man");
insert into customer values("a11","fox","男","2000-10-10","13888888888","tom@163.com","吃,喝,玩","vip","good man");
insert into customer values("a11","james","男","1990-10-10","13888888888","tom@163.com","吃,喝,玩","vip","good man");
- 3.实现查询所有客户信息操作
- 1.在success.jsp页面添加连接
查看所有客户信息
- 2.在CustomerFindAllServlet中调用service,在service中调用dao,最后得到一个
List
。 - 3.在showCustomer.jsp页面展示客户信息
- 1.在success.jsp页面添加连接
<c:forEach items="${cs}" var="c">
<tr>
<td><input type="checkbox">
td>
<td>${c.id }td>
<td>${c.name}td>
<td>${c.gender }td>
<td>${c.birthday }td>
<td>${c.cellphone }td>
<td>${c.email }td>
<td>${c.preference }td>
<td>${c.type }td>
<td>${c.description }td>
<td><a>编辑a> <a>删除a>td>
tr>
c:forEach>
- 4.删除操作
- 1.在showCustomer.jsp页面的删除连接上添加参数 客户的id
删除
- 2.创建一个CustomerDelByIdServlet,获取请求参数,调用service中删除方法.
- 问题:如果删除完成后,怎样处理?
- 需要重新跳转到查询所有的servlet中,在重新查询数据。
- 1.在showCustomer.jsp页面的删除连接上添加参数 客户的id
- 5.编辑
- 1.查询,做回显示
编辑
- 1.创建CustomerFindByIdServlet,得到要查询的id,调用service,得到Custonmer对象。
- 2.将customer对象存储到request域,请求转发到customerInfo.jsp页面。
- 3.在customerInfo.jsp页面展示客户信息
- 注意:客户的id不能修改,所以使用
- 2.修改
- 1.注意使用BeanUtils时的类型转换问题
- 2.注意编码问题
- post:
request.setCharacterEncoding("utf-8");
- get:手动转换
new String(request.getParameter(name).getBytes("iso8859-1"),"utf-8");
- post:
- 3.进行修改操作
- 1.查询,做回显示
public void update(Customer c) throws SQLException {
String sql = "update customer set name=?,gender=?,birthday=?,cellphone=?,email=?,preference=?,type=?,description=? where id=?";
QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource());
runner.update(sql, c.getName(), c.getGender(), c.getBirthday(),
c.getCellphone(), c.getEmail(), c.getPreference(), c.getType(),
c.getDescription(), c.getId());
}
修改完成后,在重新查询一次
response.sendRedirect(request.getContextPath() + "/findAll");
解决关于回显示时的问题:
- 1.性别 应该使用radio
- 使用自定义标签
- 1.定义标签类 extends SimpleTagSupport
- 2.定义tld文件
- 使用自定义标签
<tag>
<name>sexname>
<tag-class>cn.itcast.customer.tag.GenderTagtag-class>
<body-content>emptybody-content>
<attribute>
<name>gendername>
<required>truerequired>
<rtexprvalue>truertexprvalue>
attribute>
tag>
* 3.在页面上使用
* 1.使用taglib导入
* 2.使用` `
虚拟主机
- 使用虚拟主机可以将项目部署成顶级域名
- 1.在service.xml文件
- 1.端口修改为80
- 2.配置主机
"www.customer.com" appBase="D:\java1110\workspace\day19_2"
unpackWARs="true" autoDeploy="true">
"org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log." suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
"" docBase="D:\java1110\workspace\day19_2\WebRoot" />
</Host>
- 3.在hosts文件中配置
- 127.0.0.1 www.customer.com
内容总结
以上是互联网集市为您收集整理的Java进阶学习第十九天dbutils与案例全部内容,希望文章能够帮你解决Java进阶学习第十九天dbutils与案例所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。