Level 1: specify the type of JDBC encapsulation
Task description
This task: encapsulate a JDBC tool class as required.
Relevant knowledge
In order to complete this task, you need to master the basic use of JDBC. Please refer to the previous training content Advanced features of Java - JDBC (Part 1).
This chapter will encapsulate JDBC for a table with known data structure.
Connect database
In the process of adding, deleting, modifying and querying, we are inseparable from the connection of the database, so we can encapsulate its operation into a method. The method does not need parameters and takes the connection object as the return value.
After completing the driver loading and database connection in the method, you can use:
private static Connection getConnection() { //1. Load drive //2. Connect to the database Connection conn=null; //Connection object return return conn; }
After encapsulation, we can directly use this method in addition, deletion, modification and query.
Close database connection
Similarly, each time we connect to the database, we need to release the corresponding resources. We also encapsulate it as a method. The method parameters are frequently used objects. These objects are usually ResultSet, Statement and Connection. Therefore, our method of closing the Connection is as follows:
public static void close(ResultSet rs,PreparedStatement ps,Connection conn){ try { if(rs!=null) rs.close(); if(ps!=null) ps.close(); if(conn!=null) conn.close(); } catch (SQLException e) { e.printStackT\frace(); } }
New data
Now we have a news table news in our database. The structure is as follows:
Field name | type | remarks | constraint |
---|---|---|---|
id | int | News number | Primary key |
title | varchar(60) | News headlines | nothing |
author_name | varchar(30) | Author name | nothing |
According to the table structure, we create a News object:
public class News { private int id; private String title; private String anthor_name; public News(int id, String title, String anthor_name) { super(); this.id = id; this.title = title; this.anthor_name = anthor_name; } public int getId() { return id; } public void setId(int id) { this.id = id; } ......//Omit the get and set methods of other properties }
In daily life, we see a lot of news every day, so we need to constantly add the latest news to the database. Let's encapsulate the new method:
Before encapsulation, we first conceive the method. The method needs to pass a News object without returning a value. Therefore, the definition and implementation idea of the method are as follows:
public void insert(News news) throws SQLException { Connection conn = getConnection();//Get the connection object PreparedStatement ps = null; //Write new sql statements String sql = ""; try{ ps = conn.prepareStatement(sql); //Through the incoming news object, the pre compiled? Assign value ps.setXXX(1,news.getXXX()); //Execute new sql statement ps.executeUpdate(); }catch(SQLException e){ e.printStackT\frace(); }finally{ //Close connection close(null, ps, conn); } }
Programming requirements
Supplement the code in the editor on the right to complete the database connection, deletion, update and search methods. The deletion method is to delete the news id passed in by the user.
Note: the connection database name is mysql_db, the database user is root, and the password is 123123.
Test description
The platform will test the code you write:
Test input: None
Expected output:
News [id=1, title = Yue Yunpeng's 18 years old, Jia Ling's 18 years old, Shen Teng's 18 years old, netizen: not to be funny? anthor_name = Guangming]
Note: two pieces of news data will be inserted into the news table in the test file to test the method you write. The data are as follows:
id | title | author_name |
---|---|---|
1 | Yue Yunpeng's 18 years old, Jia Ling's 18 years old, Shen Teng's 18 years old, netizen: aren't you here to be funny? | Xiao Ming |
2 | Assuming that the aircraft runs 1 light year per second, can it fly to the edge of the universe? Scientists say the answer | Explore the mysteries of the universe |
Start your mission and wish you success!
Implementation code
[JDBCUtils.java]
package step1; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import test.News; public class JDBCUtils { /** * Connect database */ private static Connection getConnection() { Connection conn = null; /********** Begin **********/ String url = "jdbc:mysql://localhost:3306/mysql_db"; try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection(url, "root", "123123"); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } /********** End **********/ return conn; } /** * Update data method * * @param news * @throws SQLException */ public void update(News news) throws SQLException { Connection conn = getConnection(); PreparedStatement ps = null; /********** Begin **********/ String sql = "update news set title = ? ,author_name = ? where id = ? "; try { ps = conn.prepareStatement(sql); ps.setObject(1, news.getTitle()); ps.setObject(2, news.getAuthor_name()); ps.setObject(3, news.getId()); ps.execute(); } catch (SQLException e) { e.printStackTrace(); throw new SQLException("Failed to update data"); } finally { close(null, ps, conn); } /********** End **********/ } /** * Query all data * * @return * @throws SQLException */ public List<News> findAll() throws SQLException { Connection conn = getConnection(); PreparedStatement ps = null; ResultSet rs = null; News news = null; List<News> newsList = new ArrayList<News>(); /********** Begin **********/ String sql = "select * from news"; try { ps = conn.prepareStatement(sql); rs = ps.executeQuery(); while (rs.next()) { news = new News(rs.getInt(1), rs.getString(2), rs.getString(3)); newsList.add(news); } } catch (SQLException e) { e.printStackTrace(); throw new SQLException("Failed to query all data"); } finally { close(rs, ps, conn); } /********** End **********/ return newsList; } /** * Delete method * * @param id * @throws SQLException */ public void delete(int id) throws SQLException { Connection conn = getConnection(); PreparedStatement ps = null; /********** Begin **********/ String sql = "delete from news where id=?"; try { ps = conn.prepareStatement(sql); ps.setObject(1, id); ps.execute(); } catch (SQLException e) { e.printStackTrace(); throw new SQLException(" Failed to delete data"); } finally { close(null, ps, conn); } /********** End **********/ } /** * add object * * @param news * @throws SQLException */ public void insert(News news) throws SQLException { Connection conn = getConnection(); PreparedStatement ps = null; String sql = "insert into news(id,title,author_name)values(?,?,?)"; try { ps = conn.prepareStatement(sql); ps.setInt(1, news.getId()); ps.setString(2, news.getTitle()); ps.setString(3, news.getAuthor_name()); ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); throw new SQLException("Failed to add data"); } finally { close(null, ps, conn); } } /** * Query object by id * * @param id * @return * @throws SQLException */ public News findById(int id) throws SQLException { Connection conn = getConnection(); PreparedStatement ps = null; ResultSet rs = null; News news = null; String sql = "select * from news where id=?"; try { ps = conn.prepareStatement(sql); ps.setInt(1, id); rs = ps.executeQuery(); if (rs.next()) { news = new News(); news.setId(id); news.setTitle(rs.getString(2)); news.setAuthor_name(rs.getString(3)); } } catch (SQLException e) { e.printStackTrace(); throw new SQLException("according to ID Failed to query data"); } finally { close(rs, ps, conn); } return news; } /** * Close database connection * * @param rs * @param ps * @param conn */ public static void close(ResultSet rs, PreparedStatement ps, Connection conn) { try { if (rs != null) rs.close(); if (ps != null) ps.close(); if (conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } }
[News.java]
package test; public class News { private int id; private String title; private String author_name; public News() { super(); } public News(int id, String title, String anthor_name) { super(); this.id = id; this.title = title; this.author_name = anthor_name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getAuthor_name() { return author_name; } public void setAuthor_name(String author_name) { this.author_name = author_name; } @Override public String toString() { return "News [id=" + id + ", title=" + title + ", author_name=" + author_name + "]"; } }
[Test1.java]
package test; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; import java.util.List; import step1.JDBCUtils; public class Test1 { public static void main(String[] args) throws SQLException { createTable(); JDBCUtils jUtils = new JDBCUtils(); News news1 = new News(1, "Yue Yunpeng's 18 years old, Jia Ling's 18 years old, Shen Teng's 18 years old, netizen: aren't you here to be funny?", "Xiao Ming"); News news2 = new News(2, "Assuming that the aircraft runs 1 light year per second, can it fly to the edge of the universe? Scientists say the answer", "The big Question "); jUtils.insert(news1); jUtils.insert(news2); // Modify data news1.setAuthor_name("Guangming net"); jUtils.update(news1); // Delete data jUtils.delete(2); // Get data in table List<News> findAll = jUtils.findAll(); for (int i = 0; i < findAll.size(); i++) { System.out.println(findAll.get(i)); } // Detect update method News findById = jUtils.findById(1); if (!findById.toString().equals(news1.toString())) { System.out.println("Data modification failed,Please check update method"); System.out.println("query id Result of 1:" + findById); } // Check delete method News findById2 = jUtils.findById(2); if (findById2 != null) { System.out.println("Data deletion failed,Please check delete method"); System.out.println("query id Result of 2:" + findById2); } } public static void createTable() { try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { e.printStackTrace(); } Connection conn = null; Statement statement = null; String url = "jdbc:mysql://localhost:3306/"; try { conn = DriverManager.getConnection(url, "root", "123123"); statement = conn.createStatement(); statement.executeUpdate("drop database if exists mysql_db"); statement.executeUpdate("create database mysql_db"); statement.executeUpdate("use mysql_db"); String sql = "create table news(" + "id int primary key, " + "title varchar(60), " + "author_name varchar(30)" + ")"; statement.executeUpdate(sql); } catch (SQLException e) { e.printStackTrace(); } finally { try { if (statement != null) statement.close(); if (conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
Level 2: generic JDBC encapsulation
Task description
This task: encapsulate the JDBC tool class of a generic class.
Relevant knowledge
In the previous chapter, we used JDBC to encapsulate specific classes (News), but in a project, there are far more than one table in the database. Do we need to encapsulate each table? Obviously, it is inappropriate, so we can encapsulate the JDBC tool class as a generic.
Learning reflection( Reflection -- an important mechanism of JAVA )Later, we all know the powerful reflection mechanism. Using reflection, we can obtain the structure information of classes, dynamically call properties and methods, and so on. Therefore, in this chapter, we use reflection to encapsulate the addition, deletion, modification and query of JDBC.
In order to complete this level task, you need to master the common methods of reflection.
Common methods of reflection
-
Three methods to get an instance of Class
Class class=Class name.class; Class class=Class.forName("Full class name"); Class class=object.getClass();
-
Gets the class name of the object
String className=class.getName();//The result is the full class name String className=class.getSimpleName();//Get simple class name
-
Get Field
Field field=class.getField("Attribute name");//Get the property of public through the property name Field[] fields=class.getFields();//Get all properties decorated with public Field field=class.getDeclaredField("Attribute name");//The obtained properties include public and private Field[] field = c.getDeclaredFields();//Get all properties, including public and private
-
Get Field information
String name=field.getName();//Get property name Class<?> type=filed.getType();//Get property type Object value=field.get(obj);//Gets the value of the field property of the obj object field.set(obj,value);//Set the value of the field property of the obj object
-
Set the property of the private modifier to accessible
field.setAccessible(true);//The default value is false. You can only modify public operations. Set true to modify private operations
Analysis and implementation of generic encapsulation of update data
We can analyze from the sql statement. The sql for updating data is familiar to everyone: update table name set column2 = Value2, column3 = value3, where column1 = value1;
Observing the sql statement, we can design this method to let the user pass in an Object object, and then use reflection to obtain all the attributes in the Object to modify it. The specific implementation is as follows (note that the attribute name of the Object should be consistent with the field name and type of the table structure in the database):
public static void update(Object obj) { Connection conn = getConnection();//Get connection object PreparedStatement ps = null; Class<?> c = obj.getClass();//Get the Class of obj StringBuffer sb = new StringBuffer("update "+ c.getSimpleName() +" set ");//Using StringBuffer to modify the construction of SQL statements Field[] field = c.getDeclaredFields();//Get the property array of the object through reflection for(int i = 1; i < field.length; i++) { if(i != field.length-1) { //Judge whether it is the last attribute. If not, add a comma after it sb.append(field[i].getName()).append("=?,"); }else { //If it is the last attribute, add where sb.append(field[i].getName()).append("=? where "); } } //By default, the first attribute is the primary key. When you change, you can change it through the first attribute sb.append(field[0].getName() + "=?"); try { ps = conn.prepareStatement(sb.toString()); for(int i = 1; i < field.length; i++) { field[i].setAccessible(true);//Set private properties that can be accessed ps.setObject(i, field[i].get(obj));//For pre compiled SQL statements? Assign value } field[0].setAccessible(true); ps.setObject(field.length, field[0].get(obj)); ps.execute();//Execute sql statement } catch (Exception e) { e.printStackT\frace(); }finally { close(null,ps,conn);//Close connection data } }
Programming requirements
According to the example of updating data, supplement the code in the editor on the right to complete the three methods of adding data, deleting data and querying all data in the table.
Test description
Test input: None
Expected output:
Student [id=2, name = Li Si, sex = male, age=20]
News [id=1, title = Yue Yunpeng's 18 years old, Jia Ling's 18 years old, Shen Teng's 18 years old, netizen: not to be funny? author_name = Guangming]
News [id=2, title = suppose the aircraft runs 1 light year per second, can it fly to the edge of the universe? Scientists say the answer, author_name = explore the mysteries of the universe]
The platform will call the method you wrote according to the existing Student table and News table to add, delete, modify and query the data. Insert two data loads into the two tables to modify one data in News table and delete one data in Student table. The inserted data is as follows:
Student table
id | name | sex | age |
---|---|---|---|
1 | Zhang San | male | 18 |
2 | Li Si | female | 20 |
News table
id | title | author_name |
---|---|---|
1 | Yue Yunpeng's 18 years old, Jia Ling's 18 years old, Shen Teng's 18 years old, netizen: aren't you here to be funny? | Guangming net |
2 | Assuming that the aircraft runs 1 light year per second, can it fly to the edge of the universe? Scientists say the answer | Xiao Ming |
Note: the JDBC tool classes encapsulated in this chapter are only for reference. You can also encapsulate your own tool classes according to your actual needs.
Start your mission and wish you success!
Implementation code
[JDBCUtils.java]
package step2; import java.lang.reflect.Field; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; public class JDBCUtils { private static Connection getConnection() { try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { e.printStackTrace(); } String url = "jdbc:mysql://localhost:3306/mysql_db"; Connection conn = null; try { conn = DriverManager.getConnection(url, "root", "123123"); } catch (SQLException e) { e.printStackTrace(); } return conn; } /** * The class name corresponds to the table and the attribute corresponds to the field * * @param obj Incoming object * @return */ public void insert(Object obj) { Connection conn = getConnection(); // Connect database PreparedStatement ps = null; /********** Begin **********/ try { String sql = "insert into "; String sql2 = ") values("; // Get class name and table name String simpleName = obj.getClass().getSimpleName(); sql += simpleName + "("; // Get all properties Field[] declaredFields = obj.getClass().getDeclaredFields(); // Splicing sql statements for (int i = 0; i < declaredFields.length; i++) { sql += declaredFields[i].getName(); sql2 += "?"; if (i + 1 != declaredFields.length) { sql += ","; sql2 += ","; } else { sql2 += ")"; } } sql += sql2; ps = conn.prepareStatement(sql); // Fill placeholder for (int i = 0; i < declaredFields.length; i++) { declaredFields[i].setAccessible(true); Object object = null; try { object = declaredFields[i].get(obj); } catch (Exception e) { e.printStackTrace(); } ps.setObject(i + 1, object); } ps.execute(); } /********** End **********/ catch (SQLException e) { e.printStackTrace(); } finally { close(null, ps, conn); } } /** * Get all records in the corresponding table through the Class of the object * * @param c * @return */ public <T> List<T> selectAll(Class<T> c) { Connection conn = getConnection(); List<T> list = new ArrayList<T>(); PreparedStatement ps = null; ResultSet rs = null; /********** Begin **********/ try { // Get class name as table name String simpleName = c.getSimpleName(); // sql query statement String sql = "select * from " + simpleName; ps = conn.prepareStatement(sql); // Get result set rs = ps.executeQuery(); // Get all attributes, corresponding to all columns of the result set Field[] fields = c.getDeclaredFields(); while (rs.next()) { // create object T t = c.newInstance(); // Assign a value to the corresponding attribute of the object for (Field field : fields) { field.setAccessible(true); field.set(t, rs.getObject(field.getName())); } // Add object to collection list.add(t); } } /********** End **********/ catch (Exception e) { e.printStackTrace(); } finally { close(rs, ps, conn); } return list; } /** * Delete objects through primary key (the default first attribute) * * @param obj * @return */ public void delete(Object obj) { Connection conn = getConnection(); PreparedStatement ps = null; /********** Begin **********/ try { // Gets the class name as an indication String simpleName = obj.getClass().getSimpleName(); // Get the information of the first attribute Field[] declaredFields = obj.getClass().getDeclaredFields(); declaredFields[0].setAccessible(true); String name = declaredFields[0].getName(); // sql delete statement String sql = "delete from " + simpleName + " where " + name + "=?"; // Fill placeholder ps = conn.prepareStatement(sql); ps.setObject(1, declaredFields[0].get(obj)); ps.execute(); } /********** End **********/ catch (Exception e) { e.printStackTrace(); } finally { close(null, ps, conn); } } /** * Simulate the update operation of jdbc. By default, the first attribute is the primary key * * @param obj * @return */ public void update(Object obj) { Class<?> c = obj.getClass();// Get the Class of obj StringBuffer sb = new StringBuffer("update " + c.getSimpleName() + " set ");// Using StringBuffer to modify the construction of SQL statements Field[] field = c.getDeclaredFields();// Get the property array of the object through reflection for (int i = 1; i < field.length; i++) { if (i != field.length - 1) { // Judge whether it is the last attribute. If not, add a comma after it sb.append(field[i].getName()).append("=?,"); } else { // If it is the last attribute, add where sb.append(field[i].getName()).append("=? where "); } } // By default, the first attribute is the primary key. When you change, you can change it through the first attribute sb.append(field[0].getName() + "=?"); String sql = sb.toString() + ";"; Connection conn = getConnection();// Get connection object PreparedStatement ps = null; try { ps = conn.prepareStatement(sql); for (int i = 1; i < field.length; i++) { field[i].setAccessible(true);// Set private properties that can be accessed ps.setObject(i, field[i].get(obj));// For pre compiled SQL statements? Assign value } field[0].setAccessible(true); ps.setObject(field.length, field[0].get(obj)); ps.execute();// Execute sql statement } catch (Exception e) { e.printStackTrace(); } finally { close(null, ps, conn);// Close connection data } } public static void close(ResultSet rs, PreparedStatement ps, Connection conn) { try { if (rs != null) rs.close(); if (ps != null) ps.close(); if (conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } public <T> Object selectById(Class<T> c, int id) { String sql = "select * from " + c.getSimpleName() + " where id=" + id; Field[] field = c.getDeclaredFields(); Connection conn = getConnection(); PreparedStatement ps = null; ResultSet rs = null; Object obj = null; try { ps = conn.prepareStatement(sql); rs = ps.executeQuery(); obj = c.newInstance(); while (rs.next()) { for (int i = 0; i < field.length; i++) { field[i].setAccessible(true); field[i].set(obj, rs.getObject(field[i].getName())); } } } catch (Exception e) { e.printStackTrace(); } finally { close(rs, ps, conn); } return obj; } }
[News.java]
package test; public class News { private int id; private String title; private String author_name; public News() { super(); } public News(int id, String title, String anthor_name) { super(); this.id = id; this.title = title; this.author_name = anthor_name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getAuthor_name() { return author_name; } public void setAuthor_name(String author_name) { this.author_name = author_name; } @Override public String toString() { return "News [id=" + id + ", title=" + title + ", author_name=" + author_name + "]"; } }
[Student.java]
package test; public class Student { private int id; private String name; private String sex; private int age; public Student() { super(); } public Student(int id, String name, String sex, int age) { this.id = id; this.name = name; this.sex = sex; this.age = age; } public int getId() { return id; } public Student setId(int id) { this.id = id; return this; } public String getName() { return name; } public Student setName(String name) { this.name = name; return this; } public String getSex() { return sex; } public Student setSex(String sex) { this.sex = sex; return this; } public int getAge() { return age; } public Student setAge(int age) { this.age = age; return this; } @Override public String toString() { return "Student [id=" + id + ", name=" + name + ", sex=" + sex + ", age=" + age + "]"; } }
[Test2.java]
package test; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; import java.util.List; import step2.JDBCUtils; public class Test2 { static JDBCUtils jUtils = new JDBCUtils(); public static void main(String[] args) { createTable(); Student student1 = new Student(1, "Zhang San", "male", 18); Student student2 = new Student(2, "Li Si", "female", 20); News news1 = new News(1, "Yue Yunpeng's 18 years old, Jia Ling's 18 years old, Shen Teng's 18 years old, netizen: aren't you here to be funny?", "Guangming net"); News news2 = new News(2, "Assuming that the aircraft runs 1 light year per second, can it fly to the edge of the universe? Scientists say the answer", "Xiao Ming"); jUtils.insert(student1); jUtils.insert(student2); jUtils.insert(news1); jUtils.insert(news2); isTrue(student1, student2, news1, news2, "newly added"); news2.setAuthor_name("The big Question "); jUtils.update(news2); student2.setSex("male"); jUtils.update(student2); isTrue(student1, student2, news1, news2, "to update"); jUtils.delete(student1); List<Student> studentList1 = jUtils.selectAll(Student.class); if (studentList1.size() != 0) { if (studentList1.size() != 1) { System.out.println("Data deletion failed,Please check delete method." + student1.toString() + "Not deleted successfully"); } } else { System.out.println("Please complete the query method"); } List<Student> studentList = jUtils.selectAll(Student.class); for (int i = 0; i < studentList.size(); i++) { System.out.println(studentList.get(i)); } List<News> newsList = jUtils.selectAll(News.class); for (int i = 0; i < newsList.size(); i++) { System.out.println(newsList.get(i)); } } public static void createTable() { try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { e.printStackTrace(); } Connection conn = null; Statement statement = null; String url = "jdbc:mysql://localhost:3306/"; try { conn = DriverManager.getConnection(url, "root", "123123"); statement = conn.createStatement(); statement.executeUpdate("drop database if exists mysql_db"); statement.executeUpdate("create database mysql_db"); statement.executeUpdate("use mysql_db"); String sql = "create table News(" + "id int primary key, " + "title varchar(60), " + "author_name varchar(30)" + ")"; statement.executeUpdate(sql); String sql2 = "create table Student(" + "id int primary key, " + "name varchar(20), " + "sex varchar(4)," + "age int" + ")"; statement.executeUpdate(sql2); } catch (SQLException e) { e.printStackTrace(); } finally { try { if (statement != null) statement.close(); if (conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } public static void isTrue(Student student1, Student student2, News news1, News news2, String type) { Student s1 = (Student) jUtils.selectById(Student.class, 1); Student s2 = (Student) jUtils.selectById(Student.class, 2); News n1 = (News) jUtils.selectById(News.class, 1); News n2 = (News) jUtils.selectById(News.class, 2); if (!student1.toString().equals(s1.toString()) || !student2.toString().equals(s2.toString()) || !news1.toString().equals(n1.toString()) || !news2.toString().equals(n2.toString())) { System.out.println("Please complete as required" + type + "method"); } } }
If you still don't know something or want to perform advanced operations, you can move to another article: Learning JDBC is enough