JDBC的个人整理—编写步骤的原理和规范

由于在项目中使用Hibernate居多,从而JDBC直接使用慢慢减少,突然看了下视频整理对之前知识的查漏补缺。

连接数据的步骤

 

1.注册驱动(只做一次)
2.建立连接(Connection)
3.创建执行SQL的语句(Statement)
4.执行语句
5.处理执行结果(ResultSet)
6.释放资源

注册驱动

 

  • Class.forName(“com.mysql.jdbc.Driver”);

 

            推荐这种方式,不会对具体的驱动类产生依赖。

  • DriverManager.registerDriver(com.mysql.jdbc.Driver);

             会造成DriverManager中产生两个一样的驱动,并会对具体的驱动类产生依赖。

  • System.setProperty(“jdbc.drivers”, “driver1:driver2”);

            虽然不会对具体的驱动类产生依赖;但注册不太方便,所以很少使用。

建立连接

 

  • Connectionconn = DriverManager.getConnection ( url , user, password);
  • url 格式: JDBC: 子协议 : 子名称 // 主机名 : 端口 / 数据库名?属性名 = 属性值 &…
  • User,password 可以用“属性名 = 属性值”方式告诉数据库;
    其他参数如:useUnicode=true&characterEncoding=GBK

创建执行SQL的语句(Statement)

 

  • Statement

 

            Statement st = conn.createStatement();

           st.executeQuery(sql);

  • PreparedStatement

            Stringsql= “select * from table_name where col_name=?”;

            PreparedStatementps = conn.preparedStatement(sql);

            ps.setString(1, “col_value”);

            ps.executeQuery();

处理执行结果(ResultSet)

 

ResultSetrs= statement.executeQuery(sql);

While(rs.next()){

  rs.getString(“col_name”);

  rs.getInt(“col_name”);

  //…

}

释放资源

 

  • 释放ResultSet,Statement,Connection.
  • 数据库连接(Connection)是非常稀有的资源,用完后必须马上释放,如果Connection不能及时正确的关闭将导致系统宕机。Connection的使用原则是尽量晚创建,尽量早的释放

 

整合起来的可参考规范(使用单例模式)

将注册、建立连接和释放资源整合到一个JdbcUtils类中

 

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;


public final class JdbcUtilsSing {
	private String url = "jdbc:mysql://localhost:3306/jdbc";
	private String user = "root";
	private String password = "";

	// private static JdbcUtilsSing instance = new JdbcUtilsSing();
	private static JdbcUtilsSing instance = null;

	private JdbcUtilsSing() {
	}

	/**利用延迟加载并且加锁解决并发问题:使用的时候才new实例 
	 * @return
	 */
	public static JdbcUtilsSing getInstance() {
		//双重检查来避免instance为null的问题
		if (instance == null) {
			synchronized (JdbcUtilsSing.class) {
				if (instance == null) {
					instance = new JdbcUtilsSing();
				}
			}
		}
		return instance;
	}

	static {
		try {
			Class.forName("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e) {
			throw new ExceptionInInitializerError(e);
		}
	}

	public Connection getConnection() throws SQLException {
		return DriverManager.getConnection(url, user, password);
	}

	public void free(ResultSet rs, Statement st, Connection conn) {
		try {
			if (rs != null)
				rs.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (st != null)
					st.close();
			} catch (SQLException e) {
				e.printStackTrace();
			} finally {
				if (conn != null)
					try {
						conn.close();
					} catch (SQLException e) {
						e.printStackTrace();
					}
			}
		}
	}
}

 


模板使用的例子:

 

 

 

static void template() throws Exception {
		Connection conn = null;
		Statement st = null;
		ResultSet rs = null;
		try {
			// 2.建立连接
			conn = JdbcUtils.getConnection();
			// conn = JdbcUtilsSing.getInstance().getConnection();
			// 3.创建语句
			st = conn.createStatement();

			// 4.执行语句
			rs = st.executeQuery("select * from user");

			// 5.处理结果
			while (rs.next()) {
				// 参数中的1,2,3,4是指sql中的列索引
				System.out.println(rs.getObject(1) + "\t" + rs.getObject(2)
						+ "\t" + rs.getObject(3) + "\t" + rs.getObject(4));
			}
		} finally {
			JdbcUtils.free(rs, st, conn);
		}

	}

 

 

 

CRUD的操作

连接数据库的步骤跟以上是一样的

 

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;


public class CRUD {

	/**
	 * @param args
	 * @throws SQLException
	 */
	public static void main(String[] args) throws SQLException {
		 create();
		read();
		 update();
		 delete();
	}

	/**
	 * 删除
	 * @throws SQLException
	 */
	static void delete() throws SQLException {
		Connection conn = null;
		Statement st = null;
		ResultSet rs = null;
		try {
			// 2.建立连接
			conn = JdbcUtils.getConnection();
			// conn = JdbcUtilsSing.getInstance().getConnection();
			// 3.创建语句
			st = conn.createStatement();

			String sql = "delete from user where id>4";

			// 4.执行语句
			int i = st.executeUpdate(sql);

			System.out.println("i=" + i);
		} finally {
			JdbcUtils.free(rs, st, conn);
		}
	}

	/**
	 * 更新
	 * @throws SQLException
	 */
	static void update() throws SQLException {
		Connection conn = null;
		Statement st = null;
		ResultSet rs = null;
		try {
			// 2.建立连接
			conn = JdbcUtils.getConnection();
			// conn = JdbcUtilsSing.getInstance().getConnection();
			// 3.创建语句
			st = conn.createStatement();

			String sql = "update user set money=money+10 ";

			// 4.执行语句
			int i = st.executeUpdate(sql);

			System.out.println("i=" + i);
		} finally {
			JdbcUtils.free(rs, st, conn);
		}
	}

	/**
	 * 创建
	 * @throws SQLException
	 */
	static void create() throws SQLException {
		Connection conn = null;
		Statement st = null;
		ResultSet rs = null;
		try {
			// 2.建立连接
			conn = JdbcUtils.getConnection();
			// conn = JdbcUtilsSing.getInstance().getConnection();
			// 3.创建语句
			st = conn.createStatement();

			String sql = "insert into user(name,birthday, money) values ('name1', '1987-01-01', 400) ";

			// 4.执行语句
			int i = st.executeUpdate(sql);

			System.out.println("i=" + i);
		} finally {
			JdbcUtils.free(rs, st, conn);
		}
	}

	/**
	 * 查询
	 * @throws SQLException
	 */
	static void read() throws SQLException {
		Connection conn = null;
		Statement st = null;
		ResultSet rs = null;
		try {
			// 2.建立连接
			conn = JdbcUtils.getConnection();
			// conn = JdbcUtilsSing.getInstance().getConnection();
			// 3.创建语句
			st = conn.createStatement();

			// 4.执行语句
			rs = st.executeQuery("select id, name, money, birthday  from user");

			// 5.处理结果
			while (rs.next()) {
				System.out.println(rs.getObject("id") + "\t"
						+ rs.getObject("name") + "\t"
						+ rs.getObject("birthday") + "\t"
						+ rs.getObject("money"));
			}
		} finally {
			JdbcUtils.free(rs, st, conn);
		}
	}

}

 

CRUD的小结:

 

  • 增、删、改用Statement.executeUpdate来完成,返回整数(匹配的记录数),这类操作相对简单。
  • 查询用Statement.executeQuery来完成,返回的是ResultSet对象,ResultSet中包含了查询的结果;查询相对与增、删、改要复杂一些,因为有查询结果要处理

 

处于SQL注入问题的改善:PreparedStatement

 

  • SQL中包含特殊字符或SQL的关键字(如:' or 1 or ')Statement将出现不可预料的结果(出现异常或查询的结果不正确),可用PreparedStatement来解决。
  • PreperedStatement(从Statement扩展而来)相对Statement的优点:

 

              1.没有SQL注入的问题。

              2.Statement会使数据库频繁编译SQL,可能造成数据库缓冲区溢出。

              3.数据库和驱动可以对PreperedStatement进行优化(只有在相关联的数据库连接没有关闭的情况下有效)。

PreparedStatement使用的例子

 

static void read(String name) throws SQLException {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			// 2.建立连接
			conn = JdbcUtils.getConnection();

			// conn = JdbcUtilsSing.getInstance().getConnection();
			// 3.创建语句
			String sql = "select id, name, money, birthday  from user where name=?";
			ps = conn.prepareStatement(sql);
			ps.setString(1, name);
			// 4.执行语句
			rs = ps.executeQuery();

			// 5.处理结果
			while (rs.next()) {
				System.out.println(rs.getInt("id") + "\t"
						+ rs.getString("name") + "\t" + rs.getDate("birthday")
						+ "\t" + rs.getFloat("money"));
			}

		} finally {
			JdbcUtils.free(rs, ps, conn);
		}
	}


代码“rs = ps.executeQuery();”  executeQuery()方法同样可以添加参数不会编译异常,由于PreparedStatement是继承Statement,从而添加参数只是调用Statement的executeQuery(sql)方法。因为Statement是通过拼字符串形式交给数据库执行SQL语句,从而无法识别“?”就会报异常

 

 

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值