浅谈JDBC之DAO模式
概述
DAO,Data Access Object,即数据存取对象,它位于业务逻辑与持久化数据之间,主要功能是实现对持久化数据的访问。
DAO隔离了业务逻辑代码与数据访问代码,使我们能够很方便地实现不同数据库的持久化操作。
实际上DAO起到的是类似转换器的功能,即将实体转换为数据库中的记录或将数据库中的记录转换为实体。
通常DAO的组成部分包括以下四个内容:
- 数据库操作辅助类:实现数据库操作辅助功能,如获取连接,关闭连接等
- 实体类:用于数据传递
- DAO接口:约定DAO功能
- DAO接口的实现类:具体实现DAO功能
示例
数据库操作辅助类:
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/**
* JDBC辅助类
*
* @author 小明
*
*/
public class JdbcUtil {
/* 最好使用配置文件保存 */
private static String driver; // 驱动
private static String url; // 连接字符串
private static String user; // 用户名
private static String password; // 密码
private static Connection conn; // Connection对象
private static PreparedStatement pstmt; // PreparedStatement对象
private static ResultSet rs; // ResultSet对象
/* 加载数据库驱动 */
static {
loadProperties();
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
private JdbcUtil() {
}
/**
* 读取配置文件
*/
private static void loadProperties() {
Properties properties = new Properties();
InputStream in = Thread.currentThread().getClass()
.getResourceAsStream("/jdbc.properties");
try {
properties.load(in);
} catch (IOException e) {
throw new RuntimeException(e);
}
driver = properties.getProperty("driver");
url = properties.getProperty("url");
user = properties.getProperty("user");
password = properties.getProperty("password");
}
/**
* 获取数据库连接
*
* @return 连接对象
*/
public static Connection getConnection() {
try {
return conn = DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/**
* 释放ResultSet资源
*
* @param rs
*/
public static void close(ResultSet rs) {
try {
if (null != rs)
rs.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/**
* 释放ResultSet资源
*
* @param rs
*/
public static void close(Statement stmt) {
try {
if (null != stmt)
stmt.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/**
* 释放ResultSet资源
*
* @param rs
*/
public static void close(Connection conn) {
try {
if (null != conn)
conn.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/**
* 释放所有资源
*/
public static void close() {
try {
if (null != rs && !rs.isClosed()) {
rs.close();
}
rs = null;
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
try {
if (null != pstmt && !pstmt.isClosed()) {
pstmt.close();
}
pstmt = null;
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
try {
System.out.println(conn);
if (null != conn && !conn.isClosed()) {
conn.close();
}
conn = null;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
/**
* 执行增删改
*
* @param sql
* 待执行的SQL语句
* @param params
* SQL语句中?占位符的参数
* @return 受影响的行数
*/
public static int executeUpdate(String sql, Object... params) {
try {
if (null == conn)
getConnection();
pstmt = conn.prepareStatement(sql);
if (null != params) { // 为SQL语句中?占位符设置参数
for (int i = 0; i < params.length; i++) {
pstmt.setObject(i + 1, params[i]);
}
}
return pstmt.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/**
* 实现查询
*
* @param sql
* 待执行的查询SQL语句
* @param params
* SQL语句中?占位符的参数
* @return 查询结果集ResultSet对象
*/
public static ResultSet executeQuery(String sql, Object... params) {
try {
if (null == conn)
getConnection();
pstmt = conn.prepareStatement(sql);
if (null != params) { // 为SQL语句中?占位符设置参数
for (int i = 0; i < params.length; i++) {
pstmt.setObject(i + 1, params[i]);
}
}
return rs = pstmt.executeQuery();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
其中属性文件内容:
实体类:
/**
* 用户实体类
*
* @author 小明
*
*/
public class User {
private int id; // 编号
private String username; // 用户名
private String password; // 密码
private String gender; // 性别
private String address; // 地址
public User() {
super();
}
public User(String username, String password, String gender, String address) {
super();
this.username = username;
this.password = password;
this.gender = gender;
this.address = address;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
DAO接口:
/**
* 用户DAO接口
*
* @author 小明
*
*/
public interface UserDao {
/**
* 保存用户对象
*
* @param user
* 待保存的用户
* @return 受影响的行数
*/
int save(User user);
// 其它方法省略
// ………………
}
DAO实现类:
/**
* 用户接口实现类
*
* @author 小明
*/
public class UserDaoMySQLImpl implements UserDao {
@Override
public int save(User user) {
// SQL语句
String sql = "INSERT INTO users(username,password,gender,address) VALUES(?,?,?,?)";
// 建立连接
JdbcUtil.getConnection();
// 执行插入操作
int cnt = JdbcUtil.executeUpdate(sql, user.getUsername(),
user.getPassword(), user.getPassword(), user.getAddress());
// 释放资源
JdbcUtil.close();
return cnt;
}
// 其它方法省略
// ………………
}
测试:
/**
* 用户注册
*/
public void register() {
Scanner input = new Scanner(System.in);
System.out.print("请输入用户名:");
String username = input.next();
System.out.print("请输入密码:");
String password = input.next();
System.out.print("请输入性别:");
String gender = input.next();
System.out.print("请输入地址:");
String address = input.next();
// 创建用户对象
User user = new User(username, password, gender, address);
// 保存用户对象到数据库中
UserDao dao = new UserDaoMySQLImpl();
int cnt = dao.save(user);
// 处理结果
if (cnt == 1) {
System.out.println("注册成功");
} else {
System.out.println("注册失败");
}
}