JavaWeb's Dao rapid development memory notes

1. Dao specification

As the background of Java, we allow to connect to each database and perform CURD operations on it, but different database manufacturers have their own set of operating rules. In order to unify the rules, Java has designed a set of interface specifications, and its package is located in java. sql.*;

2. Design the operation process of CURD

The Dao design of JavaWeb is that each operation needs to run according to certain rules, and its order is nothing more than:

1. Load the driver
2. Get the connection
3. Create the Statement statement
4. Execute the SQL statement
5. Release the resources

3. Simple create database table operation.

The main code is listed below, which strictly follows the above process. Note that this article is only for personal review and does not have a very specific explanation:

PreparedStatement ps = null;
    Connection conn = null;
    try {
        String sql = "CREATE TABLE t_student(id bigint primary key auto_increment,name varchar(20),age int(20))";
        conn = DruidUtil.getConn();
        ps = conn.prepareStatement(sql);
        ps.executeUpdate();
        ps.close();
        conn.close();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        DruidUtil.close(null,ps, conn);
    }

4. The following describes the designed architecture:

4.1 Create the class design corresponding to the database table

public class Student {

    private long id;
    private String name;
    private int age;

    //setter/getter...

    @Override
    public String toString() {
        //...       
    }

}

4.2 Create a canonical interface for Dao components

public interface IStudentDao {

    /**
     * 保存一个用户
     * @param student
     */
    void save(Student student);

    /**
     *  更新一个用户
     */
    void update(long id,Student student);

    /**
     * 删除一个用户
     */
    void delete(long id);

    /**
     * 根据id查询一个用户
     */
    Student getStudent(long id);

    /**
     * 查询所有用户
     */
    List<Student> getAllStudents();

}

4.3 Create a test class corresponding to the Dao component interface

write picture description here

write picture description here

write picture description here

public class StudentDaoTest {

    private IStudentDao studentDao=new StudentDaoImpl();

    @Test
    public void testSave() {
        Student student=new Student();
        student.setName("张三");
        student.setAge(22);
        studentDao.save(student);
    }

    @Test
    public void testUpdate() {
        Student student=new Student();
        student.setName("zhangsan");
        student.setAge(20);
        studentDao.update(3L, student);
    }

    @Test
    public void testDelete() {
        studentDao.delete(2L);
    }

    @Test
    public void testGetStudent() {
        Student student = studentDao.getStudent(4L);
        System.out.println(student);
    }

    @Test
    public void testGetAllStudents() {
        List<Student> students = studentDao.getAllStudents();
        for (Student student : students) {
            System.out.println(student);
        }
    }

}

4.4 Create Dao component implementation class

For the following code, you can pay attention to the addition, deletion and modification code first, and ignore the query for the time being:

public class StudentDaoImpl implements IStudentDao{

    @Override
    public void save(Student student) {
        String sql="INSERT INTO t_student(name,age) VALUES(?,?)";
        JdbcTemplate.update(sql, new Object[] {student.getName(),student.getAge()});
    }

    @Override
    public void update(long id, Student student) {
        String sql="UPDATE t_student set name=?,age=? WHERE id=?";
        JdbcTemplate.update(sql, new Object[] {student.getName(),student.getAge(), id});
    }

    @Override
    public void delete(long id) {
        String sql="DELETE FROM t_student WHERE id=?";
        JdbcTemplate.update(sql, new Object[] {id});
    }

    @Override
    public Student getStudent(long id) {
        String sql="SELECT * FROM t_student WHERE id=?";
        return JdbcTemplate.query(sql,
                new BeanResultHandler<>(Student.class),
                new Object[] {id});
    }

    @Override
    public List<Student> getAllStudents() {
        String sql="SELECT * FROM t_student";
        return JdbcTemplate.query(sql,
                new BeanListResultHandler<>(Student.class));
    }

}

4.5 Extract the same part of the code into the Util package & Template class

In the code added, deleted and modified above, the process is basically the same, so we extract it into the template class JdbcTemplate. You can pay attention to its update method:

public class JdbcTemplate {

    public static void update(String sql,Object... params) {
        Connection conn=null;
        PreparedStatement ps=null;
        try {
            conn=DruidUtil.getConn();
            ps=conn.prepareStatement(sql);
            for (int i = 0; i < params.length; i++) {
                ps.setObject(i+1, params[i]);
            }
            ps.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            DruidUtil.close(null, ps, conn);
        }
    }

}

In it, the code blocks for acquiring connections and releasing resources are extracted once again:

public class DruidUtil {

    private static final String driverClassname = "com.mysql.jdbc.Driver";
    private static final String url = "jdbc:mysql:///jdbcdemo?characterEncoding=UTF-8";
    private static final String user = "root";
    private static final String password = "admin";
    private static DataSource datasource;

    static {
        try {
            Properties properties = new Properties();
            InputStream is = Thread.currentThread()
                    .getContextClassLoader().getResourceAsStream("druid.properties");
            properties.load(is);
            datasource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Connection getConn() {
        try {
            return datasource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void close(ResultSet rs, Statement ps, Connection conn) {
        try {
            if (rs != null) {
                rs.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (ps != null) {
                    ps.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (conn != null) {
                        conn.close();
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

For the database connection here, we take mysql-connector-java-5.1.40-bin.jar [mysql driver package] + druid-1.0.15.jar [Druid's Alibaba development package], configuration file druid.properties as follows:

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///jdbcdemo
username=root
password=admin

4.6 Deep encapsulation of the result set again

After the query result, we get the ResultSet object, but more, the data result we want to get should be an object/queue.

The query method of StudentDaoImpl first designs a query template [whether it is an object or a queue], the code is as follows:

public class JdbcTemplate {

    public static <T> T query(String sql,IResultSetHandler<T> handler,Object... params) {
        Connection conn=null;
        PreparedStatement ps=null;
        ResultSet rs=null;
        try {
            conn=DruidUtil.getConn();
            ps=conn.prepareStatement(sql);
            for (int i = 0; i < params.length; i++) {
                ps.setObject(i+1, params[i]);
            }
            rs=ps.executeQuery();
            return handler.handle(rs);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            DruidUtil.close(rs, ps, conn);
        }
        return null;
    }

}

In the above template, whether to convert the ResultSet to an object or a queue finally depends on the parameter IResultSetHandler handler stored at that time.

public interface IResultSetHandler<T> {

    T handle(ResultSet rs) throws Exception;

}

Come back and see how the client calling him writes:

write picture description here

Through the code, we found that the client uses a specific implementation subclass BeanResultHandler, whose role is to convert the ResultSet into an object:

write picture description here

For converting ResultSet to queue, the code is as follows:

write picture description here

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325985845&siteId=291194637