MySQL学习笔记 09 - 封装JDBC和单元测试

一、封装JDBC

1、executeUpdate方法

添加删除修改的例子中,变化的数据只有SQL语句,其余的代码都是重复的,因此将重复代码封装到一个方法中,变化的数据定义为方法参数。为此我们定义一个专门用于执行增删改的方法executeUpdate,方法定义如下:

int executeUpdate(String sql,Object …values)

说明:

  1. 方法参数sql是要执行的insertupdatedelete语句。
  2. 方法可变参数valuesinsertupdatedelete语句中占位符
  3. sqlvalues这两个参数从外界传入,即外界传入什么样的SQL语句,executeUpdate()方法就执行什么样的SQL语句。
  4. 返回值int表示SQL语句执行后影响的行数

2、executeQuery方法

在查询的例子中,每次查询的SQL语句不同,为此我们定义一个专门用于执行查询的方法executeQuery,方法定义如下:

ResultSet executeQuery(String sql,Object …values) 

说明:

  1. 方法参数sql是要执行的select语句。
  2. 方法可变参数values是SQL语句中占位符的值
  3. sqlvalues这两个参数从外界传入,即外界传入什么样的SQL,executeQuery方法就 执行什么样的SQL语句。
  4. 返回值ResultSet表示SQL语句执行查询后的查询结果集。

3、封装JDBC

executeUpdate(String sql,Object …values)方法和executeQuery(String sql, Object … values )中都需要将values的值赋给sql语句中占位符?,因此将这两个方法中为占位符?赋值的代码抽象出来,定义为void setParameter(Object …values)方法。
executeUpdate(String sql,Object …values)方法和executeQuery(String sql, Object … values)中都需要连接数据库关闭资源,因此将这两个方法中连接数据库的代码抽象出来,封装成getConnection()方法,用于连接数据库,将关闭资源的代码抽象出来,封装成close()方法,用于关闭资源。
Connection对象、PreparedStatement对象、ResultSet对象、连接字符串定义为类的属性,由于这些属性不允许外界访问,因此将其定义为私有
由于该类是专门执行SQL语句的类,因此我们称它为DBHelper类。
实例:

import java.sql.*;

/**
 * 数据库访问助手
 *
 * @author DingYi
 * @date 2020/5/2 15:10
 */
public class DBHelper {

  // 数据库连接
  private Connection conn = null;
  // 语句
  private PreparedStatement ps = null;
  // 结果集
  private ResultSet rs = null;
  // 连接URL
  private static final String URL = "jdbc:mysql://localhost:3306/user_manager?useSSL=false&characterEncoding=utf8";
  // 用户名
  private static final String USER = "root";
  // 密码
  private static final String PASS = "root";


  // 1.加载驱动
  //加载驱动只需做一遍,故可以写在静态代码块中
  static {
    try {
      Class.forName("com.mysql.jdbc.Driver");
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    }
  }

  // 2. 获得连接
  private void getConnection() throws SQLException {
    if(conn == null || conn.isClosed()){
      conn = DriverManager.getConnection(URL,USER,PASS);
    }
  }

  // 为占位符?赋值
  private void setParameter(Object ... values) throws SQLException {
    if(values != null && values.length > 0){
      for(int i = 0; i < values.length; i ++) {
        ps.setObject(i + 1, values[i]);
      }
    }
  }

  /**
   * 执行增删改的方法
   * @param sql 要执行的sql语句
   * @param values sql语句中?占位符的值
   * @return 执行结果
   * @throws SQLException sql异常
   */
  public int executeUpdate(String sql, Object ... values) throws SQLException {
    // 获得连接
    getConnection();
    // 创建语句
    ps = conn.prepareStatement(sql);
    // 为占位符?赋值
    setParameter(values);
    // 执行sql语句
    return ps.executeUpdate();
  }

  /**
   * 执行查询的sql语句
   * @param sql 要执行的sql语句
   * @param values sql语句中?占位符的值
   * @return 查询结果
   * @throws SQLException sql异常
   */
  public ResultSet executeQuery(String sql, Object ... values) throws SQLException {
    // 获得连接
    getConnection();
    // 创建语句
    ps = conn.prepareStatement(sql);
    // 为占位符?赋值
    setParameter(values);
    // 执行查询
    rs = ps.executeQuery();
    return rs;
  }

  // 6. 关闭资源
  public void close() throws SQLException {
    if(rs != null){
      rs.close();
      rs = null;
    }
    if(ps != null){
      ps.close();
      ps = null;
    }
    if(conn != null){
      conn.close();
      conn = null;
    }
  }
}

二、单元测试

1、单元测试

软件开发完成后,难免有bug存在(软件的缺陷称为bug),为了减少或避免bug,就必须对软件进行测试,发现bug后对bug进行修复,使得软件具有很好的稳定性健壮性
软件测试分为单元测试模块测试集成测试。通常模块测试集成测试测试工程师的职责,单元测试通常是开发工程师的职责。
单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。对于单元测试中单元的含义,在Java中单元指一个或者一个方法。通常使用JUnit单元测试工具对Java进行单元测试。
测试过程:

  1. 导入必要的包
    单元测试的类和注解位于JUnit4框架的org.junit包中,因此需要导入org.junit.*。断言类Assert的断言方法assertEquals静态方法,使用静态导入import static org.junit.Assert.*后在单元测试类中可以直接使用Assert类的静态方法进行断言。
  2. 测试类的定义
    测试类CalculatorTest是一个独立的类,没有显示继承任何父类。测试类的名字也可以任意命名没有任何局限性。所以我们不能通过类的声明来判断它是不是一个测试类,它与普通类的区别在于它内部方法声明
  3. 创建待测试的对象
    要测试哪个类,首先就要创建一个该类的对象,如:
private static Calculator calculator = new Calculator();

在单元测试中,方法上标注了@Test后,表明该方法是单元测试方法。除了@Test注解外,还有一些重要的注解,其作用如下表所示:

注解解释示例
@Test标注在方法上,表明这是一个测试方法,返回值必须为void,而且不能有任何参数。@Test
public void test() {
}
@Before在任何一个测试执行之前必须执行的代码@Before
public void setUp() throws Exception {
}
@After在任何测试执行之后需要进行的收尾工作@After
public void tearDown () throws Exception {
}
@BeforeClass1:针对所有测试
2:只在测试用例初始化时执行一次
3:每个测试类只能有一个方法被标注为@BeforeClass
4:该方法必须是publicstatic
@BeforeClass
public static void beforeClass() {
}
@AfterClass1:针对所有测试
2:只在测试用例执行结束时执行一次
3:每个测试类只能有一个方法被标注为@AfterClass
4:该方法必须是publicstatic 的。
@ AfterClass
public static void AfterClass() {
}
@Ignore忽略的测试方法

一个JUnit4的单元测试用例执行顺序为:
在这里插入图片描述注意:

  1. 需要的jar包

hamcrest-core-1.3.jar
junit-4.12.jar

  1. 在进行单元测试时,需要把相应地Package导入进来。最主要的Packageorg.junit.*。 该包中包含了单元测试需要的绝大多数类;还需要导入import static org.junit.Assert.*, 其中包含了许多断言断言帮助我们判断测试的结果

2、测试用例

测试用例Test Case)是为某个特殊目标而编制的一组测试输入执行条件以及预期结果,以便测试某个程序路径或核实是否满足某个特定需求。测试之前应先编写测试用例,根据测试用例进行测试,并记录测试结果。下表是测试用例:
在这里插入图片描述
说明:

  1. 桩模块:是指模拟被测试的模块所调用的模块
  2. 测试状态:P指通过 F指失败

实例:
创建功能类

/**
 * 功能类
 *
 * @author DingYi
 * @date 2020/5/2 21:50
 */
public class Calculator {
  private static int result = 0; // 静态变量,用户存储计算结果

  public void add (int n) {
    result = result + n;
  }

  public void substract(int n) {
    // result = result - n;
    result = result - 1;
  }

  public void multiply(int n) {
    // result = result * n;
    // TODO 待开发
  }

  public void divide(int n) {
    result = result / n;
  }

  public void clear() {
    result = 0;
  }

  public int getResult() {
    return result;
  }
}

测试类:

import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;

import static org.junit.Assert.*;
/**
 * 测试类
 *
 * @author DingYi
 * @date 2020/5/2 21:57
 */
public class CalculatorTest {
  private static Calculator calculator = new Calculator();

  @Before
  public void setUp() throws Exception {
    calculator.clear();
  }

  @After
  public void tearDown() throws Exception {
    calculator.clear();
  }


  @Test
  public void add() {
    calculator.add(2);
    calculator.add(3);
    assertEquals(5, calculator.getResult());
  }

  @Test
  public void substract() {
    calculator.add(10);
    calculator.substract(2);
    assertEquals(8, calculator.getResult());
  }

  @Ignore("乘法还没有开发呢,暂时不需要测试")
  @Test
  public void multiply() {
  }

  @Test
  public void divide() {
    calculator.add(8);
    calculator.divide(2);
    assertEquals(4, calculator.getResult());
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值