Java入门11(JDBC)

JDBC


驱动加载 => 连接创建 => 创建编译 / 预编译语句 => 获取结果集 => 遍历结果集 => 返回结果集

接口
Driver 驱动
Connection 连接
Statement 操作
ResultSet 结果集
  1. 具体的实现不需要由Java的公司自己提供

  2. 所有开发者使用JDBC的规范都被统一定义

连接数据库(mysql)

统一资源定位符URL:jdbc:mysql:// + ip地址 + 端口 + 访问的数据库 + 请求参数(配置信息)

mysql驱动类的完整路径:com.mysql.jdbc.Driver

public class DBUtil {
    // 定义用户名
    private static final String USER_NAME = "root";
    // 定义密码
    private static final String PASSWORD = "123456";
    // URL--统一资源定位符
    // jdbc:mysql:// + ip地址 + 端口 + 访问的数据库 + 请求参数(配置信息)
    private static final String URL = "jdbc:mysql://localhost:3306/iWeb?characterEncoding=utf8";

    // 加载驱动(静态代码块)
    static {
        // mysql驱动类的完整路径
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            System.out.println("驱动加载失败!");
        }
    }

    // 定义一个获取数据库连接的方法
    public static Connection getConnection(){
        try {
            return DriverManager.getConnection(URL,USER_NAME,PASSWORD);
        } catch (SQLException e) {
            System.out.println("连接获取失败!");
            return null;
        }
    }
}
// 连接测试
public static void main(String[] args) {
    // 定义sql语句
    String sql = "insert into student(name) values('robot03')";
    // try-with 代码块,在try后额外提供一个括号,括号里面的资源在try-catch结束后自动释放
    // 只有实现了AutoCloseable接口的类,才支持使用try-with自动关闭

    // 获取数据库连接 + 生成statement编译语句
    try(Connection connection = DBUtil.getConnection();
        Statement statement = connection.createStatement()) {
        // 执行语句
        statement.execute(sql);
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

代码封装(DAO)& CRUD

​ DAO层:负责提供JDBC支持,提供对应的DAO接口和实现类

​ ORM(object relation model):对象应用模型,对数据库对象的映射

// 测试表对应的JavaBean
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private long id;
    private String name;
    private String gender;
    private String address;
    private long phone;
}

增(insert)

// 增(insert)
public void insert(Student student) {
    // 空值判断
    if(student == null || student.getName() == null || "".equals(student.getName())){
        System.out.println("参数有误!");
        return;
    }
    String sql = "insert into student(NAME,GENDER,ADDRESS,PHONE) values(?,?,?,?)";
    try(Connection connection = DBUtil.getConnection();
        PreparedStatement preparedStatement = connection.prepareStatement(sql)){
        // 添加参数
        preparedStatement.setString(1,student.getName());
        preparedStatement.setString(2,student.getGender());
        preparedStatement.setString(3,student.getAddress());
        preparedStatement.setInt(4,student.getPhone());
        // 执行语句
        preparedStatement.execute();
    }catch(SQLException e){
        e.printStackTrace();
    }
}

删(delete)

// 删(delete)
public void delete(Student student) {
    String sql = "delete from student where 1=1";
    if(student == null){
        System.out.println("参数有误!");
        return;
    }
    if(student.getId() > 0 && (student.getName() == null || "".equals(student.getName()))){
        // 使用 PreparedStatement 进行参数传递,只需要将 sql 中的参数标记为 ? 即可
        sql = sql +" and id = ?";
        // 使用预编译对象的时候,在创建对象时就需要传入sql
        try(Connection connection = DBUtil.getConnection();
            PreparedStatement preparedStatement = connection.prepareStatement(sql)){
            // 数字代表参数序号
            preparedStatement.setInt(1, student.getId());
            // 执行sql语句
            preparedStatement.execute();
        }catch(SQLException e){
            e.printStackTrace();
        }
    } else if (student.getId() <= 0 && student.getName() != null && (!"".equals(student.getName()))) {
        sql = sql +" and NAME = ?";
        try(Connection connection = DBUtil.getConnection();
            PreparedStatement preparedStatement = connection.prepareStatement(sql)){
            // 数字代表参数序号
            preparedStatement.setString(1, student.getName());
            // 执行sql语句
            preparedStatement.execute();
        }catch(SQLException e){
            e.printStackTrace();
        }
    }else {
        System.out.println("参数有误!");
    }
}

改(update)

public void update(Student student) {
    String sql = "update student set name = ? where id = ?";
    // 空值判断
    if(student == null || student.getName() == null || "".equals(student.getName())){
        System.out.println("参数有误!");
        return;
    }
    try(Connection connection = DBUtil.getConnection();
        PreparedStatement preparedStatement = connection.prepareStatement(sql)){
        // 传参
        preparedStatement.setString(1,student.getName());
        preparedStatement.setInt(2,student.getId());
        // 执行sql语句
        preparedStatement.execute();
    }catch(SQLException e){
        e.printStackTrace();
    }
}

查(select)

// 普通查询
public Collection<Student> listByPage(int start, int count) {
    List<Student> result = new ArrayList<>();
    String sql = "select * from student limit ?,?";
    try(Connection connection = DBUtil.getConnection();
        PreparedStatement preparedStatement = connection.prepareStatement(sql)){
        // 传参
        preparedStatement.setInt(1,start);
        preparedStatement.setInt(2,count);
        // 执行查询语句的时候,需要使用 ResultSet 接收结果
        ResultSet resultSet = preparedStatement.executeQuery();
        while(resultSet.next()){
            result.add(new Student(resultSet.getInt("id"),resultSet.getString("name"), resultSet.getString("gender"),resultSet.getString("address"),resultSet.getInt("phone")));
        }
    }catch(SQLException e){
        e.printStackTrace();
    }
    if(result.size() == 0){
        return null;
    }else{
        return result;
    }
}

// 模糊查询(字符串拼接)
public Collection<Student> listWithNameLike(String key) {
    List<Student> result = new ArrayList<>();
    String sql = "select * from student where name like ?";
    try(Connection connection = DBUtil.getConnection();
        PreparedStatement preparedStatement = connection.prepareStatement(sql)){
        // 传参
        preparedStatement.setString(1,"%" + key + "%");
        // 接收结果
        ResultSet resultSet = preparedStatement.executeQuery();
        while(resultSet.next()){
            result.add(new Student(resultSet.getInt("id"),resultSet.getString("name"), resultSet.getString("gender"),resultSet.getString("address"),resultSet.getInt("phone")));
        }
    }catch(SQLException e){
        e.printStackTrace();
    }
    if(result.size() == 0){
        return null;
    }else{
        return result;
    }
}

preparedStatement 🌞 和 statement 💩的区别:

  1. 参数传递的区别,preparedStatement 更加方便,可读性更强
  2. 性能差异,statement 先传参再编译(每次执行语句都需要进行一次编译),preparedStatement 先编译后传参(相同的语句只需要编译一次),相比较 preparedStatement 性能更好👍
  3. 🔒安全问题,statement 存在 sql 注入!!!!

Junit 单元测试

public class TestStudentDAO {
    private StudentDAO studentDAO;
    @Before
    // 被该注解修饰的方法会在所有@Test修饰的方法执行之前执行,一般用于资源加载
    public void init(){
        studentDAO = new StudentDAOImpl();
        System.out.println("假装资源被初始化。。。");
    }

    @After
    // 被该注解修饰的方法会在所有@Test修饰的方法执行之后执行,一般用于资源释放
    public void destroy(){
        System.out.println("假装资源被销毁。。。");
    }

    @Test
    public void test(){
        Collection<Student> students = studentDAO.listAll();
        // 断言类
        // 判断是否不为空
        Assert.assertFalse(students.isEmpty());
        // 判断大小是否和预期值一样
        Assert.assertEquals(3,students.size());
    }
}

热门相关:恭喜你被逮捕了   戏精老公今天作死没   神算大小姐   戏精老公今天作死没   修真界败类