笔记jdbcJava相关课程系列之四_第1页
笔记jdbcJava相关课程系列之四_第2页
笔记jdbcJava相关课程系列之四_第3页
笔记jdbcJava相关课程系列之四_第4页
笔记jdbcJava相关课程系列之四_第5页
已阅读5页,还剩16页未读 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

目一、JDBC概 什么是 SQL 如何使用Java连接某种数据 二、JDBC 案例:使用JDBC连接数据库,并操作SQL语 案例:通过JDBC创建 案例:使用JDBC向表中插入数 遍历Student_chang 三、JDBC Statement的缺 PreparedStatement的优 PreparedStatement的常用方 案例详见第五章StudentDAO 四、Connection封 五、 DAO Properties 案例:系 六、批处 JDBC批处理 案例:详见8.4案例 七、事务处 事务特性 JDBC中对事务的支持 八、DAO事务封 ThreadLocal原 原理 ThreadLocal 案例:登录系统(使用ThreadLocal实现连接共享 九、分页查 Oracle分页查询SQL语 MySQL分页查询SQL语 一、JDBC概述什么Java的设计者希望使用相同的方式不同的数据库JDBCJava用于统一连接数据库并操作数据库的一组通用接口定义(即通过一系列接口定义了数据库的通用APICvaaC(实现什么是驱动SQL如何使用Java连接某种数据库需要两个部分:1)JDBC连接数据库(导入某数据库的.jar包2)提供对该数据库的驱动包(使用静态方法Class.forName驱动连接数据库并操作PreparedStatement连接数据库时常见的错误ClassNotFoundExceptionportnumber①连接数据库时输入数据库路径时没有添加端②Oracle数据库的完整写法应为:jdbc:oracle:thin:@IP地址:端:数据库注意事项:Oracle数据库默认端1521。MySql数据库默认端为3306二、JDBCjava.sql.Connnection包,与特定数据库进行连接(会话java.sql.StatementSQLResultSetexecuteQuery(Stringsql)throwsSQLExceptionSQL(SQLSELECT语句ResultSetbooleanexecute(Stringsql)throwsSQLExceptionSQL语句,该语句可能返回多个结果。如果第一个结果为ResultSet对象,则返回true;如果其为更新计数或者false2.6案例注释。intexecuteUpdate(Stringsql)throwsSQLExceptionSQL语句,该语句回值:①对于数据操作语句(DML语句DDL0。booleanexecute(Stringsql)方法:返回结果为true、false,常用与执行表级操作的SQL(ResultSetfalseintexecuteUpdate(Stringsql)throwsSQLExceptionint,返回值为当前执SQLinsert、update、delete语句。SocketStatementResultSet它的next()方法包含了是否有下一条记录的hasnext()方法。int1JavaJDBCConnectiongetConnection(Stringurl,Stringuser,Stringpassword)方法:静态方法,建立与给定数据库URL的连接(DriverManager试图从已的JDBC驱动程序集中选择一个适DriverManager如何知道某种数据库已的OracleDriverJDBCDriver的子类,它被要求在静态初始化的时候要将自身驱动的信息通过DriverManager的静态方法进去,这样DriverManager就知道应该如何通OracleDriver去连接该数据库了。所以之后就可以通过DrvierManagerConnectionIDJava提供的支持(2.8案例UUID类:UUID.randomUUID().toString()36Oracle提供的支持(8.4sys_guid()32案例:使JDBC连接数据库,并操SQL语句/**连接数据库一定要捕获异常的Connectionconn=null;//tryfinally块中关闭它,同时局部变量在使try{/**与数据库进行连接分为两步:1)驱动:不同的数据库实现不尽相同,所以相同,都是驱动。而对于驱动包路径,名字是固定的,基本上不会变的!2)根据数据库的位置(路径)以及用户名和进行连接*//**路径:不同数据库连接的路径写法不尽相同,Oracle其中HOST包含两部分:IP地址和端 ;本机则使用localhost或*//**SQLSQLSQLStatement*/Statementstate=conn.createStatement();/**user_tables是Oracle用 当前用户创建的所有表的信息其中一个字段叫table_name用户保存的表名Stringsql="SELECTtable_nameFROM/**通过StatementStatement会将查询结果 到ResultSet中*/ResultSetrs=state.executeQuery(sql); /**1对索引的习惯不同StringtableName=rs.getString(1);}/**socket和流,但我们不用关心使用字符还是字节接收,都Statement做了*/ }catch(Exception }finally{}finally{ try }catch(SQLExceptione) }SQL案例:通JDBC创建表ConnectionConnectionconn=null;try{//1 //2importjava.sql.*,但全导入较耗费性能//3SQLStatementStatementstate=conn.createStatement();"idvarchar2(36)PRIMARYKEY,"+"namevarchar2(30),"+"agenumber(2),"+" varchar2(2)"+")";//execute()2.2if(!state.execute(sql)){System.out.println(" }catch(Exception }finally{ try }catch(SQLExceptione) }案例:使用JDBC向表中插入数据ConnectionConnectiontry{Class.forName("oracle.jdbc.driver.OracleDriver");Statementstate=conn.createStatement();//UUIDStringuuid=UUID.randomUUID().toString(); Stringsql="INSERTINTOStudent_changVALUES('"+uuid+"','Chang',22,'1')";//Stringsql="INSERTINTOStudent_chang//insert0,executeUpdate}}catch(Exception }finally{ try conn.close();}catch(SQLExceptione) 遍历Student_changConnectionConnectiontry{StatementStringsql="SELECT*FROMStudent_chang";ResultSetrs=state.executeQuery(sql); Stringid=rs.getString(1);Stringname=rs.getString("name");//不知第几列也可写列名intage=rs.getInt("age"); }}catch(Exception }finally{ try conn.close();}catch(SQLExceptione) 三、JDBCAPI:PreparedStatementStatement的缺点用Statement操作时代码的可读性和可性差,编写SQL语句复杂StatementSQL不安全可能出现SQL注入,详见9.6案例step3扩展:XSS、html代码注入、struts2OGNL存在可以执行底层操作系PreparedStatement的优点PreparedStatementSQLPreparedStatement对象中的“?”)setString、setInt、setDouble……等方法来提供。由于PreparedStatement对象已预编译过,所以其执行速度要快于Statement对象。因SQLPreparedStatement对象,以提高效率。3)PreparedStatement继承于Statement,其中三种方法:execute、executeQuery、executeUpdatePreparedStatement时已经将SQLSQL。PreparedStatement可以防止SQL注入2StatementPreparedStatement的常用方法execute方法处理这些复杂的语句,executeQueryexecuteUpdate处理形式更简单的语句。ResultSettrue;如果第一个结果是更新计数或者没有结果,false。ResultSetexecuteQuery():在此PreparedStatement对象中执行SQL查询,并返回该查ResultSet对象。intexecuteUpdate()PreparedStatementSQL语句,该语句必须是一DDL语句。voidaddBatch()PreparedStatement对象的批处理命令中。其他1SQLsetIntsetString等。案例详见第五章StudentDAO四、Connection封装DBUtilsprivatestaticStringdriver; privatestaticStringurl;privatestaticStringuser; privatestaticStringpassword;static{//5.4step2tryPropertiespropsnewProperties();//Propertiesdriver=props.getProperty("driver");url=props.getProperty("url");user=password=props.getProperty("password");}catch(IOExceptione) }catch(ClassNotFoundExceptione) }/**封装连接操作,供其他类继承,再次使用数据库连接的时候,可以直接调用openConnectionurl、user、pwd通过上面的.properties文件加载*/protectedstaticConnectiongetConnection()throwsSQLException{returnDriverManager.getConnection(url,user,pwd);}/***/protectedstaticvoidcloseConnection(Connectionconn){try{conn.close();}catch(SQLExcptione) }//catch}五、持久类封装DAOJava的对象并返回(即读数据Java的对象转Javaentity,DAO要达到的目的:对数据库数据的操作Java比如:Student表有字段id、name、age、,则对应的Java类中有Student类,属性id、name、ageProperties用于“.properties”文本文件的类,导入java.util.Properties包Properties类可以方便的properties文件,并将内容以类似HashMap的形式进。perties注意事项 的都是字符串!不用写双引号,无空格4)getProperty(Stringkey方法:该方法可以从properties文件中获取数据,如:jdbc.driver=oracle.jdbc.driver.OracleDriverjdbc.driver以key作为参数调用方法。oracle.jdbc.driver.OracleDriver了。案例:系统step1:StudentpublicclassStudentimplementsprivatestaticfinallongprivateStringprivateStringprivateintprivate;}StudentStudent表的一行数step2:BaseDAO父类(DAO都需要具备的特性privatestaticPropertiesproperties=newprivatestaticStringprivatestaticStringurl="";//"jdbc:oracle:thin:@0:1521:tarena";privatestaticStringuser="";//"jsd1304";privatestaticString/**在静态初始化 驱动,驱动不需要重 ,所以静态初始化最合 驱 try{/**加载配置文件, 配置信息perties中的内容见5.3*//** }catch(Exceptione){thrownewRuntimeException(e);// 失败,我们要通知调用 }/**Connection让外界去捕获异常,连接不上数据库该怎么办?*/protectedstaticConnectiongetConnection()throwsSQLException{return /**将给定的数据库连接关闭protectedstaticvoidcloseConnection(Connection tryconn.close(catch(SQLExceptione)/catch step3:StudentDAO类(Student表)BaseDAOpublicpublicStudentfindStudentByName(Stringname){Connectionconn=null; 使用 Stringsql="SELECT*FROMstudent_changWHEREname='"+name+"'";Stringsql="SELECT*FROMstudent_changWHEREname=?";state.setString(1,name);//给第一个问号赋值/**Student 使用使用if(rs.next()){Studentstudent=newStudent();student.setId(rs.getString("id"));student.setName(rs.getString("name"));student.setAge(rs.getInt("age"));student.set(rs.getString("")); returnstudent; }catch(Exception try conn.close();}catch(SQLExceptione) return /**StudentStudent*/publicbooleansaveStudent(Studentstudent){Connectiontry{// //BaseDAOgetConnection()方法获取数据库连接 Statement "sys_guid()," SQLSQL更像是一个格式或者模版*/

PreparedStatementstate=conn.prepareStatement(sql);state.setString(1,student.getName());//将第一个问号替换为学生的state.setInt(2,student.getAge());state.setString(3, return return }//}catch(Exception try conn.close();}catch(SQLExceptione) return step4:StudentService类(业务逻辑类privateprivateStudentDAOstudentDAO=newStudentDAO();publicvoidreg(Stringname,intage,String /**if(name==null||"".equals(name)){System.out.println("}elseif(age<1||age>99){ }elseif(studentDAO.findStudentByName(name)!=null){}else{//1StudentStudentstudent=newStudent(); //2DAO3 失败 }publicvoidfindStudentByName(String//对用户输入的信息进行必要的判断,nullif(name!=null&&Studentstudent=studentDAO.findStudentByName(name); StringStringStudentServiceservice=newStudentService();StringstudentName1="changyb";intage=16; StudentServiceservice1=newservice1.reg(studentName1,age,六、批处理批处理的优点SQLSQL语句JDBC批处1)addBatch(Stringsql):StatementSQL语句添加到Statement对象令列表中缓存(每调用一次缓存一条SQLSQL3executeBatch()语句提交给数据库进行处理。这样可以有效的减少网络通信带来的性能消耗4)clearBatch()SQLSQL案例:详8.4七、事务处理事务特性(atomicity(consistency(isolation(durabilityJDBC中对事务的支持(API)JDBCSQLmt(false);//不提3) mit(;//提交务4)conn.rollback(;//回事务八、DAO事务封装ThreadLocal原理JavaThreadLocal:用于实现线程内的数据共享,即对于相同的程序代码,多个模块(方法)在同一个线程中运行时要共份数据,而在另外线程中运行时又共HashMaphashMap=newvoidset(Objectobj){ Objectget(){ returnhashMap.get(Thread.currentThread());}}ThreadLocal内部很简单:就是者一个HashMap,其中key存放的是每一个线程,valueThreadLocal实例,只能保存一个线ThreadLocalHashMaphashMap=newvoidset(Objectobj){ Objectget(){ returnhashMap.get(Thread.currentThread());}}原理图ThreadLocalpublicTget():用于获取线程共享的数据。2)publicvoidset(Tvalue):用于保存线程共享的数据。3)publicvoidremove():移除线程中保存的数据。remove()keyset(null)key案例:登录系统(使用ThreadLocal实现连接共享)step1UserInfoget/setprivatestaticfinallongprivateStringprivateStringprivateStringprivateintprivate privateStringprotectedstaticConnectiongetConnection()throws/**protectedstaticConnectiongetConnection()throws/**当一个线程调用该方法要获取连接时,我们先检查之前这个线程是否已经获取 接了,若有就不再创建了*/Connectionconn=localConn.get();//get//将创建出来的连接放入线程共享中,set return step35.2案例中的BaseDAOcloseConnection()protectedstaticvoidcloseConnection(){protectedstaticvoidcloseConnection(){try{Connectionconn=localConn.get(); localConn.remove();//key也没了,或者localConn.set(null);key还保留}}catch(Exception step4beginprotectedstaticvoidtry{Connection}}catch(Exception }protectedstaticvoidprotectedstaticvoidUserInfoDAOconn,即不用再传参数*/Connection try }catch(SQLExceptione) step6rollbackprotectedprotectedstaticvoid/**UserInfoDAOconn*/Connectionconn=localConn.get(); try }catch(SQLExceptione) }privatestaticfinalStringprivatestaticfinalStringINSERT="INSERTINTOuserinfo_chang("+ /**保存给定的所有用户信息publicbooleansave(List<UserInfo>userInfos){Connectionconn=null;try{ longstart=System.currentTimeMillis(); for(inti=0;i<50;i++){//50 state.setString(1,"test"+ state.setString(2,"12345"+ state.setString(5,"test"+i state.addBatch();//Statementsql for(UserInfouserinfo:userInfos){//集合中的记录,并存入数据库,集合不能state.setString(1,userinfo.getName());state.setString(2,userinfo.getPassword());state.setInt(3,userinfo.getAge());state.setString(4,userinfo.get());state.addBatch();//Statementsql语句写入参数列表} returntrue;//true,告知调用者保存成功}catch(Exceptione){ }finally{//closeConnection(conn); return /**publicvoidcreateTable(){Connectionconn=null;try{Statement"passwordVARCHAR2(50),ageNUMBER(2),"+if(!state.execute(sql)){System.out.println("创建完毕");}}catch(Exception}finally{ }}}九、分页查询分页查询的基本原理Connectionconn=getConnection();PreparedStatementConnectionconn=getConnection();PreparedStatementstate=conn.prepareStatement(sql);intstart=rowsPerPage*(1)+1;//每页的开始intend=start+rowsPerPage;//每页的结束state.setInt(1,end);state.setInt(2,start);ResultSetrs=state.executeQuery();List<Service>list=newArrayList<Service>(); 为何使用分页查询每次只向数据库要求一页的数据量,频繁数据库,内存压力小,适合大数据量SQL语句不尽相同。所以,使用不同的数据库,我们要适应当前数据库对分页语句的定义。当然,hibernate了数据库分页的差异。可以让我们很方便的使用统一方式Oracle分页查SQL语句Oraclerownum,使用该字段对查询的行数进行限制,从而rownumoraclerownum1rownum2,依此类推。start=rows×(每页的结束位置end=start+java的一种习惯,不是必须的算法

或end=page*from(selectid,account_id,host,user_name,login_password,status,create_date,pause_date,close_date,cost_id,rownumrfromservicewhererownum<?)wherer*rownumrownumMySQL分页查SQL语句select*fromtablelimit注意事项:start0开始,pageSize“假”分页1)把数据全部取出来放在缓存中,根据用户要看的页数(page)和每页记录(pageSize)4将数据库数据读入结果集,每次查看指定的页时,要求结果集的指针能够跳到)案例:分页查询step1:在8.4案例中step7的UserInfoDAO类添加分页查询方法和根据用户名、获取用/**分页查询用户信息。page:第几页。rows*/publicList<UserInfo>findPaging(intpage,introws){try{/***/intstart=(1)*rows+1;intend=page*rows;//java区间定位,第二次再将前区间定位。从而获取区间中的数据。*///*rownumr后有一个空格Stringsql="SELECT*FROM"+"(SELECT ,rownumr""FROMuserinfo_changWHERErownum<?)WHEREr>=?////Connection//PreparedStatement//connBaseDAO去关(统一线

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论