package com.cn.test;

import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;

import org.junit.Test;

import com.cn.dao.PrepDao;
import com.cn.dao.impl.PrepDaoImpl;
import com.cn.domain.Prep;

/**
 * 
 * @ClassName: PrepDaoTest
 * @Description: PrepDao的测试类，主要用于对与预订相关的数据访问层（PrepDao）中的各个方法进行单元测试，
 *               验证如添加预订信息、删除预订信息、更新预订信息以及多种条件下查询预订信息等功能是否能正确与数据库交互并执行相应操作，
 *               以此确保PrepDao所提供的数据库操作功能符合预期。
 * @author: ljy
 * @date: 2019年9月16日 下午10:52:47
 */
public class PrepDaoTest {

    // 创建PrepDao接口的具体实现类PrepDaoImpl的实例，后续将通过该实例调用PrepDao中定义的各个数据库操作方法，
    // 来测试不同的预订信息相关的数据库操作功能。
    PrepDao prepDao = new PrepDaoImpl();

    /**
     * @Test注解表明这是一个JUnit测试方法，用于测试向数据库中添加单条预订信息的功能。
     * 在此方法中，先创建一个Prep对象并设置好相应的预订信息属性，然后调用prepDao的add方法将该预订信息添加到数据库中，
     * 最后通过打印返回结果来查看添加操作是否成功执行，若出现SQLException异常则打印异常栈信息方便排查问题。
     */
    @Test
    public void testAdd() {
        // 创建一个Prep对象，该对象用于封装要添加到数据库中的预订信息，其各个属性对应数据库中预订信息表的不同字段。
        Prep prep = new Prep();
        // 设置预订信息关联的列车ID，这里设置为4，代表预订的是数据库中ID为4的列车对应的车次，实际应用中该值应根据业务逻辑确定。
        prep.setTrainId(4);
        // 设置预订信息关联的会员（乘客）ID，此处设为2，表明是哪位会员进行的预订，同样需根据实际业务情况来确定该值。
        prep.setPmemberId(2);
        // 设置列车的起始站名称，将其设置为"上海"，表示预订的列车出发站点。
        prep.setStartStation("上海");
        // 设置列车的终点站名称，此处设为"北京"，代表预订的列车最终到达的站点。
        prep.setEndStation("北京");
        // 设置列车的车次编号，这里将其设置为"K113"，是一个示例车次，需符合实际车次命名规则和业务要求。
        prep.setTrainNumber("K113");
        // 设置列车的出发时间，采用"yyyy-MM-dd HH:mm:00"格式的字符串来表示时间，这里设置的具体时间为2019-09-01 15:30:00，
        // 该格式需与数据库中对应时间字段的存储格式相匹配，以确保能正确插入数据。
        prep.setStartTime("2019-09-01 15:30:00");
        // 设置列车的到达时间，同样遵循"yyyy-MM-dd HH:mm:00"格式，设置为2019-09-01 16:40:00，用于表示列车预计到达终点站的时间。
        prep.setEndTime("2019-09-01 16:40:00");
        // 设置列车的票价，单位通常为某种货币单位（比如人民币元），这里设置为200，仅作为测试用途的示例价格数值。
        prep.setPrice(200);
        // 设置预订的某种状态（这里不太明确具体含义，从变量名way推测可能是预订方式之类的布尔值属性），此处设为false，具体取值根据业务定义来确定。
        prep.setWay(false);

        // 获取当前系统时间，并将其转换为Timestamp类型，用于设置预订信息的预订时间，即记录这条预订信息是什么时候创建的。
        Timestamp booktime = new Timestamp(new Date().getTime());
        prep.setBooktime(booktime);

        try {
            // 调用prepDao的add方法，该方法在PrepDao接口中定义，并由PrepDaoImpl类实现具体逻辑。
            // 其内部会构建合适的SQL插入语句，与数据库建立连接，然后将Prep对象所包含的预订信息插入到数据库对应的预订信息表中，
            // 返回值recordNumber通常表示受影响的数据库记录行数，在成功插入一条记录的情况下，一般返回值为1，这里将其打印输出，
            // 以便查看添加操作是否按预期成功执行，如果出现SQLException异常（比如数据库连接问题、SQL语法错误等情况）则会进入catch块进行处理。
            int recordNumber = prepDao.add(prep);
            System.out.println(recordNumber);
        } catch (SQLException e) {
            // 如果在执行添加预订信息的操作过程中出现了SQLException异常，
            // 通过e.printStackTrace()方法打印异常的栈追踪信息，方便开发人员排查问题所在，确定是哪部分代码或者数据库相关配置导致了异常的出现。
            e.printStackTrace();
        }
    }

    /**
     * @Test注解表明这是一个JUnit测试方法，用于测试根据预订信息的某种标识（可能是主键等唯一标识）从数据库中删除对应预订信息的功能。
     * 在此方法中，调用prepDao的delete方法并传入指定的标识值，尝试从数据库中删除相应的预订记录，
     * 最后通过打印返回结果来查看删除操作是否成功执行，若出现SQLException异常则打印异常栈信息以便排查问题。
     */
    @Test
    public void testDelete() {
        try {
            // 调用prepDao的delete方法，该方法的具体实现位于PrepDaoImpl类中，其内部会构建相应的SQL删除语句，
            // 根据传入的预订信息标识（这里传入的硬编码值为2，仅作为测试示例，实际应用中应根据具体业务需求获取要删除的预订信息标识），
            // 在数据库中查找并删除对应的预订记录，处理数据库连接以及执行删除操作等相关事宜。
            // 返回值recordNumber通常表示受影响的数据库记录行数，若成功删除对应的预订记录，返回值一般为1；若数据库中不存在该标识对应的记录，则返回值为0。
            // 将返回的recordNumber打印输出，便于查看删除操作是否按预期成功执行。
            int recordNumber = prepDao.delete(2);
            System.out.println(recordNumber);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * @Test注解表明这是一个JUnit测试方法，用于测试更新数据库中预订信息的功能。
     * 先创建一个包含更新后信息的Prep对象，设置好相应的预订信息属性以及要更新的预订记录的标识，然后调用prepDao的update方法，
     // 将这些更新内容应用到数据库中对应的预订记录上，最后通过打印返回结果来查看更新操作是否成功执行，若出现SQLException异常则打印异常栈信息方便排查问题。
     */
    @Test
    public void testUpdate() {
        Prep prep = new Prep();
        // 设置要更新的预订记录在数据库中的唯一标识（ID），这里将其设置为3，代表要更新的是数据库中ID为3的预订记录，
        // 通过这个ID可以准确找到对应的预订信息行进行更新操作，实际应用中该值应根据具体业务需求来确定，比如通过用户输入或者其他业务逻辑获取。
        prep.setPrepId(3);
        prep.setTrainId(4);
        prep.setPmemberId(2);
        prep.setStartStation("上海");
        // 设置更新后的终点站名称为"北京洞窟"，这里可能是测试修改目的地等信息的情况，实际应用中应符合业务要求的合理站点名称。
        prep.setEndStation("北京洞窟");
        prep.setTrainNumber("K113");
        // 此处设置的出发时间格式有误，应该是"yyyy-MM-dd HH:mm:00"格式，比如"2019-09-01 15:30:00"，当前的"2019-19-01 15:30:00"不符合日期规范，可能导致数据库插入或更新失败，需修正。
        prep.setStartTime("2019-19-01 15:30:00");
        // 同样，此处到达时间格式也有误，应修正为正确的日期时间格式，如"2019-09-01 16:40:00"。
        prep.setEndTime("2019-19-01 16:40:00");
        // 设置更新后的票价为1200，改变了预订的价格信息。
        prep.setPrice(1200);
        // 设置更新后的预订状态（way属性）为true，具体含义根据业务定义来确定。
        prep.setWay(true);

        try {
            // 调用prepDao的update方法，该方法在PrepDao接口中定义并由PrepDaoImpl类实现具体更新逻辑，
            // 其内部会根据传入的Prep对象所携带的更新信息，在数据库中查找并更新对应ID的预订记录，例如构建合适的SQL更新语句、
            // 处理数据库连接以及执行更新操作等，返回值recordNumber通常表示受影响的数据库记录行数，若成功更新对应的预订记录，返回值一般为1；
            // 若数据库中不存在该ID对应的记录，则返回值为0，将返回的recordNumber打印输出，便于查看更新操作是否按预期成功执行。
            int recordNumber = prepDao.update(prep);
            System.out.println(recordNumber);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * @Test注解表明这是一个JUnit测试方法，用于测试从数据库中获取所有预订信息的功能。
     * 调用prepDao的getAll方法获取数据库中全部的预订记录，然后遍历获取到的预订信息列表，将每条预订信息打印输出，
     * 以此来验证查询所有预订信息的功能是否能正确执行，查看返回的预订信息是否符合预期，若出现SQLException异常则打印异常栈信息以便排查问题。
     */
    @Test
    public void testGetAll() {
        try {
            // 调用prepDao的getAll方法，该方法的具体实现位于PrepDaoImpl类中，其内部会构建相应的SQL查询语句，
            // 执行查询操作从数据库的预订信息表中获取所有记录，并将这些记录封装为Prep对象列表返回，以便后续进行遍历和处理。
            List<Prep> list = prepDao.getAll();
            for (Prep prep : list) {
                // 遍历获取到的预订信息列表，通过调用prep对象的toString方法将每条预订信息以字符串的形式打印输出，
                // toString方法通常会按照一定的格式展示预订对象的各个属性信息，方便查看查询结果的具体内容，了解所有预订的详细情况。
                System.out.println(prep.toString());
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * @Test注解表明这是一个JUnit测试方法，用于测试根据会员（乘客）ID从数据库中获取对应预订信息的功能。
     * 在此方法中，先传入指定的会员ID值，然后调用prepDao的getPrepByPmemberId方法，
     * 根据该会员ID查询并获取相应的预订记录，最后遍历并打印输出获取到的预订信息，以此验证按会员ID查询预订信息的功能是否正确，若出现SQLException异常则打印异常栈信息以便排查问题。
     */
    @Test
    public void testGetPrepByPmemberId() {
        try {
            // 调用prepDao的getPrepByPmemberId方法，传入会员ID值2（这里是硬编码示例，实际应用中根据具体业务场景传入相应会员ID），
            // 该方法的具体实现位于PrepDaoImpl类中，其内部会构建相应的SQL查询语句，根据传入的会员ID在数据库中查找并获取该会员的所有预订记录，
            // 将查询到的预订信息封装为Prep对象列表返回，以便后续遍历展示。
            List<Prep> list = prepDao.getPrepByPmemberId(2);
            for (Prep prep : list) {
                // 遍历获取到的预订信息列表，通过调用prep对象的toString方法将每条预订信息以字符串形式打印输出，
                // 方便查看查询到的符合条件的预订记录内容，确认是否获取到了期望的预订信息。
                System.out.println(prep.toString());
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * @Test注解表明这是一个JUnit测试方法，用于测试根据预订信息的唯一标识（ID）从数据库中获取对应预订信息的功能。
     * 在此方法中，先定义要查询的预订记录在数据库中的唯一标识（ID），然后调用prepDao的getById方法，
     * 根据该ID查询并获取相应的预订记录，最后将获取到的预订信息打印输出，以此验证按预订信息ID查询的功能是否正确，若出现SQLException异常则打印异常栈信息以便排查问题。
     */
    @Test
    public void testGetById() {
        try {
            // 定义要查询的预订记录在数据库中的唯一标识（ID），这里将其设置为3，代表要获取ID为3的预订信息，仅作为测试示例，
            // 实际应用中可根据具体业务场景通过合适的方式获取相应的预订信息ID值，比如从用户输入、其他关联数据等途径获取。
            Integer prepId = 3;
            // 调用prepDao的getById方法，该方法的具体实现位于PrepDaoImpl类中，其内部会构建合适的SQL查询语句，
            // 根据传入的预订信息ID在数据库中查找并获取对应预订记录，将查询到的预订信息封装为Prep对象返回，以便后续进行展示或其他处理。
            Prep prep = prepDao.getById(prepId);
            // 打印输出获取到的预订信息，通过调用prep对象的toString方法将预订对象的各个属性以字符串形式展示出来，
            // 方便查看查询结果，确认获取到的预订信息是否符合预期。
            System.out.println(prep.toString());
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 以下代码被注释掉了，从代码结构来看，它原本可能也是用于测试向数据库中添加预订信息的功能，不过采用了不同的方式（使用了JDBCUtil和QueryRunner等工具类来操作数据库）。
     * 这里暂不生效，但保留注释方便后续查看或可能的代码复用等情况。
     */
    /*
    private static JDBCUtil jdbcUtil = new JDBCUtil();

    @Test
    public void test() {

        Connection conn = jdbcUtil.getConnection();
        QueryRunner queryRunner = new QueryRunner();

        Prep prep = new Prep();
        prep.setTrainId(4);
        prep.setPmemberId(2);
        prep.setStartStation("上海");
        prep.setEndStation("北京");
        prep.setTrainNumber("K113");
        prep.setStartTime("2019-09-01 15:30:00");
        prep.setEndTime("2019-09-01 16:40:00");
        prep.setPrice(200);
        prep.setWay(false);
        Timestamp booktime = new Timestamp(new Date().getTime());
        prep.setBooktime(booktime);


        try {
            int recordNumber = queryRunner.update(conn,
                    "insert into prep (trainid,pmemberid,startstation,endstation,trainnumber,starttime,endtime,price,way,booktime) values (?,?,?,?,?,?,?,?,?,?)",
                    prep.getTrainId(), prep.getPmemberId(), prep.getStartStation(), prep.getEndStation(), prep.getTrainNumber(),
                    prep.getStartTime(), prep.getEndTime(), prep.getPrice(), prep.isWay(), prep.getBooktime());
            System.out.println(recordNumber);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            DbUtils.close(conn);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    */
}