Db2知识点和作业知识点讲解
Java连接数据库基本步骤:
1.加载jdbc驱动程序:
Static
{
Try{
Class.forName(“COM.ibm.db2.jdbc.app.DB2Driver”);
}
Catch(exception e){
E.printstacktrace();
}
}
2. 创建数据库的连接
String url = “jdbc:db2:sample”;//欲连接的数据库路径
String userid=”db2admin”;//用户名
String passwd=”db2admin”;//密码
Connection sample=DriverManager.getConnection(url,userid,passwd);
或者:
Connection sample=Drivermanager.getConnection(“jdbc.db2.sampe”,”db2admin”,”db2admin”)
3.创建preparedStatement/statement语句
Preparedstatement 一般用于sql语句有?的,不可以直接执行的语句。
创建:
String Sql=”insert into templ(empno,firstnme,lastname,edlevel) values
(?,1,2,3)”
Preparedstatement pstmt=sample.preparestatement(sql);
给第一个问号赋值(从1开始):
如果是字符串:
pstmt.setString(1,deptno);
如果是数字:
pstmt.setInt(1,deptno);
Statement 就是没有?可以直接执行的
Statement stmt=sample.creatstatement();记住:无参数
4.执行sql语句:
第一种查询语句
创建结果集:
对于:preparedstatement
Resultset rs=pstmt.executeQuery();
对于:statement 前面说了statement可以直接执行sql语句
Resultset rs=stmt.executeQuery("SELECT EMPNO, LASTNAME " +
" FROM TEMPL " + " WHERE SALARY > 40000 ")
第二种插入,更新,删除语句,这个不会返回结果集,返回值为更新数据的个数,我们用int接受
对于:preparedstatement
Int rows=pstmt.executeUpdate();
对于:statement 前面说了statement可以直接执行sql语句
Int rows=stmt.executeUpdate(“insert into templ(empno,firstnme,lastname,edlevel) values (0,1,2,3)”)
(ps:不存在:executeinsert.executedelete,嘻嘻!!!)
5.前面提到查询语句(select语句)会返回结果集,我们可以便利结果集查询里面的内容,插入,删除,更新语句不行
Statement://一般用于sql语句没有?的,可以直接执行的语句
String sql =“select NAME, JOB, SALARY from staff Where ID = 10”;//
sql语句
Statement stmt = sample.createStatement();//创建statement语句
ResultSet rs = stmt.executeQuery( sql);//执行,并存入结果集
语句:
while(rs.next()){
String data1 = rs.getString(1) ; //从1开始
String data2 = rs.getString(2) ;
String data3 = rs.getString(3) ;
}
PreparedStatement:
String sql=“select NAME, JOB, SALARY from staff Where ID = 10”;
Preparestatement pstmt=sample.preparestatement(sql);
Resultset rs=pstmt.executequery();
语句:
while(rs.next()){
String data1 = rs.getString(1) ; //从1开始
String data2 = rs.getString(2) ;
String data3 = rs.getString(3) ;
}
getString最常用,指取出的那一列属性的是字符串类型,如果那一列属性是整数类型,就用getInt
6. 关闭jdbc对象资源
操作完成以后要把所有使用的JDBC对象全都关闭,以释放JDBC资源,关闭顺
序和声明顺序相反:
1、先关闭ResultSet
2、再关闭preparedStatement
3、最后关闭连接对象connection
if(rs != null){ // 关闭记录集
try{
rs.close() ;
}catch(SQLException e){
e.printStackTrace() ;
}
}
if(stmt != null){ // 关闭声明 preparestatement类似
try{
stmt.close() ;
}catch(SQLException e){
e.printStackTrace() ;
}
}
if(sample != null){ // 关闭连接对象
try{
Sample.close() ;
}catch(SQLException e){
e.printStackTrace() ;
}
}
7.设置是否自动提交:
sample.setAutoCommit(false); 否,不立即更新数据库
sample.setAutoCommit(true); 是,立即更新数据库
7.判断和设置结果集中某个数据是否为空:
判断:
这个是前面查询结果集的截图
(https://img-blog.csdnimg.cn/20210107153103592.png)
如果我们要判断最后接收的值是否是空值
我们可以把上面语句改为:
while(rs.next()){
String data1 = rs.getString(1) ; //从1开始
String data2 = rs.getString(2) ;
String data3 = rs.getString(3) ;
if ( rs.wasNull() ) //
{ System.out.println ("\n Edlevel is null for EMPNO \n");
System.out.println (eno);
}
}
设置某个值为空:
这个就只能使用preparedstatement语句
pstmt.setNull (1, java.sql.Type.SMALLINT);
setNULL(a,b)第一个参数是参数的位置,第二个参数的参数的类型;上面的是 smallint类型的,别忘了java.sql.Type
8.处理异常:当然更新的数据若为空当然就不用判断了!!!所以可以在判断异常前判断更新数据是否为空,也可以不判断,毕竟概率不大
try {
sql = “DELETE FROM TEMPL WHERE EMPNO = 999”;
psstmt = con.prepareStatement(sql);
deleteCount = psstmt.executeUpdate();
if (( SQLWarn = psstmt.getWarnings()) !=null)
{
System.out.println ("\n Warning received on a DELETE \n");}
} // end try
catch (SQLException x)
{ if (x.getSQLState().equals(“42818”))
{ System.out.println ("\n Operand data types not compatible \n");
} // end if 判断当前异常为什么类型,42818是参数类型不匹配
else { System.out.println ("\n Error deleting from TEMPL \n");
System.out.println ("\n Value of SQLCODE is: \n");
SQLCode = x.getErrorCode();
System.out.println (SQLCode);
} // end else
} // end catch
9.
这个我也没搞懂!!!好像没考到,作业也没有
参考:https://blog.csdn.net/qq_26975307/article/details/54412067
10.
通过游标更新数据库:
https://blog.csdn.net/qq_26975307/article/details/54412067
和上面网址一样:
简而言之:
就是你要插,删,更某个数据,只是知道获取这个数据的某个判断条件,就可以使用
下面一个例子:
有时你的判断条件是基于游标位置:下面对更新游标位置的说明:
boolean next()游标位置后移一个,如果当前是最后一行了,那么返回false
boolean previous()游标位置前移一个,如果当前是第一行,则返回false
oolean first() 游标位置返回第一行,如果不存在(查询结果为空),那么返回false
boolean last()游标位置返回最后一行,如果不存在(查询结果为空),那么返回fals
void beforeFirst()返回到最开始,它的下一行是第一行数据。
void afterLast()返回到最后,它的上一行是最后一行数据
boolean relative(int n) 以当前位置为基准,跳n个位置,如果n为正那么往后移动n行,如果为负那往前移动n行。
boolean absolute(int n)为正,则以第一行为基准,跳到第n行,为负,则从最后一行往前跳n行.
11.DatabaseMetaData
参考:https://www.cnblogs.com/shide/p/3340906.html
DatabaseMetaData可以得到数据库的信息,如数据库名称,表名,什么的。
12.batch功能
主要实现批量处理
他是PreparedStatement类型的一个函数
例子:
首先声明两个数组:
short [] edLvl = { 14, 18, 16 };
String [] workDpt = { “D11”, “D01”, “B01” };
一个SQL语句
String exSql = "UPDATE EMP SET EDLEVEL = ? "
- "WHERE WORKDEPT = ? ";
声明preparedstatement:
PreparedStatement ps = con.prepareStatement(exSql);
利用循环和addbatch()函数将sql语句添加到ps中
for (int i=0; i < edLvl.length; i++ ) {
ps.setShort (1, edLvl [i]);
ps.setString(2, workDpt [i]);
ps.addBatch(); // Add a statement to a current batch
}
执行sql语句:(注意这里返回的是数组)
int [] rowCounts = ps.executeBatch();
13.sqlj(略)都差不多就是这个要连接上下文,我们作业没有,所以不考
14.与client连接(压根没讲,也可能我没听,滑稽!)
15clob
例子:
String resume = null;
String empnum = “000130”;
int startper, startper1, startdpt = 0;
PreparedStatement stmt1, stmt2, stmt3 = null;
String sql1, sql2, sql3 = null;
String empno, resumefmt = null;
Clob resumelob = null;
ResultSet rs1, rs2, rs3 = null;
sql1 = "SELECT POSSTR(RESUME,‘Personal’) "
- "FROM EMP_RESUME "
- "WHERE EMPNO = ? AND RESUME_FORMAT = ‘ascii’ ";
stmt1 = con.prepareStatement (sql1);
stmt1.setString ( 1, empnum);
rs1 = stmt1.executeQuery();
while (rs1.next()) {
startper = rs1.getInt(1); //获取’Personal’字节的起始位置
} // end while
sql2 = "SELECT POSSTR(RESUME,‘Department’) "
- "FROM EMP_RESUME "
- "WHERE EMPNO = ? AND RESUMEFORMAT = ‘ascii’ ";
stmt2 = con.prepareStatement (sql2);
stmt2.setString ( 1, empnum);
rs2 = stmt2.executeQuery();
while (rs2.next()) {
startdpt = rs2.getInt(1); //获取Department的起始位置
} // end while
startper1 = startper - 1;
sql3 = "SELECT EMPNO, RESUME_FORMAT, "
- "SUBSTR(RESUME,1,?)|| SUBSTR(RESUME,?) AS RESUME "
- "FROM EMP_RESUME "
- "WHERE EMPNO = ? AND RESUME_FORMAT = ‘ascii’ ";
stmt3 = con.prepareStatement (sql3);
stmt3.setInt (1, startper1);
stmt3.setInt (2, startdpt);
stmt3.setString ( 3, empnum);
rs3 = stmt3.executeQuery();
while (rs3.next()) {
empno = rs3.getString(1);
resumefmt = rs3.getString(2);
resumelob = rs3.getClob(3);
long len = resumelob.length();
int len1 = (int)len;
String resumeout = resumelob.getSubString(1, len1);
} // end while
这样就把上面图中的personal部分去掉了。
16.blob参考下面任务10
下面内容来自某个学长
连接:
内容下载连接
https://github.com/Xing-hui/db2
学长CSDN
https://blog.csdn.net/y_silence_/article/details/84146417?utm_medium=distribute.pc_relevant_download.none-task-blog-BlogCommendFromBaidu-2.nonecase&depth_1-utm_source=distribute.pc_relevant_download.none-task-blog-BlogCommendFromBaidu-2.nonecas
实验报告知识点:
任务1:没东西
任务2:没东西
任务3:没东西
任务4:
String inputValue = JOptionPane.showInputDialog(“Please input a
value”);//输入的东西保存在inputValue
JOptionPane.showMessageDialog(null, "\nNumber of rows updated: " +
updateCount);//弹出一个输出框
任务5:
表格的相关操作,创建表格
String[] Names = { “编号”, “名字”, “姓氏”, “职位”};//表头
Object[][] Info = new Object[4][4];//表格内容,几行几列
JTable table = new JTable(playerInfo, Names);//创建表格
表格主要的库函数:
- 取单元格数据
String cellValue=(String) tableModel.getValueAt(row, column);// 取单元
格数据,row是行号,column是列号 - 给单元格数据赋值,即给二维数组赋值,一般用ResultSet结果集赋值上面
的Info
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
{
System.out.println(j+“ci”);
info[i][j]=rs.getString(j+1);
}
}
单 行 插 入 String single_insert =“insert into templ(empno,firstnme,lastname,edlevel) values (?,?,?,?)”;
多行插入 int count =4;//用户想插入四行
String sql=“insert into templ(empno,firstnme,lastname,edlevel) values
(?,?,?,?)”;
for(int i=0;i<4;i++)
{
sql=sql+",(?,?,?,?)";
}
通 过 子 查 询 插 入 S t r i n g f i n d _ i n s e r t = " i n s e r t i n t o
t e m p l ( e m p n o , f i r s t n m e , l a s t n a m e , e d l e v e l ) s e l e c t
empno,firstnme,lastname,edlevel from employee where empno=? and
firstnme=? and lastname=? and edlevel=?";
任务6:ResultSet的wasNull()方法
表示它的下一列是不是空
任务7:
没东西(上面讲过了,看下代码记住每个编号干嘛的就好)
任务8:
第一问:没东西
第二问:实现对结果集的任意行,任意列的修改
- 方法一: String finalstr="";
- S t r i n g s e l e c t f o r u p d a t e = " s e l e c t
empno,firstnme,lastname,edlevel,job from employee" - +" for update";//sql语句,不要忘记加上for update!!
int finalrow=0;
int finalcolmn=0; - int r= table.getSelectedRow();//得到表格被选中的行数,与结
果集对应 finalrow=r;
int c=table.getSelectedColumn();//得到表格被选中的列数,与结果集
对应 finalcolmn=c; - stmt=sample.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,Res
*ultSet.CONCUR_UPDATABLE); //创建可滚动,可更新的结果集 - ResultSet select_rs=stmt.executeQuery(selectforupdate);
- for(int i=0;i<finalrow;i++)
- {
- select_rs.next();//结果集移动到第finalrow行
- }
- if(select_rs.next())
- {
- select_rs.updateObject(finalcolmn,finalstr);//更新结果集的
第finalcolumn列,更新为finalstr - }
- select_rs.updateRow();//将结果集落实到数据库
- 方法二: * String finalstr="";
- S t r i n g s e l e c t f o r u p d a t e = " s e l e c t
empno,firstnme,lastname,edlevel,job from employee" - +" for update";//sql语句,不要忘记加上for update!! int
finalrow=0; int finalcolmn=0; - int r= table.getSelectedRow();//得到表格被选中的行数,与结
果集对应 - finalrow=r;
- int c=table.getSelectedColumn();//得到表格被选中的列数,
与结果集对应 - finalcolmn=c;
*stmt=sample.createStatement(ResultSet.TYPE_SCROLL_IN-SENSITIVE,ResultSet. - CONCUR_UPDATABLE);
- ResultSet select_rs=stmt.executeQuery(selectforupdate);
- select_rs.absolute(finalrow+1);//直接定位到第finalrow+1行
- select_rs.updateObject(finalcolmn+1,finalstr);
- select_rs.updateRow();
*/
任务9:
Section3.2:创建可滚动的结果集,使用last,previous,first函数遍历
String sql=“select NAME,JOB,SALARY from staff”;
P r e p a r e d S t a t e m e n t
stmt=sample.prepareStatement(sql,rs.TYPE_SCROLL_INSENSITIVE,rs.CO
NCUR_READ_ONLY); //为了创建可滚动,只读的结果集
ResultSet rs = stmt.executeQuery( );
rs.last();
rs.previous();
rs.first();
知识:
rs.absolute()//绝对位置,负数表示从后面数
rs.first()第一条
rs.last()最后一条
rs.previoust()前一条
rs.next()后一条
Section3.3:批处理操作,同时执行多条语句
Statement接口里有两个方法:
void addBatch(String sql)
将给定的 SQL 命令添加到此 Statement 对象的当前命令列表中。通过调用方
法 executeBatch 可以批量执行此列表中的命令。
int[] executeBatch()
将一批命令提交给数据库来执行,如果全部命令执行成功,则返回更新
计数组成的数组。
返回:
包含批中每个命令的一个元素的更新计数所组成的数组(数组中的每个元素为:
成功处理了命令后,执行命令所影响数据库中行数的更新计数)。数组的元素
根据将命令添加到批中的顺序排序。
批处理操作,即同时执行多条语句
代码:
Statement stmt=sample.createStatement();
stmt.addBatch(“INSERT INTO DB2ADMIN.DEPARTMENT " + “VALUES (‘BT6’,‘BATCH6 NEWYORK’,‘BBBBB1’,‘BTT’,‘NEW
YORK CITY6’)”);
stmt.addBatch(“INSERT INTO DB2ADMIN.DEPARTMENT " +
“VALUES (‘BT7’,‘BATCH7 NEWYORK’,‘BBBBB2’,‘BT2’,‘NEW
YORK CITY7’)”);
int []updateCounts=stmt.executeBatch();
sample.commit();
Section3.4:取数据库结构
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 catalog:要获得表所在的编目。"“”“意味着没有任何编目,Null
表示所有编目。
String schema:要获得表所在的模式。”“”"意味着没有任何模式,
Null表示所有模式。
String tableName:指出要返回表名与该参数匹配的那些表。
String types:一个指出返回何种表的数组。
可能的数组项是:“TABLE”、“VIEW”、“SYSTEM TABLE”, “GLOBAL
TEMPORARY”,“LOCAL TEMPORARY”,“ALIAS”,“SYSNONYM”。
通过getTables()方法返回的结果集中的每个表都有下面是10字段的描
述信息,而且只有10个。通常我们用到的也就是标红的几个字段。而且在结果
集中直接使用下面字段前面的序号即可获取字段值。
1.TABLE_CAT (String) => 表所在的编目(可能为空)
2.TABLE_SCHEM (String) => 表所在的模式(可能为空)
3.TABLE_NAME (String) => 表的名称
任务10:blob类型对象的读取和插入
Blob类型的赋值,用setBinaryStream(int n, java.io.InputStream x, int
length)类型赋值,n指示参数编号的 int。InputStream 对象。length指示字
节数的 int。
查询图片代码:
Statement st=conn.createStatement();
ResultSet rs=st.executeQuery(“select image from employee”);
while(rs.next()) {
//读取Blob对象
Blob blob= (Blob) rs.getBlob(1);
//Blob对象转化为InputStream流
java.io.InputStream inputStream =blob.getBinaryStream();
//要写入的文件
File fileOutput = new File(“c:/backa.jpg”);
//文件的写入流的定义
FileOutputStream fo = new FileOutputStream(fileOutput);
int c;
//读取流并写入到文件中
while ((c = inputStream.read()) != -1)
fo.write©;
//流的关闭:
fo.close();
}
插入图片代码:
PreparedStatement preparedStatement = conn
.prepareStatement(“insert into emp_photo values(‘000130’,‘jpeg’,?)”);
//创建文件对象:
File file=new File(“e:/123.jpg”);//参数是本地图片的路径名
// 创建流对象:
BufferedInputStream imageInput = new BufferedInputStream(
new FileInputStream(file));
//参数赋值:
preparedStatement.setBinaryStream(1, imageInput,(int) file.length());//
第二个参数InputStream 对象,第三个参数字节数int
//执行语句
preparedStatement.executeUpdate();
任务11:clob类型的读取
Clob resumelob = null;//定义clob类型
resumelob = rs3.getClob(3);//将结果集中第三个位置的clob取出 String detailinfo = resumelob.getSubString((long)1,
(int)resumelob.length());//将clob类型转化为字符串类型,参数固定,基本上
就这么写
还用到的sql函数
POSSTR(RESUME,‘Personal’)//查看Personal这个单词在RESUME中的位置
SUBSTR(RESUME,1,length)//取resume中1-length长度的字段