《传智播客Jdbc.ppt》由会员分享,可在线阅读,更多相关《传智播客Jdbc.ppt(38页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、高级软件人才实作培训专家高级软件人才实作培训专家!传智播客Jdbc Still waters run deep.流静水深流静水深,人静心深人静心深 Where there is life,there is hope。有生命必有希望。有生命必有希望高级软件人才实作培训专家高级软件人才实作培训专家!简介简介lJDBC(Java Data Base Connectivity,java数据库连接),由一些接口和类构成的API。lJ2SE的一部分,由java.sql,javax.sql包组成。北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!简介简介l应用程序、JDBC API、数据库
2、驱动及数据库之间的关系北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!连接数据的步骤连接数据的步骤l注册驱动(只做一次)l建立连接(Connection)l创建执行SQL的语句(Statement)l执行语句l处理执行结果(ResultSet)l释放资源快速起步示例北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!注册驱动lClass.forName(“com.mysql.jdbc.Driver”);推荐这种方式,不会对具体的驱动类产生依赖。lDriverManager.registerDriver(com.mysql.jdbc.Driver);会造成Dr
3、iverManager中产生两个一样的驱动,并会对具体的驱动类产生依赖。lSystem.setProperty(“jdbc.drivers”,“driver1:driver2”);虽然不会对具体的驱动类产生依赖;但注册不太方便,所以很少使用。l驱动类型(四种类型)北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!建立连接(Connection)lConnection conn=DriverManager.getConnection(url,user,password);lurl格式:JDBC:子协议:子名称/主机名:端口/数据库名?属性名=属性值&lUser,password
4、可以用“属性名=属性值”方式告诉数据库;l其他参数如:useUnicode=true&characterEncoding=GBK。北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!创建执行SQL的语句(Statement)lStatement Statement st=conn.createStatement();st.executeQuery(sql);lPreparedStatementString sql=“select*from table_name where col_name=?”;PreparedStatement ps=conn.preparedStateme
5、nt(sql);ps.setString(1,“col_value”);ps.executeQuery();北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!处理执行结果(ResultSet)ResultSet rs=statement.executeQuery(sql);While(rs.next()rs.getString(“col_name”);rs.getInt(“col_name”);/北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!释放资源l释放ResultSet,Statement,Connection.l数据库连接(Connection)是
6、非常稀有的资源,用完后必须马上释放,如果Connection不能及时正确的关闭将导致系统宕机。Connection的使用原则是尽量晚创建,尽量早的释放。北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!基本的基本的CRUD(创建、读取、更新、删除)(创建、读取、更新、删除)l模板代码 Connection conn=null;Statement st=null;ResultSet rs=null;try/获得Connection/创建Statement/处理查询结果ResultSet finally/释放资源ResultSet,Statement,Connection北京传智
7、播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!创建创建l增加对应SQL的INSERT,返回增加成功的行(记录)数 conn=getConnection();Statement st=conn.createStatement();String sql=“insert into user(name,age,regist_date)”+“values(name,10,now()”;int i=st.executeUpdate(sql);/i为插入的记录数北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!读取读取l读取(查询)对应SQL的SELECT,返回查询结果con
8、n=getConnection();st=conn.createStatement();String sql=select id,name,age,regist_date from user;rs=st.executeQuery(sql);while(rs.next()System.out.print(rs.getInt(id)+tt);System.out.print(rs.getString(name)+tt);System.out.print(rs.getInt(age)+tt);System.out.print(rs.getTimestamp(regist_date)+tt);Syst
9、em.out.println();北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!更新更新l更新(修改)对应SQL的UPDATE,返回被修改的行(记录)数 conn=getConnection();Statement st=conn.createStatement();String sql=“update person set name=new name”;int i=st.executeUpdate(sql);/i为符合条件的记录数北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!删除删除l删除对应SQL的DELETE,返回被删除的行(记录)数 conn
10、=getConnection();Statement st=conn.createStatement();String sql=“delete from user where id=1”;int i=st.executeUpdate(sql);/i为删掉的记录数北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!CRUD总结总结l增、删、改用Statement.executeUpdate来完成,返回整数(匹配的记录数),这类操作相对简单。l查询用Statement.executeQuery来完成,返回的是ResultSet对象,ResultSet中包含了查询的结果;查询相对与增
11、、删、改要复杂一些,因为有查询结果要处理。北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!SQL注入注入,PreparedStatement和和Statement l在SQL中包含特殊字符或SQL的关键字(如:or 1 or)时Statement将出现不可预料的结果(出现异常或查询的结果不正确),可用PreparedStatement来解决。lPreperedStatement(从Statement扩展而来)相对Statement的优点:1.没有SQL注入的问题。2.Statement会使数据库频繁编译SQL,可能造成数据库缓冲区溢出。3.数据库和驱动可以对Prepered
12、Statement进行优化(只有在相关联的数据库连接没有关闭的情况下有效)。北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!数据类型数据类型l详细信息见java.sql.Typesl几种特殊且比较常用的类型1.DATA,TIME,TIMESTAMP date,time,datetime存:ps.setDate(i,d);ps.setTime(i,t);ps.setTimestamp(i,ts);取:rs.getDate(i);rs.getTime(i);rs.getTimestamp(i);2.CLOB text 存:ps.setCharacterStream(index,
13、reader,length);ps.setString(i,s);取:reader=rs.getCharacterStream(i);reader=rs.getClob(i).getCharacterStream();string=rs.getString(i);3.BLOB blob 存:ps.setBinaryStream(i,inputStream,length);取:rs.getBinaryStream(i);rs.getBlob(i).getBinaryStream();北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!一个简单用户相关的数据访问层一个简单用户相关的
14、数据访问层 lJ2EE三层架构简介表示层、业务逻辑层、数据访问层,三层之间用接口隔离。l定义domain对象User,定义存取用户的接口l用JDBC实现接口l用配置文件(properties)和反射实现与具体类的耦合 北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!事务事务(ACID)l原子性(atomicity):组成事务处理的语句形成了一个逻辑单元,不能只执行其中的一部分。l一致性(consistency):在事务处理执行前后,数据库是一致的(数据库数据完整性约束)。l隔离性(isolcation):一个事务处理对另一个事务处理的影响。l持续性(durability):
15、事务处理的效果能够被永久保存下来。lconnection.setAutoCommit(false);/打开事务。mit();/提交事务。lconnection.rollback();/回滚事务。北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!事务事务(SavePoint)l当只想撤销事务中的部分操作时可使用SavePointlSavePoint sp=connection.setSavepoint();lconnection.rollerbak(sp);mit();北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!事务事务(JTA)l跨越多个数据源的事务,
16、使用JTA容器实现事务。l分成两阶段提交。ljavax.transaction.UserTransaction tx=(UserTransaction)ctx.lookup(“jndiName);tx.begin();/connection1 connection2(可能来自不同的数据库)mit();/tx.rollback();北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!隔离级别隔离级别多线程并发读取数据时的正确性 lconnection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);lV
17、:可能出现,X:不会出现隔离级别隔离级别 脏读脏读 不可重复读不可重复读 幻读幻读 读未提交(Read uncommitted)VVV读已提交(Read committed)xVV可重复读(Repeatable read)xxV可串行化(Serializable)xxx北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!存储过程l存储过程CallableStatement(从PreperedStatement扩展来)cs=connection.prepareCall(“call psname(?,?,?)”);cs.registerOutParameter(index,Type
18、s.INTEGER);cs.setXXX(i,xxxx);cs.executeUpdate();int id=cs.getInt(index);北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!其他的几个其他的几个APIlPreparedStatement.getGeneratedKeys()PreparedStatement ps=connection.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);ps.executeUpdate();ResultSet rs=st.getGeneratedKeys();rs.g
19、etInt(1);l批处理,可以大幅度提升大量增、删、改的速度。PreparedStatement.addBatch();PreparedStatement.executeBatch();北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!其他的几个其他的几个APIl可滚动的结果集Statement st=connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);ResultSet rs=st.executeQuery(sql);rs.beforeFirst();
20、rs.afterLast();rs.first();rs.isFirst();rs.last();rs.isLast();rs.absolute(9);rs.moveToInsertRow();l可更新的结果集conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);rs.updateString(col name,new value);rs.updateRow();北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!DatabaseMetaData和ParameterMet
21、aDatalDatabaseMetaData meta=connection.getMetaData();l通过DatabaseMetaData可以获得数据库相关的信息如:数据库版本、数据库名、数据库厂商信息、是否支持事务、是否支持某种事务隔离级别,是否支持滚动结果集等。lParameterMetaData pmd=preparedStatement.getParameterMetaData();l通过 ParameterMetaData可以获得参数信息。北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!ResultSetMetaDatalResultSetMetaData
22、meta=rs.getMetaData();l通过ResultSetMetaData可以获得结果有几列、各列名、各列别名、各列类型等。l可以将ResultSet放入Map(key:列名 value:列值)。l用反射ResultSetMetaData将查询结果读入对象中(简单的O/RMapping)1)让SQL语句中列别名和要读入的对象属性名一样;2)通过ResultSetMetaData获得结果列数和列别名;3)通过反射将对象的所有setXxx方法找到;4)将3)找到的方法setXxx和2)找到的列别名进行匹配(即方法中的xxx于列别名相等);5)由上一步找到的方法和列别名对应关系进行赋值Me
23、thod.invoke(obj,rs.getObject(columnAliasName);北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!数据源和连接池数据源和连接池lDataSource用来取代DriverManager来获取Connection;l通过DataSource获得Connection速度很快;l通过DataSource获得的Connection都是已经被包裹过的(不是驱动原来的连接),他的close方法已经被修改。l一般DataSource内部会用一个连接池来缓存Connection,这样可以大幅度提高数据库的访问速度;l连接池可以理解成一个能够存放Con
24、nection的Collection;l我们的程序只和DataSource打交道,不会直接访问连接池;北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!一个简单的数据源一个简单的数据源实现l使用代理模式的Connection(核心代码)class MyConnection implements Connectionprivate Connection realConn;private LinkedList connPool;MyConnection(Connection rConn,LinkedList cPool)this.realConn=rConn;this.connP
25、ool=cPool;public void close()this.connPool.addLast(this);/.北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!一个简单的数据源一个简单的数据源实现lDataSource(核心代码)class MyDataSource implements DataSourceprivate LinkedList connPool=new Vector();public Connection getConneciton()if(this.connPool.size()0)return this.connPool.removeFirst(
26、0);return createConnection();private Connection createConnection()Connection realConn=DriverManager.getConnection();Connection myConn=new MyConnection(realConn,this.connPool);return myConn;/.北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!常用的开源实现DBCPl使用DBCP必须用的三个包:commons-dbcp-1.2.1.jar,commons-pool-1.2.jar,commo
27、ns-collections-3.1.jar。l配置参数。lJava API:BasicDataSourceFactory.createDataSource(properties);北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!使用继承优化JDBC代码(模板模式)l优化查询操作,区分开变化和不变的部分:sql和ResultSet的处理是变化部分,创建和释放资源部分是不变部分。l提取超类,将不变部分放入超类,变化部分留给子类实现。l超类的主要代码:public Object find(String sql,Object args)rs=ps.executeQuery();i
28、f(rs.next()return rowMapper(rs);protected abstract Object rowMapper(ResultSet rs);北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!使用组合优化JDBC代码(策略模式)l优化查询操作,区分开变化和不变的部分:sql和ResultSet的处理是变化部分,创建和释放资源部分是不变部分。l提取接口封装变化部分。lJDBC操作主要代码:public Object find(String sql,Object args,RowMapper rowMapper)rs=ps.executeQuery();if
29、(rs.next()return rowMapper.mapRow(rs);l回调接口:public interface RowMapper public Object mapRow(ResultSet rs)throws SQLException;北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!Spring的JdbcTemplatel查询带有参数,和行映射方法:public Object queryForObject(String sql,Object args,RowMapper rowMapper),使用自定义的UserRowMapper完成映射。l一个RowMapp
30、er的常用实现BeanPropertyRowMapper,该实现可将结果集转换成一个Java Bean(字段名与Java Bean属性名不符合规范,可用别名处理)。lpublic List query(String sql,Object args,RowMapper rowMapper)返回多个结果。lpublic int queryForInt(String sql)(如:select count(*)from user),其他结果比如String可用queryForObject方法向下转型。lpublic Map queryForMap(String sql,Object args)返回若
31、类型的Map(key:字段名或别名,value:列值)。lpublic List queryForList(String sql,Object args)返回多Map。北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!Spring的JdbcTemplatel更新public int update(String sql,Object args)。l插入数据并获得结果:public Object execute(ConnectionCallback action)l其他方法简介北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!Spring的NamedParame
32、terJdbcTemplatelNamedParameterJdbcTemplate内部包含了一个JdbcTemplate,所以JdbcTemplate能做的事情NamedParameterJdbcTemplate都能干;NamedParameterJdbcTemplate相对于JdbcTemplate主要增加了参数可以命名的功能。lpublic Object queryForObject(String sql,Map paramMap,RowMapper rowMapper)lpublic Object queryForObject(String sql,SqlParameterSource
33、 paramSource,RowMapper rowMapper)SqlParameterSource的两个主要实现MapSqlParameterSource和BeanPropertySqlParameterSourcelpublic int update(String sql,SqlParameterSource paramSource,KeyHolder generatedKeyHolder)保存数据获得主键。北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!Spring的SimpleJdbcTemplatelSimpleJdbcTemplate内部包含了一个NamedP
34、arameterJdbcTemplate;所以NamedParameterJdbcTemplate能做的事情SimpleJdbcTemplate都能干,SimpleJdbcTemplate相对于NamedParameterJdbcTemplate主要增加了JDK5.0的泛型和可变长度参数支持。lpublic List query(String sql,ParameterizedRowMapper rm,Object.args)lpublic T queryForObject(String sql,ParameterizedRowMapper rm,SqlParameterSource args
35、)lpublic List query(String sql,ParameterizedRowMapper rm,SqlParameterSource args)lgetJdbcOperations返回的是JdbcOperations(实现JdbcTemplate)lgetNamedParameterJdbcOperations返回的是NamedParameterJdbcOperations(实现是NamedParameterJdbcTemplate)北京传智播客教育 高级软件人才实作培训专家高级软件人才实作培训专家!实现UserDao接口l实现UserDao接口l修改daoconfig.properties文件,切换UserDao的实现。l测试UserDao的新的实现类。北京传智播客教育