Dao模式
程序员写的是业务(因为其逻辑性不太强)
软件设计原则:开闭原则,对新增加的进行开放,对修改关闭
实际开发中, web项目, 程序员编写业务代码
把所有的代码都写在业务方法中:
接收前端请求,获取请求参数…
编写业务代码处理请求
调用jdbc代码操作数据
把数据进行加工
把数据响应给前端
缺点:
方法很臃肿, 这个方法不便于复用, 部分重复代码重复写
方法的扩展性不好, 因为代码全部集中在一个方法内部, 替换某部分的代码,对这个方法进行修改
解决方案: 拆的思想
把方法拆分为多个方法, 不是OOP编程思想
把方法拆分为多个方法,把这个方法分类, 把不同功能的方法放在不同的类, 不同层次的类在进行分层(包)
常见的分层:
操作数据库的层: DAO层(数据访问层)
业务处理的层: service层(业务层)
表对应实体类层: 实体层(entity,pojo)
工具类存放的层: 工具层(util)
处理前端请求层: web层
分层的目的:
使用层来技术隔离, 方便每一层的技术替换,而不需要修改其他层
使用层来进行解耦, 每一层直接的调用, 以接口的形式
![]()
上下层之分, 上层调用下层,不能下层调用上层,不能跨层调用
使用dao模式开发:
-
编写实体类, 与数据库的表一一对应
类与表对应
一行记录对应类的一个对象
表的字段对应类的属性
数据库的数据类型与java的数据类型对应 java推荐使用包装类型
mysql java int Integer/int bigint Long/long double Double/double decimal java.math.BigDecimal /Double char/varchar/text String date/datetime/time/timestamp java.util.Date tinyint Integer/int/Boolean
package com.fs.soso.entity; /** * 对应tb_card表的实体类 */ public class Card { private Integer id; private String cardNumber; private Integer status; //get/set toString public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getCardNumber() { return cardNumber; } public void setCardNumber(String cardNumber) { this.cardNumber = cardNumber; } public Integer getStatus() { return status; } public void setStatus(Integer status) { this.status = status; } @Override public String toString() { return "Card{" + "id=" + id + ", cardNumber='" + cardNumber + '\'' + ", status=" + status + '}'; } public Card() { } public Card(Integer id, String cardNumber, Integer status) { this.id = id; this.cardNumber = cardNumber; this.status = status; } public Card(String cardNumber, Integer status) { this.cardNumber = cardNumber; this.status = status; } }
-
编写dao接口,以及dao接口的实现类
实体类–> 实体类dao接口 –> 实体类dao实现类–> 实体类业务接口 –> 实体类业务接口实现类
Card –> [I]CardDao –> CardDaoImpl –> [I]CardService–> CardServiceImpl
package com.fs.soso.dao; import com.fs.soso.entity.Card; import java.util.List; /** * 卡的数据访问接口 * CURD */ public interface CardDao { /** * 添加记录 * @param card 手机卡对象 * @return 受影响行数 */ int add(Card card); /** * 根据主键修改 * @param card 手机卡对象 * @return 受影响行数 */ int updateById(Card card); /** * 根据主键删除 * @param id 主键值 * @return 受影响行数 */ int deleteById(int id); /** * 根据主键查询 * @param id 主键 * @return 手机卡对象 */ Card queryById(int id); /** * 查询所有 * @return 手机卡List集合 */ List<Card> queryAll(); }
package com.fs.soso.dao.impl; import com.fs.soso.dao.CardDao; import com.fs.soso.entity.Card; import com.fs.soso.util.JdbcUtil; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; public class CardDaoImpl implements CardDao { @Override public int add(Card card) { Connection conn = null; PreparedStatement pstmt = null; try { conn = JdbcUtil.getConnection(); String sql ="insert into tb_card(cardNumber,status) values(?,?)"; pstmt = conn.prepareStatement(sql); pstmt.setObject(1,card.getCardNumber()); pstmt.setObject(2,card.getStatus()); return pstmt.executeUpdate(); } catch (SQLException throwables) { throwables.printStackTrace(); }finally { JdbcUtil.close(conn,pstmt,null); } return 0; } @Override public int updateById(Card card) { Connection conn = null; PreparedStatement pstmt = null; try { conn = JdbcUtil.getConnection(); String sql ="update tb_card set status = ? where id = ? "; pstmt = conn.prepareStatement(sql); pstmt.setObject(1,card.getStatus()); pstmt.setObject(2,card.getId()); return pstmt.executeUpdate(); } catch (SQLException throwables) { throwables.printStackTrace(); }finally { JdbcUtil.close(conn,pstmt,null); } return 0; } @Override public int deleteById(int id) { Connection conn = null; PreparedStatement pstmt = null; try { conn = JdbcUtil.getConnection(); String sql ="delete from tb_card where id = ? "; pstmt = conn.prepareStatement(sql); pstmt.setObject(1,id); return pstmt.executeUpdate(); } catch (SQLException throwables) { throwables.printStackTrace(); }finally { JdbcUtil.close(conn,pstmt,null); } return 0; } @Override public Card queryById(int id) { Connection conn = null; PreparedStatement pstmt = null; ResultSet resultSet = null; try { conn = JdbcUtil.getConnection(); String sql ="select * from tb_card where id = ? "; pstmt = conn.prepareStatement(sql); pstmt.setObject(1,id); resultSet = pstmt.executeQuery(); Card card=null; while(resultSet.next()){ card = new Card(); //给属性赋值 //getXxx(int 列的序号从1开始) //getXxx(String 列名) 可读性高 card.setId(resultSet.getInt("id")); card.setCardNumber(resultSet.getString("cardNumber")); card.setStatus(resultSet.getInt("status")); } return card; } catch (SQLException throwables) { throwables.printStackTrace(); }finally { JdbcUtil.close(conn,pstmt,null); } return null; } @Override public List<Card> queryAll() { Connection conn = null; PreparedStatement pstmt = null; ResultSet resultSet = null; try { conn = JdbcUtil.getConnection(); String sql ="select * from tb_card"; pstmt = conn.prepareStatement(sql); resultSet = pstmt.executeQuery(); List<Card> cards = new ArrayList<>(); while(resultSet.next()){ Card card = new Card(); //给属性赋值 card.setId(resultSet.getInt("id")); card.setCardNumber(resultSet.getString("cardNumber")); card.setStatus(resultSet.getInt("status")); //把对象添加到集合中 cards.add(card); } return cards; } catch (SQLException throwables) { throwables.printStackTrace(); }finally { JdbcUtil.close(conn,pstmt,null); } return null; } }
junit进行单元测试
对编写方法进行测试, 实际开发中,使用junit进行单元测试
使用步骤:
导入junit依赖
![]()
![]()
![]()
![]()
2.创建存放测试源代码的资源目录
项目完成之后, 删除测试代码
创建存放测试代码的资源目录 test
![]()
![]()
根据被测试的类(接口),生成对应的测试类
![]()
![]()
![]()
编写测试代码
package com.fs.soso.dao; import com.fs.soso.dao.impl.CardDaoImpl; import com.fs.soso.entity.Card; import org.junit.After; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.*; public class CardDaoTest { private CardDao cardDao; /** * setUp() 使用 before修饰的, 表示该方法在调用测试方法之前执行 * 做准备工作 * @throws Exception */ @Before public void setUp() throws Exception { //System.out.println("setUp..."); cardDao = new CardDaoImpl(); } /** * tearDown() 使用 After修饰的, 表示该方法在调用测试方法之后执行 * 释放资源 * @throws Exception */ @After public void tearDown() throws Exception { //System.out.println("tearDown..."); } /** * @Test 标记方法上,表示这个方法是一个测试方法 * 直接运行测试方法,不需要main调用 * 测试方法要求: * 1. 返回值类型只能是void * 2. 一定是无参方法 * 3.不能是static修饰 */ @Test public void add() { //System.out.println("add..."); Card card = new Card("16666666666",0); int rs = cardDao.add(card); System.out.println(rs); } @Test public void updateById() { Card card = new Card(12,"16666666666",1); cardDao.updateById(card); } @Test public void deleteById() { } @Test public void queryById() { System.out.println(cardDao.queryById(12)); } @Test public void queryAll() { System.out.println(cardDao.queryAll()); } }