2009-12-10传智播客jdbc——高级应用(转载)

Oracle数据库部分终于在昨天结束了,整理学习日志到很晚。今天继续讲解JDBC,是方老师授课的。方老师在我们班还有六堂的课程,多少有些舍不得,他是个好老师。学完这六堂课,JAVAWEB基础到此也就结束了(09-12-18)。十分渴望快些学习到项目那,把这些技术混合运用,做出个像模像样的东西来!



今天的内容依然很多,我还是好好把它整理出来吧!



一、JDBC中调用Oracle存储过程:

例,在Oracle中创建一个存储过程:

CREATE OR REPLACE PROCEDURE UPEMPFUN(

ARG_EMPNO IN NUMBER,

ARG_SAL IN NUMBER,

ARG_RES OUT VARCHAR

)IS BEGIN

UPDATE EMP SET SAL = ARG_SAL WHERE EMPNO=ARG_EMPNO;

COMMIT;

ARG_RES := 'OK!';

END;


在JDBC中,调用上面的存储过程(我的Oralce出问题了,没有测试):

CallableStatement cStmt = conn.prepareCall("{call UPEMPFUN(?, ?, ?)}");

// 注册接收返回值的变量

cStmt.registerOutParameter(3, Types.VARCHAR);

cStmt.setInt(1, 7360);

cStmt.setFloat(1, 8888);

cStmt.execute();

// 打印返回值

System.out.println(cStmt.getString(3));




二、JDBC数据库中的分布技术:

1.ResultSet提供了对结果集进行滚动的功能:

next():移动到下一行

Previous():移动到前一行

absolute(int row):移动到指定行

beforeFirst():移动resultSet的最前面

afterLast() :移动到resultSet的最后面



使用上面的滚动记录功能可以实现分页功能,但建议不要使用这种技术进行分页。因为当记录数量大的时间,会带来性能上的下降,资源的浪费。



2.MySQL分页语句:

Select * from tab_ame limit M,N;

M:记录起始索引位置

N:获取记录数量



3.Oracle分页语句(TOP-N技术):

Select * from (

Select rownum rn,* from (

Select * from tab_name where 条件

) where rownum <=结束位置

)where rn >=起始位置

它与MySql分页相比,MySql更方便些。而且MySql中的N直接获取记录数量,但Oracle中却是结束位置的索引和起始位置的索引之间的记录。



4.编写一个WEB应用,使用分布技术显示数据库中的记录:

简易流程图:(如果看不到图片,请到这里:http://www.blogjava.net/changcheng/)


ListStudent.java,doGet部分:

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

// 获取总记录数量

StudentDao sd = new StudentDao();

int totalrecord = 0;

int pagenum = 0;

Page page = null;

try {

totalrecord = sd.getTotal();

// 获取记录信息

String currage = request.getParameter("currpage");

page = new Page(totalrecord, (currage != null) ? Integer

.parseInt(currage) : 1);

page.setRecord(sd.getRecord(page.getStartindex(), page.getPagesize()));

} catch (Exception e) {

e.printStackTrace();

}



// 将信息发往index.jsp进行显示

request.setAttribute("page", page);

request.getRequestDispatcher("index.jsp").forward(request, response);

}




Student.java:

public class StudentDao {

// 获取学生总数

public int getTotal() throws SQLException {

// 获取连接

Connection conn = JdbcUtil.getDataSource().getConnection();

// 查询数量

PreparedStatement ps = conn

.prepareStatement("select count(*) from student");

ResultSet rs = ps.executeQuery();

int total = 0;

while (rs.next()) {

total = rs.getInt(1);

}

// 释放连接

JdbcUtil.release(rs, ps, conn);

return total;

}



// 获取记录

public List getRecord(int startindex, int count) throws SQLException {

// 获取连接

Connection conn = JdbcUtil.getDataSource().getConnection();

// 查询记录

PreparedStatement ps = conn

.prepareStatement("select id,name,sex from student limit ?,?;");

ps.setInt(1, startindex);

ps.setInt(2, count);

ResultSet rs = ps.executeQuery();

// 读取记录

List result = new ArrayList();

while (rs.next()) {

StudentBean stuben = new StudentBean();

stuben.setId(rs.getInt("id"));

stuben.setName(rs.getString("name"));

stuben.setSex(rs.getBoolean("sex"));

result.add(stuben);

}

// 释放连接

JdbcUtil.release(rs, ps, conn);

return result;

}



}




Page.java:

public class Page {

private int totalrecord;// 总记录数

private int totalpage;// 总页面数

private int pagesize = 3;// 页面显示记录数

private int startindex;// 起始索引

private int currpage;// 当前页面

private List record;// 记录



public Page(int totalrecord, int currpage) {

this.totalrecord = totalrecord;

this.currpage = currpage;

}

public int getTotalrecord() {

return this.totalrecord;

}

public List getRecord() {

return record;

}

public void setRecord(List record) {

this.record = record;

}

// 计算总页面数

public int getTotalpage() {

if (this.totalrecord % this.pagesize == 0)

totalpage = this.totalrecord / this.pagesize;

else

totalpage = this.totalrecord / this.pagesize + 1;



return this.totalpage;

}

// 计算起始索引

public int getStartindex() {

this.startindex = (this.currpage - 1) * this.pagesize;

return this.startindex;

}

public int getPagesize() {

return this.pagesize;

}

}




Index.jsp,body部分:

<body>

HI

<hr>

<table border="1">

<tr>

<td>ID</td><td>姓名</td><td>性别</td>

</tr>

<!-- 显示记录信息 -->

<cc:forEach var="record" items="${page.record}">

<tr>

<td>${record.id }</td><td>${record.name }</td><td>${record.sex }</td>

</tr>

</cc:forEach>



<!-- 显示翻页信息 -->

</table>

<cc:forEach var="i" begin="1" end="${page.totalpage}">

<a href="http://localhost:8080/091210/ListStudent?currpage=${i}">${i}</a>

</cc:forEach>

</body>




如果连接的是Oracle数据库,则使用Oracle数据库的TOP-N技术即可!



三、JDBC对数据库LOB操作:

LOB数据(LargeObject),简称大对象。它分为两类:

1. CLOB:CharactorLargeObject,专门用于处理字符的大对象。

2. BLOB:ByteLargeObject,专门用于处理二进制数据,比如图片等。



1. MySQL中的LOB操作:

在MySQL中:TEXT与CLOB对应,BLOB与BLOB对应。

调用下面的方法设置TEXT:

PreparedStatement.setCharacterStream(index, reader, length);

//注意length长度须设置,并且设置为int型


调用下面的方法获取TEXT:

1.reader = resultSet. getCharacterStream(i);

2.reader = resultSet.getClob(i).getCharacterStream();

3.string = resultSet.getString(i);




调用下面的方法设置BLOB:

PreparedStatement.setBinaryStream(i, inputStream, length);


调用下面的方法获取BLOB:

1.InputStream in = resultSet.getBinaryStream(i);

2.InputStream in = resultSet.getBlob(i).getBinaryStream();




在MySql数据库中使用LOB字段,直接定义这个字段的类型为“TEXT”或“BLOB”即可!



2. Oracle中的LOB操作:

在Oracle中CLOB与“EMPTY_CLOB()”对应,“BLOB”与“EMPTY_BLOB()”对应。

Oracle中设置和获取BLOB的JDBC方法与MySQL相同。

在Oralce中添加LOB字段插入内容时,必须在事件中进行否则极可能出错。



注意:在Oracle数据库中添加CLOB字段必须使用“empty_clob()”,添加BLOB字段必须使用“empty_blob()”。在对他们进行赋值时,必须使用查询语句获取对应字段名的指针。在获取字段指针的查询语句结尾必须使用“fro update”这样锁定该行,保证不会发生冲突。



例,向Oracle数据库写入大文本操作:

private static void save() throws Exception {

// 获取连接

Connection conn = JdbcUtil.getDataSource().getConnection();

conn.setAutoCommit(false);

PreparedStatement ps = conn

.prepareStatement("insert into ocolb(id, text) values (1,empty_clob())");

ps.executeUpdate();

// 获取指针

ps = conn.prepareStatement("select text from ocolb where id=1 for update;");

ResultSet rs = ps.executeQuery();

// 写入数据

File imfi = new File("C:/ocolb.txt");

Reader reader = new FileReader(imfi);

//ps.setCharacterStream(1, reader, imfi.length());

CLOB clob = (CLOB) rs.getClob("text");

Writer writer = clob.getCharacterOutputStream();

char[] buf = new char[1024];

int len = 0;

while((len = reader.read(buf)) != -1){

writer.write(buf, 0, len);

}

reader.close();

writer.close();

// 提交

conn.commit();

// 释放连接

JdbcUtil.release(rs, ps, conn);

}




四、JDBC对数据库批量操作:

当我们向数据库的一个表中插入100条记录时,比如向employee表中插入100名员工。难道我们要一条条语句执行?如果插入100万条呢?后果可想而知,所以需要批量操作来完成此任务。



在JDBC中有两种方法可以进行指操作:

1. Statement.addBatch(sql):

实现批处理的缺点:当向表中使用sql语句批量插入数据时,采用此种方式需重复写上多条语句相同,只参数不同的sql语句,工作量大,可读性差。

String sql1 = "insert into employee(id,name) values(1,'aaa')";

String sql2 = "insert into employee(id,name) values(2,'bbb')";

st = conn.createStatement();

st.addBatch(sql1);

st.addBatch(sql2);

st.executeBatch();




2. PreparedStatement. addBatch():

SQL语句相同,但参数相同。此种方法主要用于在同一个表中批量插入数据、或批量更新数据。

String sql2 = "insert into employee(name,department_id) values(?,?)";

ps = conn.prepareStatement(sql2);

Iterator it = department.getEmployees().iterator();

while(it.hasNext()){

Employee e = (Employee) it.next();

ps.setString(1, e.getName());

ps.setInt(2, id);

ps.addBatch();

}






五、JDBC操作多个实体:

操作多个实体?这个玩法第一次听说。说直白些就是将JAVA对象与数据库的表,关联起来。如何关联?当然是通过代码关联了。



例:

1.创建department和employee表:

Create table department(

id int primary key auto_increment,

name varchar(50)

)



Create table employee(

id int primary key auto_increment,

name varchar(30),

department_id int,

constraint for_ke foreign key(department_id) references department(id)

)




2.定义Department和Employee类:

public class Department {

private int id;

private String name;

private Set<Employee> employees = new HashSet<Employee>();



}



public class Employee {

private int id;

private String name;

private Department department;



}




3.创建一个多Department对象,创建多个个Employee对象,添加到Department对象的SET中。



4.定义一个工具类,将Department对象给工具类的SAVE方法,SAVE方法使用批量操作,将数据添加到数据库的department和employee表中。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值