`

Spring笔记6---JDBC的集成

阅读更多
一. 无论采用何种持久化技术,JDBC始终都是它们的支撑件,如果没有底层的JDBC,ORM是没有办法操控RDBMS的。

  Spring 对 JDBC的集成主要包含了:

  1.提供各种模板类,简化了对RDBMS的CRUD操作,这些模板包括                    

     JdbcTemplate,NamedParameterJdbcTemplate,SimpleJdbcTemplate等等。这些模板类都是线程安全的,即在多线程环境中能始终保持一致的行为,尤其是Web环境。

 

  2.提供了各种DaoSupport辅助类,进一步简化了模板类的使用。 比如

     JdbcDaoSupport,NamedParameterJdbcDaoSupport,SimpleJdbcDaoSupport。

 

  3.提供了SimpleJdbcInsert和SimpleJdbcCall辅助类。

 

  4.提供了各种数据源类,借助DI容器实现了DataSource的灵活配置。

 

  5.提供了更多高级辅助类,比如:

      将JDBC CRUD操作建模成JAVA对象、LOB处理、操控存储过程、大批量数据处理、获得和生成主键等。

 

二. JdbcTemplate是JDBC集成的核心类,简化了JDBC API的使用。

 

1. 不用重新写调用java.sql.Connection对象的语句。

 

 

Java代码 复制代码 收藏代码
  1. jdbcTemplate.execute(new ConnectionCallback(){   
  2.    public Object doInConnectin(Connection con) throws SQLException,DataAccessException{   
  3.       log.info(con.getMetaData().getDriverName);   
  4.       return null;   
  5.   }   
  6. });  
jdbcTemplate.execute(new ConnectionCallback(){
   public Object doInConnectin(Connection con) throws SQLException,DataAccessException{
      log.info(con.getMetaData().getDriverName);
      return null;
  }
});

    *Spring 自身会从数据源中获得一Connection对象,并传入到doInConnection回调方法中。

 

2. 有若干方法用于执行静态SQL语句,即使用java.sql.Statement API.

 

 

Java代码 复制代码 收藏代码
  1. ..... execute(....) throws ....   
  2. ..... query(.....) throws .....   
  3. ..... queryForObject (.....) throws .....   
  4. ..... queryForList (.....) throws .....   
  5. ..... queryForMap (.....) throws .....   
  6. ..... queryForRowSet (.....) throws .....   
  7. int  update (.....) throws .....   
  8. int[]  batchUpdate (.....) throws .....  
..... execute(....) throws ....
..... query(.....) throws .....
..... queryForObject (.....) throws .....
..... queryForList (.....) throws .....
..... queryForMap (.....) throws .....
..... queryForRowSet (.....) throws .....
int  update (.....) throws .....
int[]  batchUpdate (.....) throws .....

   *结果集处理接口:ResultSetExtractor,RowCallbackHandler,RowMapper(线程安全,用的最多,包含许多子集,例如ColumnMapRowMapper,BeanPropertyRowMapper).

 

3. 有若干方法用于执行动态sql语句,即使用java.sql.PrepareStatement API.

 

 

Java代码 复制代码 收藏代码
  1. ..... execute(....) throws ....   
  2. ..... query(.....) throws .....   
  3. ..... queryForObject (.....) throws .....   
  4. ..... queryForList (.....) throws .....   
  5. ..... queryForMap (.....) throws .....   
  6. ..... queryForRowSet (.....) throws .....   
  7. int  update (.....) throws .....   
  8. int[]  batchUpdate (.....) throws .....  
..... execute(....) throws ....
..... query(.....) throws .....
..... queryForObject (.....) throws .....
..... queryForList (.....) throws .....
..... queryForMap (.....) throws .....
..... queryForRowSet (.....) throws .....
int  update (.....) throws .....
int[]  batchUpdate (.....) throws .....
 

 *大多方法都含有Object[] args参数,即这些方法都会采用预编译语句,执行效率更高。Hibernate就大量采用了预编译语句。

 

4. 有若干方法用于执行RDBMS的存储操作,即使用java.sql.CallableStatement API.

 

 

Java代码 复制代码 收藏代码
  1. ..... execute(....) throws ....   
  2. Map call(CallablestatementCreator csc,List declaredParameters) throws DataAccessException;  
..... execute(....) throws ....
Map call(CallablestatementCreator csc,List declaredParameters) throws DataAccessException;
 

三. JdbcDaoSupport是建立在JdbcTemplate基础上的支持类,其辅助类会自动创建相应模板类。

 

    在使用JdbcDaoSupportImpl实现类之前,需要配置示例如下:

 

 

Xml代码 复制代码 收藏代码
  1. <bean id="jdbcDaoSupport" class="org.springframework.samples.JdbcDaoSupportImpl">  
  2. <property name="dataSource" ref="dataSource"/>  
  3. <bean>  
<bean id="jdbcDaoSupport" class="org.springframework.samples.JdbcDaoSupportImpl">
<property name="dataSource" ref="dataSource"/>
<bean>

 

    或者直接提供一个JdbcTemplate给JdbcDaoSupportImpl,如下配置:

 

 

Java代码 复制代码 收藏代码
  1. <bean id="jdbcDaoSupport" class="org.springframework.samples.JdbcDaoSupportImpl">   
  2. <property name="jdbcTemplate" ref="jdbcTemplate"/>   
  3. <bean>  
<bean id="jdbcDaoSupport" class="org.springframework.samples.JdbcDaoSupportImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
<bean>
 

四. SimpleJdbcDaoSupport及NamedParameterJdbcDaoSupport;NamedParameterJdbcTemplate及     SimpleJdbcTemplate的相应支持类。

 

 例如:SimpleJdbcInsert和SimpleJdbcCall支持辅助类,前者用于操作表,后者用于操作存储过程或函数,它们的某些功能比SimpleJdbcTemplate更为强大,而且都是线程安全的。

 

*.SimpleJdbcInsert的usingGeneratedKeyColumns()能自动生成主键id,例子如下:

 

 

Java代码 复制代码 收藏代码
  1. ownerInsert = new SimpleJdbcInsert(dataSource).withTableName("owner").usingGeneratedKeyColumns("id");   
  2.   
  3. param = new HashMap<String,Object>();   
  4. param.put("fistname","Nedd");   
  5. param.put("lastname","Want");   
  6.   
  7. log.info(ownerInsert.executeAndReturnKey(param));  
ownerInsert = new SimpleJdbcInsert(dataSource).withTableName("owner").usingGeneratedKeyColumns("id");

param = new HashMap<String,Object>();
param.put("fistname","Nedd");
param.put("lastname","Want");

log.info(ownerInsert.executeAndReturnKey(param));

 

五.内置的DataSource继承。

 

1.基于测试目的DriverManagerDataSource,SimpleDriverDataSource和SingleConnectionDataSource.

 

2.Apache DBCP数据源。(实现了连接池)

 

 

Java代码 复制代码 收藏代码
  1. <bean id = "dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}" p:username="${jdbc.username}" p:password="${jdbc.password}" />  
<bean id = "dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}" p:username="${jdbc.username}" p:password="${jdbc.password}" />
 

  上面的bean中配置了destroy-method属性,当销毁Spring DI容器时,BasicDataSource对象的close()方法便会被触发,从而优雅地关闭掉底层连接池持有的数据库连接。

 

3. 其他数据源。

 

   *Java EE容器内置的数据源:能从JNDI树上查找到已经注册的DataSource实现。示例如下:

 

 

Xml代码 复制代码 收藏代码
  1. <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/petclinic">  
 <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/petclinic">
 

 

 

   *LazyConnectionDataSourceProxy:会代理其他数据源。

 

   *TransactionAwareDataSourceProxy:能使得当前的CRUD操作能够参与到Spring的受管事务中。如果当前不存在活动事务,则会使用默认行为,通常在开发中很少用到。

 

   *UserCredentialsDataSourceAdapter: 将连接数据库的用户凭证信息(用户名,密码)传入到getConnection(String username,String password)方法中。一旦配置好后,客户每次获得数据库连接,都会调用getConnection方法。

 

   *IsolationLevelDataSourceAdapter:启用isolationLevelName属性能指定隔离级别。继承于UserCredentialsDataSourceAdapter。

 

   *WebSphereDataSourceAdapter:继承于IsolationLevelDataSourceAdapter,会从WebSphere容器获得数据源。并借助WebSphere专有的api达到启用自定义隔离级别的目的。

 

   *IsolationLevelDataSourceRouter: 会根据当前Spring受管事务启用的隔离级别来选定合适的DataSource数据源。

 

六. 将JDBC操作建模成Java对象。

 

   1. SqlUpdate辅助类

   2. UpdatableSqlQuery辅助类

   3. MappingSqlQuery辅助类 :能将SQL select查询结果集自动转换成领域对象集合,返回给调用者。其子类必须实现mapRow()方法,它内置大量的execute()和findObject()方法。

   4. SqlFunction辅助类。

 

七. 与存储过程交互。

 

   1. JdbcTemplate针对存储过程提供的支持。

 

 

Java代码 复制代码 收藏代码
  1. Object execute(CallableStatementCreator csc, CallableStatmentCallback action) throws DataAccessException;   
  2.   
  3.   
  4. Object execute(String callString, CallableStatmentCallback action) throws DataAccessException;   
  5.   
  6.   
  7. Object execute(CallableStatementCreator csc, List declaredParameters) throws DataAccessException;  
Object execute(CallableStatementCreator csc, CallableStatmentCallback action) throws DataAccessException;


Object execute(String callString, CallableStatmentCallback action) throws DataAccessException;


Object execute(CallableStatementCreator csc, List declaredParameters) throws DataAccessException;
 

 如果使用了CallableStatmentCallback回调接口,则要实现doInCallableStatement()方法。

 

   2. StoredProcedure辅助类。

 

   3. SimpleJdbcCall 辅助类。重要辅助类。

 

 

Java代码 复制代码 收藏代码
  1. SimpleJdbcCall sjc = new SimpleJdbcCall(ds);   
  2. sjc.withProcedureName("show_sal");   
  3.   
  4. sqlParameterSource sps = new MapSqlParameterSource().addValue("enames","SMITH").addValue("empnos",7369);   
  5.   
  6. log.info(sjc.execute(sps));  
SimpleJdbcCall sjc = new SimpleJdbcCall(ds);
sjc.withProcedureName("show_sal");

sqlParameterSource sps = new MapSqlParameterSource().addValue("enames","SMITH").addValue("empnos",7369);

log.info(sjc.execute(sps));
 

以上开发者直接将存储过程名告知withProcedureName()方法,并将参数提供给了execute方法。

 

如果需要制定传入传出参数,可借助SimpleJdbcCall内置的 declareParameters()方法,示例如下,SqlParameters用于指定传入参数,而SqlOutParameters用于指定传出参数:

 

 

Java代码 复制代码 收藏代码
  1. SimpleJdbcCall sjc = new SimpleJdbcCall(ds).withProcedureName("show_sal");   
  2.   
  3. sjc.declareParameters(new SqlParameter("enames",Types.VARCHAR)).   
  4. declareParameters(new SqlParameter("empnos",Types.VARCHAR)).declareParameters(new SqlParameter("sals",Types.FLOAT)).withoutProcedureColumnMetaDataAccess();   
  5.   
  6. sqlParameterSource sps = new MapSqlParameterSource().addValue("enames","SMITH").addValue("empnos",7369);   
  7.   
  8. log.info(sjc.execute(sps));  
SimpleJdbcCall sjc = new SimpleJdbcCall(ds).withProcedureName("show_sal");

sjc.declareParameters(new SqlParameter("enames",Types.VARCHAR)).
declareParameters(new SqlParameter("empnos",Types.VARCHAR)).declareParameters(new SqlParameter("sals",Types.FLOAT)).withoutProcedureColumnMetaDataAccess();

sqlParameterSource sps = new MapSqlParameterSource().addValue("enames","SMITH").addValue("empnos",7369);

log.info(sjc.execute(sps));
 

一旦启用了declareParameters()方法,withoutProcedureColumnMetaDataAccess()方法也就该被调用,从而避免再去从底层jdcb驱动获得RDBMS相关元数据,比如存储过程的输入输出参数。

 

 

八. 处理大批量数据。

 

1. JdbcTemplate内置的batchUpdate()方法。

 

 

Java代码 复制代码 收藏代码
  1. int[] batchUpdate(String[] sql) throws DataAccessException;   
  2.   
  3. int[] batchUpdate(String[] sql,BatchPreparedStatementSetter pss) throws DataAccessException;  
int[] batchUpdate(String[] sql) throws DataAccessException;

int[] batchUpdate(String[] sql,BatchPreparedStatementSetter pss) throws DataAccessException;

 

 

例如:

 

 

Java代码 复制代码 收藏代码
  1. final int[] no= new int[]{324,543,1234,421,32142,3212};   
  2.   
  3. jdbcTemplate.batchUpdate("update emp set sal = ? where empno = ?",new BatchPreparedStatementSetter(){   
  4.   
  5.  public void setValues(PreparedStatement ps,int i) throws SQLException{   
  6.   ps.setInt(1,no[i]);   
  7.   ps.setFloat(2,no[i]);   
  8.   
  9. }   
  10.   
  11.   public int getBatchSize(){   
  12.     return no.length;   
  13. }   
  14.   
  15. }){   
  16.   
  17. }  
final int[] no= new int[]{324,543,1234,421,32142,3212};

jdbcTemplate.batchUpdate("update emp set sal = ? where empno = ?",new BatchPreparedStatementSetter(){

 public void setValues(PreparedStatement ps,int i) throws SQLException{
  ps.setInt(1,no[i]);
  ps.setFloat(2,no[i]);

}

  public int getBatchSize(){
    return no.length;
}

}){

}
 

 

2. SimpleJdbcTemplate内置的batchUpdate方法。

 

 

Java代码 复制代码 收藏代码
  1. int[] batchUpdate(String sql,Map[] batchValues) ;   
  2.   
  3. int[] batchUpdate(String sql,SqlParameterSource[] batchArgs) ;   
  4.   
  5. int[] batchUpdate(String sql,List<Object> batchArgs);   
  6.   
  7. int[] batchUpdate(String sql,List<Object> batchArgs,int[] argTypes);  
int[] batchUpdate(String sql,Map[] batchValues) ;

int[] batchUpdate(String sql,SqlParameterSource[] batchArgs) ;

int[] batchUpdate(String sql,List<Object> batchArgs);

int[] batchUpdate(String sql,List<Object> batchArgs,int[] argTypes);
 

List对象作为参数示例:

 

 

Java代码 复制代码 收藏代码
  1. SimpleJdbcTemplate sjt = xxx.getBean("simpleJdbcTemplate");   
  2.   
  3. List<Object[]> paramList = new ArrayList<Object[]>();   
  4. paramList.add(new Integer[]{2342,23423});   
  5. paramList.add(new Integer[]{2342,23423});   
  6. paramList.add(new Integer[]{2342,23423});   
  7. paramList.add(new Integer[]{2342,23423});   
  8. paramList.add(new Integer[]{2342,23423});   
  9.   
  10. sjt.batchUpdate("update emp set sal = ? where empno = ?",paramList);  
SimpleJdbcTemplate sjt = xxx.getBean("simpleJdbcTemplate");

List<Object[]> paramList = new ArrayList<Object[]>();
paramList.add(new Integer[]{2342,23423});
paramList.add(new Integer[]{2342,23423});
paramList.add(new Integer[]{2342,23423});
paramList.add(new Integer[]{2342,23423});
paramList.add(new Integer[]{2342,23423});

sjt.batchUpdate("update emp set sal = ? where empno = ?",paramList);

 最后一sql语句也可以将sql类型告知给batchUpdate(),如下:

 

 

Java代码 复制代码 收藏代码
  1. sjt.batchUpdate("update emp set sal = ? where empno = ?",paramList,new int[]{Types.INTEGER,Types.FLOAT});  
sjt.batchUpdate("update emp set sal = ? where empno = ?",paramList,new int[]{Types.INTEGER,Types.FLOAT});
 

 

九. 基于JDBC的LOB集成支持。

 

为操控LOB字段,Spring能应用需要启用LobHandler继承链。当前,Spring内置了DefaultLobHandler和OracleLobHandler实现类。通常除了Oracle数据库外,开发者可直接配置DefaultLobHandler实例即可。

如果用OracleLobHandler,还的为它配置NativeJdbcExtractor对象,以获得底层数据库的原生连接。

 

 

Xml代码 复制代码 收藏代码
  1. <bean id="imageDatabase" class="xxxxxxxxxxxxx" p:dataSource-ref="dataSource" p:lobHandler-ref="defaultLobHandler"/>  
  2.   
  3. <bean id="defaultLobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" p:dataSource-ref="dataSource" lazy-init="true"/>  
<bean id="imageDatabase" class="xxxxxxxxxxxxx" p:dataSource-ref="dataSource" p:lobHandler-ref="defaultLobHandler"/>

<bean id="defaultLobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" p:dataSource-ref="dataSource" lazy-init="true"/>
 

1. 读取

 

借用了AbstractLobStreamingResultSetExtractor回调类,这里调用了LobHandler的getBlobAsBinaryStream()方法,即将Blob转换成了二进制流。

 

 

Java代码 复制代码 收藏代码
  1. @Transactional(readOnly=true)   
  2. public void streamImage(final name,final OutputStream contentstream) throws DataAccessException{   
  3.    getJdbcTemplate().query{   
  4.         "select content from imagedb where image_name=?",new Object[]{name}, new AbstractLobStreamingResultSetExtractor(){   
  5.          protected void handleNoRowFound() throws LobRetrievalFailureException{   
  6.               throw new EmptyResultDataAccessException(   
  7.               "image with name '"+name+"' not found in database",1);   
  8.   
  9.            }   
  10.   
  11.     public void streamData(ResultSet rs) throws SQLException,IOException{   
  12.    InputStream is = lobHandler.getBlobAsBinaryStream(rs,1);   
  13.    if(is!=null){   
  14.       FileCopyUtils.copy(is.contentstream);   
  15.   
  16.   }   
  17.      
  18. }   
  19.      }   
  20.   }   
  21. }  
@Transactional(readOnly=true)
public void streamImage(final name,final OutputStream contentstream) throws DataAccessException{
   getJdbcTemplate().query{
        "select content from imagedb where image_name=?",new Object[]{name}, new AbstractLobStreamingResultSetExtractor(){
         protected void handleNoRowFound() throws LobRetrievalFailureException{
              throw new EmptyResultDataAccessException(
              "image with name '"+name+"' not found in database",1);

           }

    public void streamData(ResultSet rs) throws SQLException,IOException{
   InputStream is = lobHandler.getBlobAsBinaryStream(rs,1);
   if(is!=null){
      FileCopyUtils.copy(is.contentstream);

  }
  
}
     }
  }
}
 

2.存储

 

要使用LobHandler内置的LobCreator对象。需要启用AbstractLobCreatingPreparedStatementCallback回调类。借助LobCreator的setBlobAsBinaryStream()方法能将输入流存储到Blob字段中。setClobAsString()方法能将大文本块存储到Clob字段中。

 

 

Java代码 复制代码 收藏代码
  1. @Transactional  
  2. public void storeImage(   
  3.   final String name,    
  4.   final InputStream contentstream,   
  5.   final int contentLength,   
  6.   final String description   
  7. throws DataAccessException{   
  8.   
  9.   getJdbcTemplate().execute(   
  10.   
  11. "insert into imagedb(image_name,content,description) values (?,?,?)",new AbstractLobCreatingPreparedStatementCallback(this.lobHandler)){   
  12.  protected void setValues(    
  13.                PreparedStatement ps, LobCreator lobCreator   
  14.        ) throws SQLException{   
  15.          ps.setString(1,name);   
  16.          lobCreator.setBlobAsBinaryStream(   
  17.              ps,2,contentstream,contentlength);   
  18.          lobCreator.setClobAsString(ps,3,description);   
  19.         }   
  20.         }   
  21.   
  22.      );   
  23.   
  24. }  
@Transactional
public void storeImage(
  final String name, 
  final InputStream contentstream,
  final int contentLength,
  final String description
) throws DataAccessException{

  getJdbcTemplate().execute(

"insert into imagedb(image_name,content,description) values (?,?,?)",new AbstractLobCreatingPreparedStatementCallback(this.lobHandler)){
 protected void setValues( 
               PreparedStatement ps, LobCreator lobCreator
       ) throws SQLException{
         ps.setString(1,name);
         lobCreator.setBlobAsBinaryStream(
             ps,2,contentstream,contentlength);
         lobCreator.setClobAsString(ps,3,description);
        }
        }

     );

}
 

十. 获得和生成主键。

 

 

Java代码 复制代码 收藏代码
  1. KeyHolder kh = new GeneratedKeyHolder();   
  2.   
  3. int update(PreparedStatementCreator psc,KeyHolder generatedKeyHolder) throws DataAccessException;  
KeyHolder kh = new GeneratedKeyHolder();

int update(PreparedStatementCreator psc,KeyHolder generatedKeyHolder) throws DataAccessException;
 

 

十一. 还需要注意的。

 

1. 要合理设置Statement的fetchSize大小,即JdbcTemplate的fetchSize变量取值。(查询时,权衡时间和空间的优化)。

 

2. 大批量存储时,开发者要控制每批数据的数据量。设置batchSize的大小。

 

3. 尽量采用PreparedStatement操控数据库,而不是Statement。

 

4. 充分挖掘JdbcTemplate,NamedParameterJdbcTemplate,SimpleJdbcTemplate,SimpleJdbcInsert,SimpleJdbcCall等辅助类的功能。不要直接使用Connection对象操控。

 

分享到:
评论

相关推荐

    springboot学习思维笔记.xmind

    springboot学习笔记 spring基础 Spring概述 Spring的简史 xml配置 注解配置 java配置 Spring概述 Spring的模块 核心容器CoreContainer Spring-Core Spring-Beans ...

    spring-note spring 读书笔记

    详细介绍了Spring 与 IOC,Aop,还有Spring与JDBC,HIBERNATE,STRUTS,Transaction 进行集成,配置文件的编写

    Spring学习笔记

    Spring学习笔记Spring spring的配置 IOC 依赖注入 基于Xml的注入 基于注释的注入 Spring的自动注入和属性自动注入 AOP 静态代理 动态代理 使用spring实现AOP 基于Annotation实现AOP ... spring集成jdbc

    Spring+JDBC集成学习笔记(可参考ppt附件38-46页)

    NULL 博文链接:https://whp0731.iteye.com/blog/450115

    leetcode下载-SSM-Examples:SSM-示例

    leetcode下载 Java 常用技术,涉及SSM,一些小的工具 config-helper,配置文件读取工具类,使用注解的方式,类型安全 hibernate—examples,从原生jdbc到hibernate集成 ...Spring-webservice,集成Spring的webse

    Java学习笔记-个人整理的

    {12.13.6}drop}{177}{subsection.12.13.6} {12.13.7}rename}{177}{subsection.12.13.7} {12.14}SQL脚本}{177}{section.12.14} {12.15}Transaction}{177}{section.12.15} {12.16}char与varchar2}{178}{section....

    spring-boot

    SpringBoot学习笔记所有源码集,包括 集成了freemarker、Servlet、拦截器、拦截器、Filter、静态资源处理、启动加载数据、Springboot 日志、JDBC使用、Springboot JPA、Mybatis、动态数据源、集成swagger、集成Redis...

    Greatly_repository:Spring Boot 学习笔记

    Spring Boot 学习笔记 基础篇 #提升篇 15.SpringBoot之集成Shiro 16.SpringBoot之使用mybatis-generator自动生成代码 17.SpringBoot之使用lombok编码 18.SpringBoot之初始化数据 19.SpringBoot之使用POI开发Excel...

    springmybatis

    mybatis实战教程mybatis in action之五与spring3集成附源码 mybatis实战教程mybatis in action之六与Spring MVC 的集成 mybatis实战教程mybatis in action之七实现mybatis分页源码下载 mybatis实战教程mybatis in ...

    互联网创意产品众筹平台

    问题一箩筐-jdbc.properties属性文件设置错误,无法连接数据库, Q) {; h4 t( ?: r& ^ │ 5.问题一箩筐-关于url扩展名称问题 │ 6.问题一箩筐-关于打印日志log4j问题5 y: }- e: Z$ p6 X9 d0 A9 @ │ 7.问题一箩筐-生产...

    JSP网络编程学习笔记源代码 part2

    第四篇为“数据库访问技术”,主要讲述JDBC技术及JSP和Servlet如何通过JDBC访问数据库,以及如何改进数据库的访问和目前流行的Hibernate、iBATIS及Spring集成访问的支持;第五篇为“标签语言和表达式语言”,主要...

    java文集

    Java 6 RowSet 使用完全剖析 结合Spring2.0和ActiveMQ进行异步消息调用 struts+hibernate增删改查(一) AXIS 布署问题 struts+hibernate增删改查(二) MySQL中如何实现Top N及M至N段的记录查询?...

Global site tag (gtag.js) - Google Analytics