JDBC


##什么是JDBC? JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的java API。可以为多种关系数据库提供统一访问,它由一组用java语言编写的类和接口组成。

##JDBC原理 JDBC通过标准(一系列接口)定义了访问数据库的通用API,不同的数据库厂商根据各自数据库的特点提供的对JDBC的实现(实现类包)。 图示:
jdbc基本原理

##核心API

// 1.装载 OracleDriver 到内存里,
// 通过static块实现在DriverManager中的“自动注册”
Class.forName("oracle.jdbc.OracleDriver");

// 2.创建Connection的实现对象,
// 根据url连接参数找到与之匹配的Driver对象,调用其方法获取连接
String url = "jdbc:oracle:thin:@192.168.10.205:1521:tarena";
String username = "jsd1303";
String pwd = "jsd1303";
Connection conn = DriverManager.getConnection(url, username, pwd);

// 3.通过Statement对象,传送SQL语句
Statement stmt = conn.createStatement();

// 4.执行SQL并获得结果集
// 执行select语句
ResultSet rs = stmt
		.executeQuery("select id,real_name,create_date from nova_account");
// 执行update、insert、delete语句
// stmt.executeUpdate("");
// 遍历结果集
while (rs.next()) {
	int id = rs.getInt("id");
	String realName = rs.getString("real_name");
	Date createDate = rs.getDate("create_date");
	System.out.println("id: " + id + " real_name: " + realName
			+ " create_date: " + createDate);
}

// 5.关闭资源
rs.close();
stmt.close();
conn.close();

##DAO Data Access Object,数据访问对象,用于应用程序与数据源进行交互。

##Statement隐患

##PreparedStatement ###说明 预编译的Statement

###核心API

//pstmt对象将包含的SQL语句发送给DBMS,并为执行作好准备
PreparedStatement pstmt = con.prepareStatement("UPDATE tableName SET m = ? WHERE x = ?");
//给占位符进行赋值
pstmt.setLong(1,12345);
pstmt.setInt(2,100);
//执行SQL语句
pstmt.executeUpdate();
//pstmt.execute();
//pstmt.executeQuery();

##事务控制 ###事务特性ACID

###相关API

//关闭事务的自动提交
conn.setAutoCommit(false);
//提交事务
conn.commit();
//回滚事务
conn.rollback();

##JDBC批处理 ###优点

  1. 降低应用程序和数据库之间的网络调用
  2. 相比单条SQL,批处理是更高效
  3. 能有效降低对Oracle的负载

###API

###例子

Connection con = null;
PreparedStatement stmt = null;
try{
    con = getConnection();
    String sql = "insert into service(id,account_id) values(?,?)";
    con.setAutoCommit(false);
    stmt = con.prepareStatement(sql);
    int count = 0;
    int batchSize = 1000;
    for(Service : Services){
        stmt.setString(1,Service.id);
        stmt.setString(2,Service.accountId);
        stmt.addBatch();
        if(++count >= batchSize){
            stmt.executeBatch();
        }
    }
    stmt.executeBatch();
    stmt.close();
    con.commit();
}catch(SQLException e){
    e.printStackTrace();
    con.rollback();
}finally{
    if(con!=null){
        try{
            con.close();
        }catch(SQLException e){
            e.printStackTrace();
        }
    }
}

##getConnection优化 ###ThreadLocal原理 用于实现线程内的数据共享,即对于相同的程序代码,多个模块在同一个线程中运行时要共享一份数据,而在另外线程中运行时又共享另外一份数据。

###ThreadLocal核心API

private static ThreadLocal localCon 
    = new ThreadLocal();
protected static synchronized Connection
    getConnection() throws SQLException{
    Connection con = localCon.get();
    if(con == null){
        con = openConnection();
        localCon.set(con);
    }
    return con;
}
</pre>

##BaseDAO封装
public class BaseDAO {

	private ThreadLocal localConn;

	/**
	 * 获得连接
	 * 
	 * @return
	 * @throws SQLException
	 */
	protected synchronized Connection getConnection() throws SQLException {
		Connection conn = localConn.get();
		if (conn == null) {
			conn = DBUtils.getConnection();
			localConn.set(conn);
		}
		return conn;
	}

	/**
	 * 开始事务
	 */
	public void beginTx() {
		Connection conn;
		try {
			conn = getConnection();
			conn.setAutoCommit(false);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 提交事务
	 */
	public void commitTx() {
		Connection conn;
		try {
			conn = getConnection();
			conn.commit();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 回滚事务
	 */
	public void rollbackTx() {
		Connection conn;
		try {
			conn = getConnection();
			conn.rollback();
		} catch (SQLException e) {
			e.printStackTrace();
		}

	}

	/**
	 * 关闭连接
	 */
	public void closeConnection() {
		Connection conn = localConn.get();
		try {
			if (conn != null) {
				conn.close();
				localConn.set(null);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}
</pre>

##分页查询
###Oracle分页参数
//说明
//currentPage -- 当前页
//numPerPage -- 每页几条
//querySql -- 查询语句

//记录总数
int totalRows = 0;//TODO 查询得到符合条件的记录总数
//总页数
int totalPages = totalRows % numPerPage == 0 
                 ? totalRows / numPerPage 
                 : (totalRows / numPerPage + 1);
//开始记录的位置
int startIndex = (currentPage - 1) * numPerPage;
//最后一条记录的位置
int lastIndex = currentPage == totalPages
                ? totalRows
                : (startIndex+numPerPage);
//分页sql
StringBuffer pagingSql = new StringBuffer();
pagingSql.append("select * from ( select my_table.*,rownum as my_rownum from ( ");
pagingSql.append(querySql);
pagingSql.append(" ) my_table where rownum <= ").append(lastIndex);
pagingSql.append(") where my_rownum > ").append(startIndex);
###MySQL分页
select * from tablename limit start,pageSize;
标题:JDBC
作者: Nova Woo 2013-05-20 
出处: http://novawoo.github.io/jdbc
说明:转载、投稿、翻译类文章版权信息以正文标注为准
分类: Java & JDBC    标签:
 
 

无觅相关文章插件,快速提升流量
友荐云推荐