数据库应用程序开发

2023级的数据结构程序与开发是1.5学分,实验占50分,考试占50分.
授课老师:qgn(奶龙 斗笠 大剑老师)

实验

这门课看起来是数据库课程,实际上是Java课程.
实验有11个任务,网上能直接查到源代码,稍微改改就是自己的了.

虽然这门课十分老掉牙,老师也建议大家用A103的XP机子(配好环境了)做,不然建议用XP虚拟机做,但其实实验能直接用自己电脑做的.

方法和老师的资料有点不一样.

  • 找ibm官网下载db2
    直接下载

  • 按照老师ppt的流程安装.不同的是:
    不要按照老师说的创建一个账号为 student 密码也是 student 的账户,只要不创建,后面会省心很多,管理员组也不用配置.

  • 开始安装,直到右下角出现绿色圆图标代表安装成功.

  • 注册许可证,按照ibm文档进行

  • 打开”db2 第一步”,安装SAMPLE数据库(这很重要!后面的实验围绕SAMPLE数据库进行)

  • 打开IntellIj,新建一个java项目.

  • 导入外部库:有一个jar文件需要导入,忘了是什么了(Flu做完实验就删环境,因为db2开机自启动),导入之后程序就能连接上数据库.

  • Java开发:
    由于我们在自己电脑上开发程序,所以代码和其他人写的不太一样,具体表现在连接数据库不一样,其他的都能照抄.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // MyJDBC.java
    public class MyJDBC {
    static { //内部静态类
    try {
    Class.forName("COM.ibm.db2.jdbc.app.DB2Driver");
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }

    不需要加载上面的驱动,实验仍然会成功,估计是导入ij能导入外部库.

    1
    sample=DriverManager.getConnection("jdbc:db2:SAMPLE","lenovo","123456");

    把类里面static中链接数据库的部分删掉.
    然后只用上面一句话就能连上数据库,lenovo用你自己的用户名,123456用你自己电脑的密码.

    剩下的开发过程和其他人是一样的,别人怎么做你就怎么做.

配环境有点红温,因为ppt说有一个db2控制中心,我始终找不到,而且”db2第一步”的界面和ppt也不一样.
我打算放弃的时候发现了一个特殊的jar能够帮程序连接数据库,实验突然跑通了.
我为EMPLOYEE表创建TEMPL别名的的时候失败了,不知道为什么,不过别名是小问题,后面实验还是能正常做,改成EMPLOYEE就行.

整体实验时间建议1+3h,前1h下载资料.

UPD20260224:IBM的DB2会往你的电脑注入至少7个环境变量,做完实验卸载之后,没用的环境变量仍然会保留,需要手动删除,有点恶心.

考试

网上能找到很多笔记,大致考点只有下面几个,背好下面这些代码基本上挂不了(qgn:如果你觉得平时分占50%然后考试就不好好写,那我是不捞你的)

加载驱动,链接数据库,关闭数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.io.*;
import java.sql.*;
import java.lang.*;
import java.math.*;

public class A {
static {
try {
Class.forName("COM.ibm.db2.jdbc.app.DB2Driver");//加载驱动
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Connection conn=Drivermanager.getConnection("jdbc.db2.SAMPLE","admin","admin");
//xx
conn.close();
}
}

所有人涨薪5% 异常处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.sql.*;
import java.io.*;

public class UpdateSalaryAndCheck {
public static void main(String[] args) throws Exception {
Connection con = EmployeeTable.getConnection();
try{
con.setAutoCommit(false);
String sql = "UPDATE Employ SET salary=1.05*salary";
Statement stmt = con.createstatement();
int updateCount = stmt.executeUpdate(sql);
System.out.println("更新行数:" + updateCount);
con.commit();
stmt.close();
con.close();
}catch(SQLException e){
String SQLState = e.getSQLState();
if (sQLState.equals("22003")) {//记住这个数字是超出范围,42818是参数不匹配
System.out.println("数值超出范围");
}
e.printStackTrace();
}
}
}

异常处理

单行插入,多行插入,子查询插入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//单行
String sql="INSERT INTO Employ VALUES(?,?,?,?,?)";
PreparedStatement pstmt=con.prepareStatement(sql);
pstmt.setString(1,"aaa");
pstmt.setInt(2,114);
...

pstmt.executeUpdate();

//多行
String sql="INSERT INTO Employ VALUES(?,?,?,?,?)";
PreparedStatement pstmt=con.prepareStatement(sql);
pstmt.setString(1,"aaa");
pstmt.setInt(2,114);
...
pstmt.addBatch();

int[] cnt=pstmt.executeBatch();

//子查询
String sql="INSERT INTO Employ(empno,name,age,salary) "+
"SELECT empno,name,age,salary FROM templ WHERE empno=?";
PreparedStatement pstmt=con.prepareStatement(sql);
pstmt.setString(1,"123");
pstmt.executeUpdate();

删除员工

1
DELETE FROM Employ WHERE empno=?

NULL

1
2
3
4
if(rs.wasNull()){
pstmt.setNull(1,Types.DOUBLE);
pstmt.executeUpdate();
}

LOB

CLOB(很长的字符)

1
2
3
4
5
6
7
while (rs.next()) {
// empno = rs.getString(1);
// resumefmt = rs.getString(2);
res = rs.getClob(3);
int len = (int)res.length();
String resout = res.getSubString(1, len);
}

BLOB(很长的二进制)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//  读
File file = new File("C:/a.jpg");
BufferedInputStream imageInput = new BufferedInputStream(new FileInputStream(file));
pstmt.setBinaryStream(1, imageInput, (int)file.length());
pstmt.executeUpdate();
// 写
Blob blob = (Blob)rs.getBlob(1);
InputStream inputStream = blob.getBinaryStream();
File file = new File("C:/backa.jpg");
FileOutputStream fos = new FIleOutputStream(file);
int c;
while((c = inputStream.read()) != -1) {
fos.write(c);
}

加锁

就是 for updatewhere current of

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ResultSet rs=stmt.executeQuery(
"SELECT salary FROM Employ FOR UPDATE");
String updateSql="UPDATE Employ SET name=? WHERE CURRENT OF ";
String cursorName=rs.getCursorName();
PreparedStatement pstmt=con.prepareStatement(updateSql+cursorName);

while(rs.next()){
String name=rs.getString(1);
if(name.equals("Smith")){
String newname="Jock";
pstmt.setString(1,newname);
pstmt.executeUpdate();
}
}
pstmt.close();
rs.close();

可动鼠标

查询Employee表信息,定义可自由移动数据集,从最后一行向前读取数据,输出Employee表的相关信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Statement stmt = conn.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);

String sql = "SELECT empno, ename, salary FROM Employee";
ResultSet rs = stmt.executeQuery(sql)

rs.afterLast();
while (rs.previous()) {
String empno = rs.getString(1);
String ename = rs.getString(2);
BigDecimal sal = rs.getBigDecimal(3);

System.out.xxx
}

参考资料

1 2 3