DAO设计模式
DAO(Database Access Object 数据库访问对象),为了降低耦合性,提出了DAO封装数据库操作的设计模式。
它可以实现业务逻辑与数据库访问相分离。相对来说,数据库是比较稳定的,其中DAO组件依赖于数据库系统,提供数据库访问的接口,隔离了不同的数据库实现。
组成部分:
1 DAO接口(主要包 添加 修改 查询 删除方法)
2 DAO实现类
3 实体类 (domain、beans、entity、pojo、model)
--作用:用在数据访问代码和业务逻辑代码之间通过实体类来传输数据
--实体类特征:
◦属性一般使用private修饰
◦提供public修饰的getter/setter方法
◦实体类提供无参构造方法,根据业务提供有参构造
◦实现java.io.Serializable接口,支持序列化机制
4 数据库连接和关闭工具类
设计的包名:
domain 存放实体类
utils 存放工具类
dao 存放接口
dao.impl 存放实现类
- 实例:
@Data
public class Employee implements Serializable {
private static final long serialVersionUID = 373910607014836778L;
private int empno;
private String ename;
private String job;
private int mgr;
private Date hiredate;
private double sal;
private double comm;
private int deptno;
public Employee() {
// TODO Auto-generated constructor stub
}
public Employee(int empno, String ename, String job, int mgr, Date hiredate, double sal, double comm, int deptno) {
super();
this.empno = empno;
this.ename = ename;
this.job = job;
this.mgr = mgr;
this.hiredate = hiredate;
this.sal = sal;
this.comm = comm;
this.deptno = deptno;
}
}
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class DbUtils {
//驱动名称
static String driver="com.mysql.jdbc.Driver";
//url连接字符串
static String url="jdbc:mysql://localhost:3306/school";
//用户名
static String user="root";
//密码
static String password="root";
static {
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
System.out.println("注册驱动失败");
}
}
/**
* 获取连接
* @return
*/
public static Connection getConnection() {
try {
return DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* 释放资源
* @param rs
* @param stat
* @param conn
*/
public static void closeAll(ResultSet rs,Statement stat,Connection conn) {
try {
if(rs!=null) {
rs.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(stat!=null) {
stat.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(conn!=null) {
conn.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 执行命令
* @param sql insert int emp() values(?,?,?,?)
* @param params
*/
public static int executeUpdate(String sql,Object... params) {
try {
Connection conn = getConnection();
PreparedStatement pstat = conn.prepareStatement(sql);
if(params!=null) {
for(int i=0;i<params.length;i++) {
pstat.setObject(i+1, params[i]);
}
}
int count=pstat.executeUpdate();
closeAll(null, pstat, conn);
return count;
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
}
public interface EmployeeDao {
//1查询
List<Employee> findAll();
//2更新
void update(Employee e);
//3删除
void delete(int empno);
//4添加
void add(Employee e);
}
public class EmployeeDaoImpl implements EmployeeDao{
@Override
public List<Employee> findAll() {
ArrayList<Employee> employees=new ArrayList<Employee>();
//1获取连接
Connection conn=null;
PreparedStatement pstat=null;
ResultSet rs=null;
try {
conn=DbUtils.getConnection();
pstat=conn.prepareStatement("select * from emp;");
rs=pstat.executeQuery();
while(rs.next()){
int empno=rs.getInt("empno");
String ename=rs.getString("ename");
String job=rs.getString("job");
int mgr=rs.getInt("mgr");
Date date=rs.getDate("hiredate");
double sal=rs.getDouble("sal");
double comm=rs.getDouble("comm");
int deptno=rs.getInt("deptno");
Employee employee=new Employee(empno, ename, job, mgr, date, sal, comm, deptno);
employees.add(employee);
}
return employees;
} catch (Exception e) {
throw new RuntimeException("查询emp失败");
} finally {
DbUtils.closeAll(rs, pstat, conn);//查看上文博客
}
}
@Override
public void update(Employee e) {
Object[] params={e.getEname(),e.getJob(),e.getMgr(),e.getHiredate(),e.getSal(),e.getComm(),e.getDeptno(),e.getEmpno()};
DbUtils.executeUpdate("update emp set ename=?,job=?,mgr=?,hiredate=?,sal=?,comm=?,deptno=? where empno=?", params);
}
@Override
public void delete(int empno) {
DbUtils.executeUpdate("delete from emp where empno=?", empno);
}
@Override
public void add(Employee e) {
Object[] params={e.getEmpno(),e.getEname(),e.getJob(),e.getMgr(),e.getHiredate(),e.getSal(),e.getComm(),e.getDeptno()};
DbUtils.executeUpdate("insert into emp values(?,?,?,?,?,?,?,?)", params);
}
}
DBUtils
Commons DbUtils是Apache组织提供的一个对JDBC进行简单封装的开源工具类库,使用它能够简化JDBC应用程序的开发,同时也不会影响程序的性能。
是java编程中的数据库操作实用工具,小巧简单实用:
1.对于数据表的读操作,可以把结果转换成List,Array,Set等java集合,便于程序员操作。
2.对于数据表的写操作,也变得很简单(只需写sql语句)。
- DBUtils主要类:
DbUtils类:启动类
QueryRunner类:执行SQL语句的类(方法:query,update等)
--注:insert 和 update 方法都能执行 “insert” 开头的sql语句,但是返回值有区别。
--insert 执行后返回的是表中的插入行生成的主键值
--update 返回的是受语句影响的行数
--所以,如果目标表中有主键且需要返回插入行的主键值就用 insert 方法,
--如果表没有主键或者不需要返回主键值可使用 update 方法。
ResultSetHandler接口:转换类型接口
--BeanHandler类:实现类,把记录转成 JavaBean 类型的对象
--BeanListHandler类:实现类,把记录转化记录为 JavaBean 类型对象的 List
--ScalarHandler类:适合获取一行或一列数据,或记录的个数
--ColumnListHandler类:取某一列的数据。封装到 List 中
--ArrayHandler类:实现类,把一条记录转化成 Object 类型数组
--ArrayListHandler类:把所有记录转化成数组,并放入 List 集合中
- 实例:
导入jar包:commons-dbutils-1.6.jar druid-1.1.5.jar mysql-connector-java-5.1.41-bin.jar
配置文件:database.properties
public class DataSourceUtils {
//声明连接池对象
private static DruidDataSource dataSource;
static{
//实例化配置对象
Properties properties=new Properties();
try {
//加载配置文件内容
properties.load(DataSourceUtils.class.getClassLoader().getResourceAsStream("database.properties"));
dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
public static DataSource getDataSource(){
return dataSource;
}
}
public class ResultHanlder {
@Test
public void testArrayHander() throws SQLException {
// ArrayHandler:适合取1条记录。把该条记录的每列值封装到一个数组中Object[]
QueryRunner runner = new QueryRunner(DruidUtils.getDataSource());
Object[] query = runner.query("select * from school where empno = ?", new ArrayHandler(), 1234);
for (Object object : query) {
System.out.println(object);
}
}
@Test
public void testArrayListHander() throws SQLException {
// ArrayHandler:适合取1条记录。把该条记录的每列值封装到一个数组中Object[]
QueryRunner runner = new QueryRunner(DruidUtils.getDataSource());
List<Object[]> query = runner.query("select * from emp ", new ArrayListHandler());
for (Object[] objects : query) {
for (Object object : objects) {
System.out.println(object);
}
}
}
@Test
public void testColumnListHander() throws SQLException {
// ColumnListHandler:取某一列的数据。封装到List中。
QueryRunner runner = new QueryRunner(DruidUtils.getDataSource());
List<Object> query = runner.query("select * from emp ", new ColumnListHandler<Object>(2));
for (Object objects : query) {
System.out.println(objects);
}
}
@Test
public void testScalarHandler() throws SQLException {
// ScalarHandler:适合取单行单列数据
QueryRunner runner = new QueryRunner(DruidUtils.getDataSource());
Object query = runner.query("select count(*) from emp ", new ScalarHandler());
System.out.println(query);
}
@Test
public void testBeanHandler() throws SQLException {
// BeanHandler:适合取单行单列数据
QueryRunner runner = new QueryRunner(DruidUtils.getDataSource());
Employee query = runner.query("select * from emp where empno=1234 ", new BeanHandler<Employee>(Employee.class));
System.out.println(query.toString());
}
@Test
public void testBeanListHandler() throws SQLException {
// BeanHandler:适合取多行多列数据
QueryRunner runner = new QueryRunner(DruidUtils.getDataSource());
List<Employee> query2 = runner.query("select * from emp", new BeanListHandler<Employee>(Employee.class));
for (Employee employee : query2) {
System.out.println(employee);
}
}
}