Java Development-DAO Design Patterns and Optimizations

Keywords: SQL Java Database JDBC

What is DAO?

DAO is Data Access Object Data Access Interface, as its name implies: dealing with the database. Sandwiched between business logic and data resources.

What are the DAO models?

The DAO pattern is actually a combination of two patterns: the Data Accessor pattern and the Active Domain Object pattern.

Their significance and role

Data Accessor mode achieves the separation of data access and business logic, and Active Domain Object mode achieves the object encapsulation of business data.
Take the database in Java Web as an example:
First, prepare a tool class DBUtils.class in advance.

public class DBUtils {
    public final static String URL="jdbc:mysql://localhost:3306/mydb";
    public final static String USERNAME="root";//User name
    public final static String  PASSWORD="*****";//Password
    public final static String DRIVER="com.mysql.jdbc.Driver";
    private DBUtils(){
    }
    //Using static fast loading driver
    static{
        try {
            Class.forName(DRIVER);
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    //Define a method for obtaining database connections
    public static Connection getconnection() {
        Connection connection=null;
        try {
        connection=DriverManager.getConnection(URL, USERNAME, PASSWORD);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            System.out.println("Failure to obtain connection");
        }
        return connection;

    }
    public static void close(ResultSet rs,Statement statement,Connection conn){
         if (rs!=null)
                try {
                    rs.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            if (statement!=null) {
                try {
                    statement.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }   
            }
            if (conn!=null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            }}      

Next we're going to implement the Dao model

A typical DAO pattern has the following components: an interface, a data transfer object, or a domain model.
First, we build a class of person.class data model class.

public class Person {
    private int id;
    private String name;
    private int age;
    private String description;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public Person( String name, int age, String description) {
        super();
        this.name = name;
        this.age = age;
        this.description = description;
    }
    public Person() {
        super();
        // TODO Auto-generated constructor stub
    }
    @Override
    public String toString() {
        return "person [id=" + id + ", name=" + name + ", age=" + age + ", description=" + description + "]";
    }

Declare an interface, data operation class PersonDao.class

import java.sql.SQLException;
import java.util.List;
import com.vince.domain.Person;
public interface PersonDao {
public void add(Person p) throws SQLException;//Exceptions need to be thrown here; otherwise errors will be reported in the following operations!!!
public void update(Person p) throws SQLException;
public void delete(int id) throws SQLException;
public Person findById(int id) throws SQLException;
public List<Person> findAll() throws SQLException;
}

Implementing class PersonDanImpl.class for writing interfaces

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.util.db.DBUtils;
import com.util.db.JdbcTemplete;
import com.vince.base.ResultSetHandler;
import com.vince.dao.PersonDao;
import com.vince.domain.Person;

public class PersonDaoImpl implements PersonDao {
private JdbcTemplete jdbcTemolete;
    public PersonDaoImpl() {
        jdbcTemolete=new JdbcTemplete();
}
    @Override
    public void add(Person p) throws SQLException {
        Connection connection=null;
        PreparedStatement ps=null;
        String sql="insert into person(name,age,description)values(?,?,?)";
        try {
        connection=DBUtils.getconnection();
        ps=connection.prepareStatement(sql);
        ps.setString(1, p.getName());
        ps.setInt(2, p.getAge());
        ps.setString(3, p.getDescription());
        ps.executeUpdate();
    } catch (SQLException e) {

        throw new SQLException("Database addition exception");
    }finally {
        DBUtils.close(null, ps, connection);
    }

        }
@Override
    public void update(Person p) throws SQLException {
    Connection connection=null;
        PreparedStatement ps=null;
        String sql="update person set name=?,age=?,description=? where id=?";
        try {
        connection=DBUtils.getconnection();
        ps=connection.prepareStatement(sql);
        ps.setString(1, p.getName());
        ps.setInt(2, p.getAge());
        ps.setString(3, p.getDescription());
        ps.setInt(4, p.getId());
        ps.executeUpdate(); 
    } catch (SQLException e) {
            throw new SQLException("Database update exception");
    }finally {
        DBUtils.close(null, ps, connection);
    }   
    }
    @Override
    public void delete(int id) throws SQLException {
        Connection connection=null;
        PreparedStatement ps=null;
        String sql="delete from person where id=?";
        try {
        connection=DBUtils.getconnection();
        ps.setInt(1,id);
        ps.executeUpdate();

    } catch (SQLException e) {
        e.printStackTrace();
        throw new SQLException("Database deletion exception");
    }finally {
        DBUtils.close(null, ps, connection);
    }
    }

@Override
    public List<Person> findAll() throws SQLException {
         Connection connection=null;
           PreparedStatement ps=null;
           ResultSet rs=null;
           Person p=null;
           List<Person> persons=new ArrayList<Person>();
            String sql="selectid,name,age,description from person";
            try {
                connection=DBUtils.getconnection();
                ps=connection.prepareStatement(sql);
                rs=ps.executeQuery();
                while(rs.next()){
                    p=new Person();
                    p.setId(rs.getInt(1));
                    p.setName(rs.getString(2));
                    p.setAge(rs.getInt(3));
                    p.setDescription(rs.getString(4));
                    persons.add(p);
                    }
                } catch (SQLException e) {
                // TODO: handle exception
                throw new SQLException("Query all data exceptions");
            }finally {
                DBUtils.close(rs, ps, connection);
            }
            return persons; }
}

The above is the implementation process of DAO pattern. This DAO design pattern mainly enables us to write code that is more concise and less redundant, and implements a rule in software design pattern: high cohesion, low coupling; what about the following? Let's consider whether we can continue to optimize the implementation of DAO design patterns.

Create a new class. JdbcTemplete .class Let's make another abstraction.
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.vince.base.ResultSetHandler;
public class JdbcTemplete {
public int update(String sql,Object ...args){
Connection connection=null;
PreparedStatement ps=null;
try {
connection=DBUtils.getconnection();
ps=connection.prepareStatement(sql);
if (args!=null) {
for(int i=0;i<args.length;i++){
ps.setObject(i+1, args[i]);
}
}
return ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
return 0;
}finally {
DBUtils.close(null, ps, connection);
}
}
public Object query(String sql,ResultSetHandler handler,Object...args){
Connection connection=null;
PreparedStatement ps=null;
ResultSet rs=null;
try {
connection=DBUtils.getconnection();
connection.prepareStatement(sql);
if (args!=null) {
for(int i=0;i<args.length;i++){
ps.setObject(i+1, args[i]);
}
}
rs=ps.executeQuery();
return handler.doHandler(rs);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}

//The parent class of all classes is Objects with multiple parameters, so we use Object... args;
//Next, in the PersonDaoImpl.class class class, we can use the abstract class we are extracting. ~Is the code much simpler?~Similar methods can be used for adding, deleting and updating the database?

@Override
    public void add(Person p) throws SQLException {
        String sql="insert into person(name,age,description)values(?,?,?)";
        jdbcTemolete.update(sql, p.getName(),p.getDescription());   
    }

For an operation that needs to be queried from a database, you need to use the ResultSet method for the operation of the query.
We define an interface ResultSetHandler.class here.

import java.sql.ResultSet;
import java.sql.SQLException;

public interface ResultSetHandler {
    public Object doHandler(ResultSet rs)throws SQLException;
}

** This interface is needed in the query method in JdbcTemplete.class
With this query method in PersonDaoImpl.class, we can write **

@Override
    public Person findById(final int id) throws SQLException {

        String sql="select name,age,description from person where id=?";
      return  (Person) jdbcTemolete.query(sql, new ResultSetHandler() {

        @Override
        public Object doHandler(ResultSet rs)throws SQLException {
             Person p=null;
                if(rs.next()){
                    p=new Person();
                    p.setId(id);
                    p.setName(rs.getString(1));
                    p.setAge(rs.getInt(2));
                    p.setDescription(rs.getString(3));                                    }
            return p;
        }
    },id);
    }

Finally, we'll get a main method to use the method we defined for data manipulation.

What mistakes need to be corrected? Welcome to point out that we should learn together.
What mistakes need to be corrected? Welcome to point out that we should learn together.

Posted by sawade on Fri, 22 Mar 2019 06:54:53 -0700