14、JDBC強化

新增的知識點

  • 密碼加密
  • 文件上傳
  • 獲取自增的key
  • 使用枚舉、泛型
  • jdbc事務(多表關聯)
  • 瞭解sql注入

引出來的幾點知識點

JDBC強化案例

單元測試

public class StudentTest {
    StudentService studentService = new StudentServiceImpl();

    @Test
    public void addStudentTest() {
        Student student = new Student(null, "jackson", "1234", "E:\\2019屆資協材料\\教材.jpg",
                "男", 48, "英國倫敦", "87626145", System.currentTimeMillis(), null);
        System.out.println(studentService.addStudent(student));

    }

    @Test
    public void studentLoginTest() {
        System.out.println(studentService.studentLogin("jackson", "1234"));
    }

    @Test
    public void teacherTest(){
        System.out.println(studentService.addTeacher(new Teacher(null, "王老師", System.currentTimeMillis(), null), new int[]{1, 2, 7, 9, 15}));
    }
}

Service層

  • 接口
public interface StudentService {
    /**
     * 新增學生
     *
     * @param student 學生信息
     * @return 動作執行返回值
     */
    ServerResponse<Integer> addStudent(Student student);

    /**
     * 學生登錄
     * @param name 姓名
     * @param pass 密碼
     * @return 是否成功
     */
    ServerResponse<Student> studentLogin(String name, String pass);

    /**
     * 新增老師信息,同時關聯學生
     * @param teacher 老師信息
     * @param sids 要關聯的學生id
     * @return 操作執行結果碼
     */
    ServerResponse<Integer> addTeacher(Teacher teacher,int[] sids);
}
  • 實現類
public class StudentServiceImpl implements StudentService {
    StudentDao studentDao = new StudentDaoImpl();

    @Override
    public ServerResponse<Integer> addStudent(Student student) {
        Objects.requireNonNull(student);
        // 密碼加密
        student.setStu_pass(MD5Util.md5(student.getStu_pass()));
        //頭像上傳
        student.setStu_image(uploadImg(student.getStu_image()));

        int result = studentDao.addStudent(student);
        if (result <= 0) {
            return ServerResponse.error();
        }
        return ServerResponse.success(result);

    }

    /**
     * 學生登錄
     *
     * @param name 姓名
     * @param pass 密碼
     * @return 是否成功
     */
    @Override
    public ServerResponse<Student> studentLogin(String name, String pass) {
        Objects.requireNonNull(name);
        Objects.requireNonNull(pass);
        pass = MD5Util.md5(pass);
        Student student = studentDao.studentLogin(name, pass);
        if (student == null) {
            return ServerResponse.error();
        }
        return ServerResponse.success(student);
    }

    /**
     * 新增老師信息,同時關聯學生
     *
     * @param teacher 老師信息
     * @param sids    要關聯的學生id
     * @return 操作執行結果碼
     */
    @Override
    public ServerResponse<Integer> addTeacher(Teacher teacher, int[] sids) {
        Objects.requireNonNull(teacher);
        Objects.requireNonNull(sids);
        int result = studentDao.addTeacher(teacher, sids);
        if (result <= 0) return ServerResponse.error();
        return ServerResponse.success(result);
    }

    private String uploadImg(String sourceFile) {
        if (sourceFile == null || sourceFile.equals("")) {
            throw new NullPointerException("文件路徑不能爲空");
        }
        File srcFile = new File(sourceFile);
        StringBuilder targetFilePath = new StringBuilder(StudentConsts.UPLOAD_PATH);
        targetFilePath.append(LocalDate.now().toString());
        File targetFile = new File(targetFilePath.toString());
        if (!targetFile.exists()) {
            targetFile.mkdirs();
        }
        targetFilePath.append("\\");
        targetFilePath.append(UUID.randomUUID() + "_" + srcFile.getName());
        try (
                BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(srcFile));
                BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(targetFilePath.toString()));
        ) {
            int len = 0;
            byte[] by = new byte[1024];
            while ((len = inputStream.read(by)) != -1) {
                outputStream.write(by, 0, len);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return targetFilePath.toString();
    }
}

Dao層

  • 接口
public interface StudentDao {

    /**
     * 新增學生信息
     * @param student 學生信息
     * @return 受影響的行數
     */
    int addStudent(Student student);

    /**
     * 登錄功能
     * @param name 姓名
     * @param pass 密碼
     * @return 學生信息返回值
     */
    Student studentLogin(String name,String pass);

    /**
     * 新增老師,同時關聯學生
     * @param teacher 老師信息
     * @param sids 學生id
     * @return 操作受影響行數
     */
    int addTeacher(Teacher teacher, int[] sids);
}
  • 實現類
public class StudentDaoImpl implements StudentDao {
    private Connection connection;
    private PreparedStatement ps;
    private ResultSet rs;

    @Override
    public int addStudent(Student student) {
        connection = DBHelper.getConnection(true);
        try {
            ps = connection.prepareStatement(StudentSql.STUDENT_INSERT);
            ps.setString(1, student.getStu_name());
            ps.setString(2, student.getStu_pass());
            ps.setString(3, student.getStu_image());
            ps.setString(4, student.getStu_sex());
            ps.setInt(5, student.getStu_age());
            ps.setString(6, student.getStu_address());
            ps.setString(7, student.getStu_phone());
            ps.setLong(8, student.getStu_createTime());
            return ps.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBHelper.closeConnection(connection, ps, null);
        }

        return 0;
    }

    /**
     * 登錄功能
     *
     * @param name 姓名
     * @param pass 密碼
     * @return 學生信息返回值
     */
    @Override
    public Student studentLogin(String name, String pass) {
        Student student = null;
        connection = DBHelper.getConnection(true);
        try {
            ps = connection.prepareStatement(StudentSql.STUDENT_LOGIN);
            ps.setString(1, name);
            ps.setString(2, pass);
            rs = ps.executeQuery();
            while (rs.next()) {
                student = new Student(rs);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBHelper.closeConnection(connection, ps, rs);
        }
        return student;
    }

    /**
     * 新增老師,同時關聯學生
     *
     * @param teacher 老師信息
     * @param sids    學生id
     * @return 操作受影響行數
     */
    @Override
    public int addTeacher(Teacher teacher, int[] sids) {
        // 開啓手動提交事務
        connection = DBHelper.getConnection(false);
        int result = 0;
        try {
            ps = connection.prepareStatement(StudentSql.TEACHER_INSERT, Statement.RETURN_GENERATED_KEYS); // 返回自增id的值
            ps.setString(1, teacher.getTName());
            ps.setLong(2, teacher.getCreateTime());
            ps.executeUpdate(); // 執行新增老師sql
            // 獲得自增的id  select last_insert_id()  rs  JDBC已經封裝了這個自增id
            rs = ps.getGeneratedKeys();// Long類型的數值
            long teacherId = 0;
            if (rs.next()) {
                teacherId = rs.getLong(1); // 參數爲第幾列
            }
            // 執行第二條sql
            ps = connection.prepareStatement(StudentSql.TEACHER_STUDENT_INSERT);
            for (int sid : sids) {
                ps.setInt(1, (int) teacherId);
                ps.setInt(2, sid);
                ps.executeUpdate();
                result++;
            }

            // 提交事務
            connection.commit();

        } catch (SQLException e) {
            e.printStackTrace();
            // 數據回滾
            try {
                connection.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        } finally {
            DBHelper.closeConnection(connection, ps, rs);
        }
        return result;
    }
}

工具類

  • DBHelper
public class DBHelper {
    private DBHelper() {
    }

    private static String url;
    private static String name;
    private static String pass;
    //ThreadLocal<T> 對每個線程都創建一個唯一的不可變的參數化類型的副本(對象)
    private static final ThreadLocal<Connection> CONNECTION_THREAD_LOCAL = new ThreadLocal<>();

    static {
        Properties properties = new Properties();
        try {
            properties.load(DBHelper.class.getClassLoader().getResourceAsStream("jdbc.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        url = properties.getProperty("jdbc.url");
        name = properties.getProperty("jdbc.name");
        pass = properties.getProperty("jdbc.pass");
        // 加載驅動
        try {
            Class.forName(properties.getProperty("jdbc.driver"));
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }


    public static Connection getConnection(boolean flag) {
        Connection connection = CONNECTION_THREAD_LOCAL.get();
        //獲取連接
        try {
            if (connection == null || connection.isClosed()) {
                connection = DriverManager.getConnection(url, name, pass);
                // 設置自動提交
                connection.setAutoCommit(flag);
                CONNECTION_THREAD_LOCAL.set(connection);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return connection;
    }

    public static void closeConnection(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet) {
        try {
            if (resultSet != null) resultSet.close();
            if (preparedStatement != null) preparedStatement.close();
            if (connection != null) {
                connection.close();
                CONNECTION_THREAD_LOCAL.remove();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
  • MD5Util
public class MD5Util {
    private MD5Util(){}
    public static String md5(String sourcePass){
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("md5");
            messageDigest.update(sourcePass.getBytes());
            byte[] digest = messageDigest.digest();
            return new BigInteger(1,digest).toString(16);

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }
}
  • CodeEnum
public enum CodeEnum {
    SUCCESS("success",200),
    ERROR("error",500);

    private String msg;
    private Integer code;

    CodeEnum(String msg, Integer code) {
        this.msg = msg;
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public Integer getCode() {
        return code;
    }
}
  • ServerResponse
public class ServerResponse<T> {
    private ServerResponse() {
    }

    private String msg;
    private Integer code;
    private T data;

    public ServerResponse(String msg, Integer code) {
        this.msg = msg;
        this.code = code;
    }

    // 返回成功的結果
    public static <T> ServerResponse success() {
        return new ServerResponse(CodeEnum.SUCCESS.getMsg(),CodeEnum.SUCCESS.getCode());
    }
    public static <T> ServerResponse success(T data){
        return new ServerResponse(CodeEnum.SUCCESS.getMsg(),CodeEnum.SUCCESS.getCode(),data);
    }

    // 返回失敗的結果
    public static <T> ServerResponse error(){
        return new ServerResponse(CodeEnum.ERROR.getMsg(),CodeEnum.ERROR.getCode());
    }
}

實體類

  • Student
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student implements Serializable {
    private Integer id;
    @NonNull
    private String stu_name;
    private String stu_pass;
    private String stu_image;
    private String stu_sex;
    private Integer stu_age;
    private String stu_address;
    private String stu_phone;
    private Long stu_createTime;
    private Long stu_updateTime;

    public Student(ResultSet rs) throws SQLException {
        this.setId(rs.getInt("id"));
        this.setStu_name(rs.getString("stu_name"));
        this.setStu_pass(rs.getString("stu_pass"));
        this.setStu_image(rs.getString("stu_image"));
        this.setStu_sex(rs.getString("stu_sex"));
        this.setStu_age(rs.getInt("stu_age"));
        this.setStu_address(rs.getString("stu_address"));
        this.setStu_phone(rs.getString("stu_phone"));
    }
}
  • Teacher
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Teacher implements Serializable {
    private Integer id;
    private String tName;
    private Long createTime;
    private Long updateTime;

}

常量類

  • StudentConsts
public class StudentConsts {
    public static final String UPLOAD_PATH = "upload\\student\\";
}
  • StudentSql
public interface StudentSql {
    String STUDENT_INSERT = "INSERT INTO student (stu_name,stu_pass,stu_image,stu_sex,stu_age,stu_address,stu_phone,stu_createTime) values (?,?,?,?,?,?,?,?)";
    String STUDENT_LOGIN = "select * from student where stu_name = ? and stu_pass = ?";

    String TEACHER_INSERT = "insert into teacher(tname,createtime) values (?,?)";
    String TEACHER_STUDENT_INSERT="insert into tb_teacher_student(tid,sid) values (?,?)";

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章