JAVA 开发平台的技术和框架(四)一、JDBC Spring JDBC

JDBC

以下内容摘自百度百科:

JDBC(Java Data Base Connectivity,java 数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。

有了JDBC,向各种关系数据发送SQL语句就是一件很容易的事。换言之,有了JDBC API,就不必为访问Sybase数据库专门写一个程序,为访问Oracle数据库又专门写一个程序,或为访问Informix数据库又编写另一个程序等等,程序员只需用JDBC API写一个程序就够了,它可向相应数据库发送SQL调用。同时,将Java语言和JDBC结合起来使程序员不必为不同的平台编写不同的应用程序,只须写一遍程序就可以让它在任何平台上运行,这也是Java语言“编写一次,处处运行”的优势。
 
Java数据库连接体系结构是用于Java应用程序连接数据库的标准方法。JDBC对Java程序员而言是API,对实现与数据库连接的服务提供商而言是接口模型。作为API,JDBC为程序开发提供标准的接口,并为数据库厂商及第三方中间件厂商实现与数据库的连接提供了标准方法。JDBC使用已有的SQL标准并支持与其它数据库连接标准,如ODBC之间的桥接。JDBC实现了所有这些面向标准的目标并且具有简单、严格类型定义且高性能实现的接口。
 
Java 具有坚固、安全、易于使用、易于理解和可从网络上自动下载等特性,是编写数据库应用程序的杰出语言。所需要的只是 Java应用程序与各种不同数据库之间进行对话的方法。而 JDBC 正是作为此种用途的机制。

JDBC 可做三件事:与数据库建立连接、发送 操作数据库的语句并处理结果。下列代码段给出了以上三步的基本示例:
 

Connection con = DriverManager.getConnection("jdbc:odbc:wombat","login","password");
 
Statement stmt = con.createStatement();
 
ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table1");
 
while (rs.next()) {
 
int x = rs.getInt("a");
 
String s = rs.getString("b");
 
float f = rs.getFloat("c");
 
}

Spring JDBC

以下内容摘自:http://blog.163.com/tianshenglongchang@126/blog/static/164628503201122953223522/ spring jdbc

1、Spring的JDBC框架

能够承担资源管理和异常处理的工作。对于JDBC来说,Spring提供了3个模板类

  • JdbcTemplate:Spring里最基本的JDBC模板,利用JDBC和简单的索引参数查询提供对数据库的简单访问。
  • NamedParameterJdbcTemplate:能够在执行查询时把值绑定到SQL里的命名参数,而不是使用索引参数。
  • SimpleJdbcTemplate:利用Java 5 的特性,比如自动装箱、通用(generic)和可变参数类表来简化JDBC模板的使用。

2、JdbcDaoSupport,&& 让Spring JDBC更“Spring”

Spring提供了JdbcDaoSupport,所有DAO继承这个类,就会自动获得JdbcTemplate(前提是注入DataSource)。

另外:Spring的xml配置可以很好的用在这里,在xml中配置,基本流程如下:

(1)生命DataSrouce的Bean,这里用BasicDataSource,就是DBCP数据源(Tomcat用的那个)

(2)声明模板JdbcTemplate的Bean,并把DataSource注入之

(3)声明Dao,class为集成自JdbcDaoSupport的东西,并注入JdbcTemplate。

上述Bean生成过程可以用Spring IDE相当的方便。

applicationContext.xml


   
    com.mysql.jdbc.Driver
   
   
    jdbc:mysql://localhost:3306/sampledb
   
   
    root
   
   
    
   


   
    
   


   
    
   



ForumDao

package dao.jdbc;

import org.springframework.jdbc.core.support.JdbcDaoSupport;

public class ForumDAO extends JdbcDaoSupport 
{
public void initDb()
{
   String sql = "create table t_user1(user_id int primary key,user_name varchar(60))";
   getJdbcTemplate().execute(sql);
}
}

Main

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;


public class Main 
{
public static void main(String args[])
{
   DriverManagerDataSource ds = new DriverManagerDataSource();
   ds.setDriverClassName("com.mysql.jdbc.Driver");
   ds.setUrl("jdbc:mysql://localhost:3306/sampledb");
   ds.setUsername("root");
   ds.setPassword("");
  
   JdbcTemplate jdbc = new JdbcTemplate();
   jdbc.setDataSource(ds);
   String sql = "create table t_user1(user_id int primary key,user_name varchar(60))";
   jdbc.execute(sql);
}

}

3、JDBCTemplate模板的update

update一般用于insert等有参数同时传入的且无需返回结果的SQL语句。

三个方法:

public int update(String sql,Object[] args)

public int update(String sql,Object[] args,int[] argTypes)

public int update(String sql,PreparedStatementSetter pss)

还有一个方法不过太诡异了,不用之……这里比较搞笑的是第1和第2个,第一个方法中:这里Object []args,居然是由Spring猜测各个类型(反射),而不是顺序按照参数填入

第三个需要匿名类,写一下:

String sql = "insert into t_forum(forum_name,forum_desc) values(?,?)";
   getJdbcTemplate().update(sql, new PreparedStatementSetter(){
    public void setValues(PreparedStatement ps) throws SQLException 
    {
     // TODO Auto-generated method stub
     ps.setString(1, forum.getForumName());
     ps.setString(2, forum.getForumDesc());
    }
   });

4、更新并获得“新的主键ID”

前提:如果主键ID是整数的。

public void addFourm(final Forum forum)
{
   final String sql = "insert into t_forum(forum_name,forum_desc) values(?,?)";
   KeyHolder holder = new GeneratedKeyHolder();
   getJdbcTemplate().update(new PreparedStatementCreator(){

    @Override
    public PreparedStatement createPreparedStatement(Connection conn)
      throws SQLException {
     PreparedStatement ps = conn.prepareStatement(sql);
     ps.setString(1, forum.getForumName());
     ps.setString(2, forum.getForumDesc());
     return ps;
    }

   },holder);
   forum.setForumId(holder.getKey().intValue());
}


5、JdbcTemplate批量执行SQL语句

有的时候要一次执行多条SQL语句(插入或者删除),一次一次的调用肯定不好。

两种方法:

public int[] batchUpdate(String[] sql)

public int[] batchUpdate(String sql,BatchPreparedStatementSetter pss)

很显然了,第一个是给一个多个SQL语句的数组,第二个则是根据基础的SQL语句,辅助以BathPreparedStatement,这样在每个pss中,只需要构造逐次的一条SQL语句即可(批量生成SQL语句)。

主要写下面方法的实现:

public void addForums(final LinkedList forums)
{
   String sql = "insert into t_forum(forum_name,forum_desc) values(?,?)";
   this.getJdbcTemplate().batchUpdate(sql, new BatchPreparedStatementSetter()
   {

    @Override
    public int getBatchSize() {
     return forums.size();
    }

    @Override
    public void setValues(PreparedStatement ps, int i)
      throws SQLException {
     // TODO Auto-generated method stub
     Forum f = forums.get(i);
     ps.setString(1,f.getForumName());
     ps.setString(2, f.getForumDesc());
    }
   });
}

 

6、查询数据:RowCallbackHandler

当需要查询数据的时候,可以使用众多回调器,RowCallbackHandler。

public void query(String sql,RowCallbackHandler rch)

public void query(String sql,Object[] args,RowCallbackHandler rch)

类似的API不再列出。

public Forum getForum(final int forumID)
{
   String sql = "select * from t_forum where forum_id=?";
   final Forum f = new Forum();
   this.getJdbcTemplate().query(sql,
     new PreparedStatementSetter()
   {

    @Override
    public void setValues(PreparedStatement ps) throws SQLException {
     // TODO Auto-generated method stub
     ps.setInt(1, forumID);
    }
   
   },
     new RowCallbackHandler()
   {

    @Override
    public void processRow(ResultSet rs) throws SQLException {
     // TODO Auto-generated method stub
     f.setForumId(rs.getInt("forum_id"));
     f.setForumName(rs.getString("forum_name"));
     f.setForumDesc(rs.getString("forum_desc"));    
    }
   
   });
  
   return f;
}

 

7、查询数据:使用RowMapper

RowMapper的好处是,自动封装了List,并自动返回,无需自己添加List和把元素添加到List中。

public List query(String sql,Object[] args,int[] argTypes,RowMapper rowMapper)

public List getForums(final int forumID)
{
   String sql = "select * from t_forum where forum_id>?";
   return (List)this.getJdbcTemplate().query(
     sql,
     new Object[]{forumID},
     new int[]{java.sql.Types.INTEGER},
     new RowMapper()
     {
      @Override
      public Object mapRow(ResultSet rs, int i)
        throws SQLException {
       Forum f = new Forum();
       f.setForumName(rs.getString("forum_name"));
       f.setForumId(rs.getInt("forum_id"));
       f.setForumDesc(rs.getString("forum_desc"));   
      
       return f;
      }
     }
     );
}

 

8、RowCallbackHandler的子类: RowCountCallbackHandler计算行数

public int getForumCounts()
{
   String sql = "select * from t_forum";
   RowCountCallbackHandler countCallback = new RowCountCallbackHandler(); // not reusable
   getJdbcTemplate().query(sql, countCallback);
   int rowCount = countCallback.getRowCount();
   return rowCount;
}

当然,可以覆盖本类的下述方法,来实现对每条结果的处理,继承自RowCallbackHandler

public final void processRow(ResultSet rs) throws SQLException

9、查询单值数据

可使用queryForXXX方法来查询肯定只返回一个数值的记录,XXX为返回的类型。

public int getForumCounts()
{
   String sql = "select count(*) from t_forum";
   return this.getJdbcTemplate().queryForInt(sql);
}

你可能感兴趣的:(java,JDBC,Spring,jdbc)