JDBC学习之一

一、步骤

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

二、详细

注册驱动

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

建立连接:

    Connection conn = DriverManager.getConnection(url, user, password);

执行SQL语句:

Statement

    Statement st = conn.createStatement();

    st.executeQuery(sql);

PreparedStatement

    String sql = “select * from table_name where col_name=?”;

    PreparedStatement ps = conn.preparedStatement(sql);

    ps.setString(1, “col_value”);

    ps.executeQuery();

处理执行结果:

ResultSet rs = statement.executeQuery(sql);

//ResultSet rs = ps.executeQuery();

While(rs.next()){

  rs.getString(“col_name”);

  rs.getInt(“col_name”);

  //…

}

释放资源:

释放ResultSet, Statement,Connection.

数据库连接(Connection)是非常稀有的资源,用完后必须马上释放,如Connection不能

及时正确的关闭将导致系统宕机。Connection的使用原则是尽量晚创建,尽量早的释放。

三、CRUD的实现

POJO/Domain

public class User {
	private int id;
	private String name;
	private Date birthday;
	private float money;
	
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	public float getMoney() {
		return money;
	}

	public void setMoney(float money) {
		this.money = money;
	}
}

JdbcUtils:提取出数据库操作的共同的部分

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

	private JdbcUtils() {
	}

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

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

	public static 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();
					}
			}
		}
	}
}
改进:考虑到可能同时有很多人需要使用此类,因此可将之改进为单例实现。

JdbcUtilsSing.java

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() {
	}

	public static JdbcUtilsSing getInstance() {
		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();
					}
			}
		}
	}
}

DAO(Interface)

public interface UserDao {
	public void addUser(User user);

	public User getUser(int userId);

	public User findUser(String loginName, String password);

	public void update(User user);

	public void delete(User user);

}
DAOImpl
public class UserDaoJdbcImpl implements UserDao {

	public void addUser(User user) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			conn = JdbcUtils.getConnection();
			String sql = "insert into user(name,birthday, money) values (?,?,?) ";
			ps = conn.prepareStatement(sql);
			ps.setString(1, user.getName());
			ps.setDate(2, new java.sql.Date(user.getBirthday().getTime()));
			ps.setFloat(3, user.getMoney());
			ps.executeUpdate();
		} catch (SQLException e) {
			throw new DaoException(e.getMessage(), e);
		} finally {
			JdbcUtils.free(rs, ps, conn);
		}
	}

	public void delete(User user) {
		Connection conn = null;
		Statement st = null;
		ResultSet rs = null;
		try {
			conn = JdbcUtils.getConnection();
			st = conn.createStatement();
			String sql = "delete from user where id=" + user.getId();
			st.executeUpdate(sql);
		} catch (SQLException e) {
			throw new DaoException(e.getMessage(), e);
		} finally {
			JdbcUtils.free(rs, st, conn);
		}

	}

	public User findUser(String loginName, String password) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		User user = null;
		try {
			conn = JdbcUtils.getConnection();
			String sql = "select id, name, money, birthday  from user where name=?";
			ps = conn.prepareStatement(sql);
			ps.setString(1, loginName);
			rs = ps.executeQuery();
			while (rs.next()) {
				user = mappingUser(rs);
			}
		} catch (SQLException e) {
			throw new DaoException(e.getMessage(), e);
		} finally {
			JdbcUtils.free(rs, ps, conn);
		}
		return user;
	}

	public User getUser(int userId) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		User user = null;
		try {
			conn = JdbcUtils.getConnection();
			String sql = "select id, name, money, birthday  from user where id=?";
			ps = conn.prepareStatement(sql);
			ps.setInt(1, userId);
			rs = ps.executeQuery();
			while (rs.next()) {
				user = mappingUser(rs);
			}
		} catch (SQLException e) {
			throw new DaoException(e.getMessage(), e);
		} finally {
			JdbcUtils.free(rs, ps, conn);
		}
		return user;
	}

	private User mappingUser(ResultSet rs) throws SQLException {
		User user = new User();
		user.setId(rs.getInt("id"));
		user.setName(rs.getString("name"));
		user.setMoney(rs.getFloat("money"));
		user.setBirthday(rs.getDate("birthday"));
		return user;
	}

	public void update(User user) {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			conn = JdbcUtils.getConnection();
			String sql = "update user set name=?, birthday=?, money=? where id=? ";
			ps = conn.prepareStatement(sql);
			ps.setString(1, user.getName());
			ps.setDate(2, new java.sql.Date(user.getBirthday().getTime()));
			ps.setFloat(3, user.getMoney());
			ps.setInt(4, user.getId());
			ps.executeUpdate();
		} catch (SQLException e) {
			throw new DaoException(e.getMessage(), e);
		} finally {
			JdbcUtils.free(rs, ps, conn);
		}
	}

}

改进:注意上述代码中异常的处理方式,不是随意的调用printStacktrace(),因为SQL异常是一种编译时异常,如果我们不做处理的话,在业务逻辑层(Service)调用DAO层的代码的时候将会产生众多的try...catch代码块,这会让我们的代码看起来很杂乱。因此,此处我们将此异常转化为运行时异常,交给DaoException类处理。

DaoException

public class DaoException extends RuntimeException {

	private static final long serialVersionUID = 1L;

	public DaoException() {
		// TODO Auto-generated constructor stub
	}

	public DaoException(String message) {
		super(message);
		// TODO Auto-generated constructor stub
	}

	public DaoException(Throwable cause) {
		super(cause);
		// TODO Auto-generated constructor stub
	}

	public DaoException(String message, Throwable cause) {
		super(message, cause);
		// TODO Auto-generated constructor stub
	}

}

下面我们思考这样一个问题,我们的业务逻辑层需要调用DaoImpl,但是当我们使用其他的框架如hibernate的时候,如何实现无缝的切换,即不改变我们的业务逻辑层,而使程序正确运行,在不了解Spring框架的时候,我们可以按照下面的方法实现。

首先,使用一个properties文件定义我们的DaoImpl类:daoconfig.properties

userDaoClass=cn.jdbc.dao.impl.UserDaoJdbcImpl
然后用一个工厂类来生产DaoImpl对象:DaoFactory

public class DaoFactory {
	private static UserDao userDao = null;
	private static DaoFactory instance = new DaoFactory();

	private DaoFactory() {
		try {
			Properties prop = new Properties();
			InputStream inStream = DaoFactory.class.getClassLoader()
					.getResourceAsStream("daoconfig.properties");
			prop.load(inStream);
			String userDaoClass = prop.getProperty("userDaoClass");
			Class clazz = Class.forName(userDaoClass);
			userDao = (UserDao) clazz.newInstance();
		} catch (Throwable e) {
			throw new ExceptionInInitializerError(e);
		}
	}

	public static DaoFactory getInstance() {
		return instance;
	}

	public UserDao getUserDao() {
		return userDao;
	}
}

注意上述代码的部分代码须小心:

private static UserDao userDao = null;
private static DaoFactory instance = new DaoFactory();
这2行代码的顺序不可搞错,否则外部类获取的userDao对象将会是空,原因是类的初始化顺序。

在业务逻辑层这样调用即可:

UserDao userDao = DaoFactory.getInstance().getUserDao();






转载于:https://my.oschina.net/working/blog/137759

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值