吉林大学数据库应用程序开发知识点总结
这是我在复习数据库应用程序开发的时候纪录的条记。我们这一年的考试题(2021级2023年12月31考试)共计两道题。第一题是根据实验报告出的,每道题基本上涉及一个知识点;第二题是对于祥瑞码的分析题,也是以数据库为焦点,操作为辅助的题目。团体难度不大,知识点都在下文提及。
知识点1 学习如何毗连数据库
1.1 加载数据库驱动程序
- Class.forName("COM.ibm.db2.jdbc.app.DB2DRIVER");
复制代码 1.2 创建数据库的毗连
- String url = "jdbc:db2:samle";
- String userid = "db2admin";
- String passwd = "db2admin";
- // 对数据库进行连接
- Connection sample =
- DriverManager.getConnection(url,userid,passwd);
复制代码 1.3 结果集ResultSet和Statement语句
对于完整的SQL语句(必要符合SQL语法)可以直接实行。
- String sql = "SELECT * FROM JLU.EMPLOYEE WHERE EMPNO = 000010";
- Statement stmt = sample.createStatement();
- ResultSet res = stmt.executeQuery(sql);
复制代码 1.4 标签标记PreparedStatement语句
这个语句有缺省处置惩罚的结果。可以利用?在sql语句中制造缺省值,但是在实行前利用preparedstatement进行增补。
- String sql = "SELECT * FROM JLU.EMPLOYEE WHERE EMPNO = ?";
- PreparedStatement pstmt = sample.prepareStament(sql);
- pstmt.setString(1,deptno);//带标签标记的deptno要在前面获取到
- // 如果需要补充的是int类型
- // pstmt.setInt(1,deptno);
- // 有几个?就需要补充几个标记
- // 标记的顺序和?相同
- int row = pstmt.excuteUpdate();
复制代码 1.5 将结果存储到结果集
- while(rs.next())
- {
- String data1 = rs.getStirng(1);
- String data2 = rs.getStirng(2);
- String data3 = rs.getStirng(3);
- /*
- 从1开始获取数据
- 函数里面的逻辑可以自己rewrite
- */
- }
复制代码
- rs.getString(n)读取String类型
- rs.getInt(n)读取Int类型
1.6 关闭jdbc对象
- 关闭ResultSet
- 关闭PreparedStatement
- 关闭Connection
- if(rs != null)
- {
- try{
- rs.close();
- }catch(SQLException ee){
- ee.printStackTrace();
- }
- }
- if (pstmt != null)
- {
- try{
- pstmt.close();
- }catch(SQLException ee){
- ee.printStackTrace();
- }
- }
- if (sample != null)
- {
- try{
- sample.close();
- }catch(SQLException ee){
- ee.printStackTrace();
- }
- }
复制代码 注意:关闭jdbc链接并不代表已经提交了事务。
知识点2 GUI窗口交互
2.1 利用JOptionPane进行提示输入交互
- 利用showMessageDialog进行消息提示
- JOptionPane.showMessageDialog(null,"已经更新的数据"+emptno);
复制代码
- 利用showInputDailog进行输入对话,会将消息存储在input中
- String input = JOptionPane.showInputDialog("请输入一个emptno\n");
复制代码 2.2 利用JTable创建数据库表格
这个JTable我们给出的方法比较老了。
我看ChatGPT给出的方案是:先创建一个DefaultTableModel dataModel;将数据存储到这个model中,然后再将model添加到JTable中。每次革新dataModle,否则每次添加数据再重新创建一个JTable效率太低,而且太占内存了。
- String[][] lineNames = {"编号","名","中间名","姓"};
- Object[][] line = new Object[4][4];
- // 使用Obeject对象只是引用,并不占据内存
- dataModel = new DefaultTableModel(data,lineNames);
- Jtable jt = new JTable();
- jt.setModel(dataModel);
复制代码 革新的话,可以先更新line 数组内里的数据,然后
- importData();
- dataModel.setDataVector(line,lineNames);
- // 更新DataModel就好了
复制代码 Excle应该就是用这种方法开发的。
2.3 获取JTable中的数据
- String cellValue = (String) tableModel.getValueAt(row, column);
复制代码 知识点3:插入,删除,修改操作
- String sql_insert = "insert into templ (empno,firstname,midname,lastname)";
复制代码
- String sql_insert = "insert into templ(empno,firstname,midname,lastname)";
- int count = num;// 用户想插入的行数
- for (int i=0; i<count; i++)
- {
- sql = sql +",(?,?,?,?)";
- }
复制代码
- String find_insert = "insert into templ(empno,firstname,midname,lasername)";
- String select_query = "select * from JLU.emplyee where ? = ?";
- String find_insert = find_insert + select_query;
复制代码
必要知道这个实现的思路就是先导入到物理存储上,然后对物理存储修改,再写入数据库。
这过程中有对锁思想的实现。(U锁的获取,老师的视频课内里讲解了)
实现方法 1:
- String str = "";
- String selectForUpdate = "select * from employee for update";
- // 注意 for update语句。这条语句作为sql是不符合规则的,但是jdbc会知道,你会update
- int finalRow = 0;
- int finalColumn = 0;
- int rNum = table.getSelectRow(); // 得到表格中被选中的行数
- int cNum = table.getSelectColumn(); // 得到表格中被选中的列数
- stmt = smple.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE); //创建可滚动,可更新的结果集
- ResultSet select_rs = stmt.excutQuery(selectforupdate);
- for (int i=0; i<finalRow; i++)
- selct_rs.next();
- if(select_rs.next())
- select_rs.updateObject(finaleColumn,str);
- select_rs.updateRow(); // 将结果落实到数据库(事务提交)
复制代码 实现方法 2:
- String str = "";
- String selectForUpdate = "select empno,firstname,lastname,edlevel,job from jlu.employee for update";
- int finalRow = 0;
- int finalColumn = 0;
- int rNum = table.getSelectRow(); // 得到表格中被选中的行数
- int cNum = table.getSelectColumn(); // 得到表格中被选中的列数
- stmt = smple.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
- ResultSet select_rs=stmt.executeQuery(selectForUpdate);
- select_rs.absolute(finalrow+1); //直接定位到第finalrow+1行
- //select_rs.absolute(lastFianlrow); // 我记得有这个函数,就是定位到最后一行+1
- select_rs.updateObject(finalcolmn+1,finalstr);
- select_rs.updateRow();
复制代码 知识点4:wasNull()方法
结果集返回的结果,假如利用String name = rs.getString(1);
再去判定name != null 的时候,判定的现实上是String类型的null,再String中“\0”就是空。
这样判定已经不是原来的rs是否为空了。
所以接纳原有的rs.wasNull()可以判定是否读到的数据是空。
总结:就是wasNull()可以查抄数据到底有没有读到。由于有时候那边的数据本来就是空,读到之后无法进行判定。比方我们单行插入的时候,许多数据并没有写进数据库。
- try{
- PreparedStatement stmt = "";
- String sql = "UPDATE TEMPL SET PHONENO = ? WHERE EMPNO = '000110'";
- stmt = con.prepareStatement(sql);
- if (some condition)
- {
- stmt.setString(1,null);
- // stmt.setNUll(1,java.sql.Type.STRING);
- }else{
- stmt.setString(1,newPhone);
- }
- int updateCount = stmt.excuteUpdate();
- if (updateCOunt != 1)
- {
- JOptionPane.showMessageDialog(null,"报错");
- }
- }catch(SQLException ex){
- ex.printStackTrace();
- }
复制代码 知识点5:结果集的进一步学习
5.1 利用last, previous,first遍历
- String sql = "select * from staff";
- PreparedStatement stmt = sample.prepareStatement(sql);
- ResultSet rs = stmt.executeQuery();
- rs.last(); // 最后一条
- rs.previous(); // 向前遍历
- rs.first(); // 第一个
- rs.next(); // 下一个
- rs.absolute(position); // 绝对位置position
复制代码 5.2 批处置惩罚
Statement对于批处置惩罚留下了两个接口
- void addBatch(String sql)
相称于把sql添加到batch中一个一个实行。
- int[] executeBatch()
实行batch中的sql命令
- Statement stmt = sample.createStatement();
- stmt.addBatch(sql1);
- stmt.addBatch(sql2);
- stmt.addBatch(sql3);
- int[] updateCounts = stmt.executeBatch(); // 返回的是影响数据库中行数的更新计数
- sample.commit(); //提交事务
复制代码 5.3 获取数据库布局
- DatabaseMetaData dbmd = sample.getMetaData(); // 获取数据库结构
- String[] tableTypes = {"TABLE","VIEW"};
- ResultSet rs = dbmd.getTables(null,"UDBA","%",tableTypes);
- /*
- dbmd.getTables(String catalog,String schema,String tableName,String[] types)
- String[] types想要返回何种表的数组
- 只会返回10字段的描述信息。
- */
复制代码 知识点6:大对象(BLOB类型)的读取
6.1 blob对象作用
blob存放二进制字符串,适用于存放UDT(User-defined Distinct Types),因此我们可以存放图片,声音等等数据。blob对象取决于varchar的大小,varchar最大是2GB,因此blob, clob, dblob 的大小都限制在2GB。
一样平常来说,为了进步性能,数据库必要专门创建一个用于存放大字段的表空间,数据表的大字段列应该将数据存放于对应的表空间中,这是由于不经过内存(缓冲池)直接读取的。
6.2 BLOB类型的赋值
- setBinaryStream(int n, java.io.InputStream x, int length)
- // n指示参数编号的int
- // InputStream对象
- // length指示字节数的int
复制代码 6.3 查询图片
代码逻辑:
先将Blob对象读取到rs结果会合,在用getBinaryStream()将Blob对象转换成二进制流对象inputStream;
之后将inputStream流对象通过.read()方法读到int c中,将c通过OutPutStream写到OutPutFile中。
- Statement stmt = sample.createStatement();
- ResultSet rs = st.excuteQuery("SELECT IMAGE FROM EMPLYEE");
- while(rs.next())
- {
- Blob blob = (Blob) rs.getBlob(1); // 读取Blob
- // Blob转换为数据流
- java.io.InputStream inputStream = blob.getBInaryStream();
- // 定义要写入的文件
- File fileOutPut = new File(path);
- FileOutPutStream fo = new FileOutPutStream(fileOutPut);
- int c;
- while((c = inputStream.read())!= -1)
- fo.write(c);
- fo.close();
- }
复制代码 6.4 插入图片
- PreparedStatement pstm = conn.prepareStatement("insert into emp_photo where emptno = ?");
- pstm.setString(emptnum);
- File file = new File(path);
- BufferedInputStream imageInput = new BufferedInputStream(new FileInputStream(file));
- pstm.setBianryStream(1,imageInput,(int)file.length);
- pstm.excuteUpdate();
复制代码 知识点7:大对象(CLOB类型)的读取
7.1 clob的作用
存储字符串类型的数据。举例:resume中都是一部分一部分的。因此可以作为大对象存储。
- Clob resumeLob = null; // 定义Clob
- resumeLob = rs3.getClob(3); // 将结果集中第三个位置的Clob取出
- String detailInfo = resumeLob.getSubString((long)),(int)resumeLob.length()); // 将Clob类型黄钻换成字符串类型
- POSSTR(RESUME,'Personal'); // 查看Personal在Resume中的位置
- SUBSTR(RESUME,1,length); // 查看resume中1-length长度的字串
- // 上面的两种语句详细用法
- sql3 =
- "SELECT EMPNO, RESUME_FORMAT," +
- "SUBSTR(RESUME,1,?)|| SUBSTR(RESUME,?) AS RESUME " +
- "FROM JLU.EMP_RESUME " +
- "WHERE EMPNO = ? AND RESUME_FORMAT = 'ascii'";
- /*
- 因为我们只知道一部分的位置,可以用substr推断另一部分的位置
- */
复制代码 这里的POSSTR和SUBSTR是在sql语句中增长的,具体的用法可以看老师给出的CLOB的示范代码。
知识点8:SQLException和SQLCODE
老师讲:数据库中许多代码都是进行错误处置惩罚的。由于没有一个代码是没有错误的,因此我们尽大概设计非常处置惩罚,来捕获错误,进步系统的鲁棒性。
8.1 SQLCODE和SQLSTATE
SQLCODE:是由数据库公司进行设计的,涵盖全部的SQLSTATE之外还可以附加其他的state;
SQLSTATE:是由国际标准构造指定的。
8.2 SQLException
是由jdbc创造的数据库非常捕获模块。
常见的用法及代码如下:
- catch(SQLExecption sex){
- sex.printStackTrace();
- int SQLCODE = sex.getErrorCode();
- if(sex.getSQLState().equlas("23505"))
- JOPtionPane.showMeaasgeDialog(null,"主键重复");
- }
复制代码 常见的SQLCODE(DB2)
- switch(SQLCODE){
- case 802:
- //数据溢出
- JOptionPane.showMessageDialog( null , "数据溢出" ,"SQL错误" , JOptionPane.ERROR_MESSAGE) ;
- break;
- case -007:
- //SQL语句中有非法字符
- JOptionPane.showMessageDialog( null , "SQL语句中有非法字符" ,"SQL信息" , JOptionPane.ERROR_MESSAGE) ;
- break;
- case -010:
- //丢失引号
- JOptionPane.showMessageDialog( null , "SQL语句丢失引号" ,"SQL信息" , JOptionPane.ERROR_MESSAGE) ;
- break;
- case -060:
- //某特定数据类型的长度或者标量规范无效
- JOptionPane.showMessageDialog( null , "某特定数据类型的长度或者标量规范无效" ,"SQL信息" , JOptionPane.ERROR_MESSAGE) ;
- break;
- case -102:
- //字符串常量太长
- JOptionPane.showMessageDialog( null , "字符串常量太长" ,"SQL信息" , JOptionPane.ERROR_MESSAGE) ;
- break;
- case -104:
- //SQL语句中遇到非法符号
- JOptionPane.showMessageDialog( null , "SQL语句中遇到非法符号" ,"SQL信息" , JOptionPane.ERROR_MESSAGE) ;
- break;
- case -433:
- //指定的值太长
- JOptionPane.showMessageDialog( null , "指定的值太长" ,"SQL信息" , JOptionPane.ERROR_MESSAGE) ;
- break;
- case -405:
- //数值文字超出了范围
- JOptionPane.showMessageDialog( null , "数值文字超出了范围" ,"SQL信息" , JOptionPane.ERROR_MESSAGE) ;
- break;
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |