Java Code Refactoring

Source: Internet
Author: User

Usually we write code that satisfies the requirements but is often not conducive to project development and maintenance, with the following JDBC code as an example

<span style= "FONT-SIZE:18PX;" >//Add student information @overridepublic void Save (Student stu) {String sql = "INSERT into T_student (name,age) VALUES (?,?)"; Connection conn = null; Statement st = null;try {///1. Load Registered driver Class.forName ("Com.mysql.jdbc.Driver");//2. Get database Connection conn = Drivermanager.getconnection ("Jdbc:mysql:///jdbcdemo", "root", "root");//3. Create Statement Object PreparedStatement PS = conn.preparestatement (sql);p s.setobject (1, Stu.getname ());p S.setobject (2, Stu.getage () );//4. Execute SQL statement ps.executeupdate ();//5. Release resource} catch (Exception e) {e.printstacktrace ();} finally {try {if (st! = NULL) St.close ();} catch (SQLException e) {E.print StackTrace ();} Finally {try {if (conn! = null) Conn.close ();} catch (SQLException e) {e.printstacktrace ()}}}} Delete Student information @overridepublic void Delete (Long ID) {String sql = "Delete from t_student WHERE id=?"; Connection conn = null; Statement st = null;try {///1. Load Registered driver Class.forName ("Com.mysql.jdbc.Driver");//2. Get database Connection conn = Drivermanager.getconnection ("Jdbc:mysql:///jdbcdemo", "root", "root");//3. Create Statement Object PreparedStatement PS = conn.preparestatement (sql);p S.setobject (1, id);//4. Execute SQL statement ps.executeupdate ();//5. Release resource} catch (Exception e) {e.printstacktrace ();} finally {try {if (st! = NULL) St.close ();} catch (SQLException e) {E.print StackTrace ();} Finally {try {if (conn! = null) Conn.close ();} catch (SQLException e) {e.printstacktrace ()}}}} Modify student Information @overridepublic void update (Student stu) {String sql = "Update t_student SET name=?,age=?" WHERE id=? "; Connection conn = null; Statement st = null;try {///1. Load Registered driver Class.forName ("Com.mysql.jdbc.Driver");//2. Get database Connection conn = Drivermanager.getconnection ("Jdbc:mysql:///jdbcdemo", "root", "root");//3. Create Statement Object PreparedStatement PS = conn.preparestatement (sql);p s.setobject (1, Stu.getname ());p S.setobject (2, Stu.getage () );p S.setobject (3, Stu.getid ());//4. Execute SQL statement ps.executeupdate ();//5. Release resource} catch (Exception e) {e.printstacktrace ();} finally {try {if (st! = NULL) St.close ();} catch (SQLException e) {E.print StackTrace ();} finally {try {if (conn! = null) Conn.close ();} catch (SQLException e) {e.printstacktrace ();}}} </span>

The code above is not a problem, but the code repeats too much, so we can extract and put the duplicated code in a tool class JDBCUtil2

Tool class public class JDBCUtil2 {private JDBCUtil2 () {}static {///1. Load Registered driver try {class.forname ("Com.mysql.jdbc.Driver");} catch (Exception e) {//TODO auto-generated catch Blocke.printstacktrace ();}} public static Connection getconnection () {try {//2. Get the database connection return drivermanager.getconnection ("Jdbc:mysql:///jdbcdemo "," root "," root "); catch (Exception e) {e.printstacktrace ();} return null;} Release resource public static void Close (ResultSet rs, Statement St, Connection conn) {try {if (rs! = null) Rs.close ();} catch (Sqlex  Ception e) {e.printstacktrace ();} finally {try {if (st! = NULL) St.close ();} catch (SQLException e) {e.printstacktrace ();} Finally {try {if (conn! = null) Conn.close ()} catch (SQLException e) {e.printstacktrace ()}}}}
Calling the methods in the tool class directly in the implementation class
public class STUDENTDAOIMPL2 implements Istudentdao {//Add student information @overridepublic void Save (Student stu) {String sql = "INSERT Into T_student (name,age) VALUES (?,?) "; Connection conn = null; PreparedStatement ps=null;try {conn=jdbcutil2.getconnection ();//3. Create statement Object PS = conn.preparestatement (SQL); Ps.setobject (1, Stu.getname ());p S.setobject (2, Stu.getage ());//4. Execute SQL statement ps.executeupdate ();//5. Release resource} catch (Exception e) {e.printstacktrace ();} finally {jdbcutil2.close (NULL, PS, conn);}} Delete Student information @overridepublic void Delete (Long ID) {String sql = "Delete from t_student WHERE id=?"; Connection conn = null; PreparedStatement ps=null;try {conn=jdbcutil2.getconnection ();//3. Create statement Object PS = conn.preparestatement (SQL); Ps.setobject (1, id);//4. Execute SQL statement ps.executeupdate ();//5. Release resource} catch (Exception e) {e.printstacktrace ();} finally {jdbcutil2.close (NULL, PS, conn);}} Modify student Information @overridepublic void update (Student stu) {String sql = "Update t_student SET name=?,age=?" WHERE id=? "; Connection conn = null; PreparedsTatement ps=null;try {conn=jdbcutil2.getconnection ();//3. Create statement Object PS = conn.preparestatement (sql);p S.setobject (1, Stu.getname ());p S.setobject (2, Stu.getage ());p S.setobject (3, Stu.getid ());//4. Execute SQL statement ps.executeupdate ();//5. Release resource} catch (Exception e) {e.printstacktrace ();} finally {jdbcutil2.close (NULL, PS, conn);}} @Overridepublic Student get (Long ID) {String sql = "SELECT * from T_student WHERE id=?"; Connection conn = null; Statement st = null; ResultSet rs = null; PreparedStatement ps=null;try {conn=jdbcutil2.getconnection ();//3. Create statement Object PS = conn.preparestatement (SQL); Ps.setobject (1, id);//4. Execute SQL Statement rs = ps.executequery (), if (Rs.next ()) {String name = rs.getstring ("name"); int = Rs.getint ("Age"); Student stu = new Student (ID, name, age); return Stu;} 5. Release resource} catch (Exception e) {e.printstacktrace ();} finally {Jdbcutil2.close (RS, PS, conn);} return null;} @Overridepublic list<student> list () {list<student> list = new arraylist<> (); String sql = "SELECT * FROM T_studenT "; Connection conn = null; Statement st = null; ResultSet rs = null; PreparedStatement ps=null;try {conn=jdbcutil2.getconnection ();//3. Create statement Object PS = conn.preparestatement (SQL);//4. Execute SQL Statement rs = Ps.executequery (); while (Rs.next ()) {Long id = rs.getlong ("id"); String name = rs.getstring ("name"); int = Rs.getint ("Age"); Student stu = new Student (ID, name, age); List.add (Stu);} 5. Release resource} catch (Exception e) {e.printstacktrace ();} finally {Jdbcutil2.close (RS, PS, conn);} return list;}}
Although the duplicate code is completed extraction, but the database of account password directly displayed in the code, not conducive to subsequent account password changes maintenance, we can build a db.propertise file to store this information

Driverclassname =com.mysql.jdbc.driverurl =jdbc:mysql:///jdbcdemousername =rootpassword =root
Just get the information inside the tool class

private static Properties P;static {//1. Load Registration Drive try {ClassLoader loader = Thread.CurrentThread (). Getcontextclassloader () ; InputStream InputStream = Loader.getresourceasstream ("db.properties");p = new properties ();p. Load (InputStream); Class.forName (P.getproperty ("Driverclassname"));} catch (Exception e) {//TODO auto-generated catch Blocke.printstacktrace ();}} public static Connection getconnection () {try {//2. Get the database connection return drivermanager.getconnection (p.getproperty ("url"), P.getproperty ("username"), P.getproperty ("password"));} catch (Exception e) {e.printstacktrace ();} return null;}
Extraction here seems to have been completed, but in the implementation of the class, there are still some duplicate code, in the DML operation, in addition to SQL and set the value of the different, the other is the same, will be the same extracted, different parts passed through the parameters,cannot be placed directly in the tool class,At this point we can create a template class JdbcTemplate and create a DML and DQL template to refactor the code.

public class JdbcTemplate {private JdbcTemplate () {};//dml generic template public static void update (String sql, Object ... params) {Con Nection conn = null; PreparedStatement PS = null;try {conn = Jdbcutil2.getconnection ();p s = conn.preparestatement (sql);//Set value for (int i = 0; i < Params.length; i++) {Ps.setobject (i + 1, params[i]);} Ps.executeupdate ();} catch (Exception e) {e.printstacktrace ();} finally {jdbcutil.close (NULL, PS, conn);}} DQL agree template public static list<student> query (String sql,object...params) {list<student> list=new ArrayList <> (); Connection conn = null; PreparedStatement Ps=null; ResultSet rs = null;try {conn=jdbcutil.getconnection ();p s=conn.preparestatement (SQL);//Set value for (int i = 0; i < PARAMS.L Ength; i++) {ps.setobject (i+1, params[i]);} rs = Ps.executequery (); while (Rs.next ()) {Long id = rs.getlong ("id"); String name = rs.getstring ("name"); int = Rs.getint ("Age"); Student stu = new Student (ID, name, age); List.add (Stu);} 5. Release resource} catch (Exception e) {e.printstacktrAce ();} Finally {Jdbcutil.close (RS, PS, conn);} return list;}}
The implementation class calls the method directly.
Add student information @overridepublic void Save (Student stu) {String sql = "INSERT into T_student (name,age) VALUES (?,?)"; O Bject[] Params=new object[]{stu.getname (), Stu.getage ()}; Jdbctemplate.update (sql, params);} Delete Student information @overridepublic void Delete (Long ID) {String sql = "Delete from  t_student WHERE id=?"; Jdbctemplate.update (SQL, id);} Modify student Information @overridepublic void update (Student stu) {String sql = "Update t_student SET name=?,age=?" WHERE id=? "; O Bject[] Params=new object[]{stu.getname (), Stu.getage (), Stu.getid ()}; Jdbctemplate.update (sql, params);} @Overridepublic Student get (Long ID) {String sql = "SELECT * from T_student WHERE id=?"; list<student> list = Jdbctemplate.query (sql, id); return list.size () >0? List.get (0): null;} @Overridepublic list<student> List () {String sql = "SELECT * from T_student"; return jdbctemplate.query (SQL);}
This duplication of code basically solved, but another serious problem is that the program DQL operation can only handle the student class and T_student table related data, can not handle other classes such as: Teacher class and T_teacher table.different tables (different objects),Different tables should have different columns, the code for the different columns to handle the result set should not be the same, and the operation of the result set will onlyDAOI know best,In other words, the method of processing the results should not be placed in the template side, should be by eachDAOto handle it yourself. So we can create a iresultsethandle interface to handle the result set.

Public interface Iresultsethandle {//processing result set list handle (ResultSet Rs) throws Exception;}

The DQL template class calls the handle method in the Iresultsethandle interface, reminding the implementation class to implement the handle method on its own .

DQL agree template public static list<student> query (String sql,<span style= "color: #ff0000;" >iresultsethandle Rsh</span>, object...params) {list<student> list=new ArrayList<> (); Connection conn = null; PreparedStatement Ps=null; ResultSet rs = null;try {conn=jdbcutil.getconnection ();p s=conn.preparestatement (SQL);//Set value for (int i = 0; i < PARAMS.L Ength; i++) {ps.setobject (i+1, params[i]);} rs = Ps.executequery (); <span style= "color: #ff0000;" >return Rsh.handle (RS); </span>//5. Release resource} catch (Exception e) {e.printstacktrace ();} finally {Jdbcutil.close (RS, PS, conn);} return list;}


Implement the class yourself to achieveIresultsethandle interface of the handle method, want to deal with what type of data in the definition can

Well, the basic is done, but DQL query is not only to query student information (list type), you can also query the number of students, it will be through generics to complete
Declares a generic t as the return type, who calls Iresultsethandle, who decides T-type public interface Iresultsethandle<t> {//process result set T handle (ResultSet RS) Throws Exception;}

DQL agree template public static <T> T query (String sql,iresultsethandle<t> rsh, object...params) {Connection conn = Null PreparedStatement Ps=null; ResultSet rs = null;try {conn=jdbcutil.getconnection ();p s=conn.preparestatement (SQL);//Set value for (int i = 0; i < PARAMS.L Ength; i++) {ps.setobject (i+1, params[i]);} rs = Ps.executequery (); return Rsh.handle (RS);//5. Release resource} catch (Exception e) {e.printstacktrace ();} finally {Jdbcutil.close (RS, PS, conn);} return null;}

Class Studentresultsethandle implements Iresultsethandle<list<student>>{public list<student> Handle (ResultSet Rs) throws Exception {list<student> list=new arraylist<> (); while (Rs.next ()) {Long id = Rs.getlong ("id"); String name = rs.getstring ("name"); int = Rs.getint ("Age"); Student stu=new Student (ID, name, age); List.add (Stu);} return list;}

This can not only query the list, but also can query the number of students

Query student integer @testpublic void Testgettotal () throws Exception {Long totalcount = jdbctemplate.query ("Select COUNT (*) tatal FRO M t_student ", New Iresultsethandle<long> () {@Overridepublic long handle (ResultSet Rs) throws Exception {long Totalc Ount=null;if (Rs.next ()) {Totalcount=rs.getlong ("Tatal");} return totalcount;}}); System.out.println (totalcount);}
Well, refactoring has been done, and good code will make it easier for us to maintain it later, so it's important to learn to refactor the code.






Java Code Refactoring

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.