JDBC
JAVA Database Connectivity Java database connection
To put it bluntly: JDBC is a kind of database access rules and specifications provided by Sun Company. Because there are many kinds of databases and the java language is widely used, Sun provides a specification for other database providers to implement the underlying access rules. Our java program can only use jdbc driver provided by sun company.
Basic steps for using JDBC
- Import driver
The java project file (that is, the peoject you created) is right-clicked - > Build Path - > Configure Build Path - > Libraries - > Add External JARS - > select mysql-connector-java-8.0.16.jar (I downloaded version 8.0.16) - Registration Driver
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
- Establish a connection
Connection conn = null; conn = DriverManager.getConnection("jdbc:mysql://Localhost / javatest? Server Timezone = UTC ","username","password";
- Create Statement
Statement st = null; st = conn.createStatement();
- Execute sql to get ResultSet
//Take queries as an example String sql = "select * from peo"; rs = st.executeQuery(sql);
- Traversal result set
String sql = "select * from peo"; rs = st.executeQuery(sql); while(rs.next()) { String id = rs.getString("Pno"); String name = rs.getString("Pname"); String pwd = rs.getString("Paswd"); System.out.println("id:"+id+" name:"+name+" pwd:"+pwd); }
- Releasing resources
//Release order: rs-> st-> conn; //For example, conn try { if(conn != null) { conn.close(); System.out.println("conn Successful closure"); }}catch (SQLException e) { e.printStackTrace(); }finally { conn = null; }
Writing a java file above is really bloated. All the JDBC tool classes introduced can make the code more flexible.
JDBC Tool Class Creation
1. Integration of Resource Release Work
The resource release code is written in a tool class JDBCUtil.java
JDBCUtil.java
/* * Releasing resources * */ public static void release(Connection conn,Statement st,ResultSet rs) { closeRs(rs); closeSt(st); closeConn(conn); } private static void closeRs(ResultSet rs) { try { if(rs != null) { rs.close(); System.out.println("rs Successful closure"); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { rs = null; } } private static void closeSt(Statement st) { try { if(st != null) { st.close(); System.out.println("st Successful closure"); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { st = null; } } private static void closeConn(Connection conn) { try { if(conn != null) { conn.close(); System.out.println("conn Successful closure"); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { conn = null; } }
Then call the release function directly in the main program final.
finally { JDBCUtil.release(conn, st, rs); }
2. Drive prevention secondary registration
Driver class contains a static code base, which contains a section of code that is
java.sql.DriverManager.registerDriver(new Driver());
It was executed at first, so it's equivalent to registering two drivers. In fact, it is not necessary.
Finally, we usually use:
Class.forName("com.mysql.cj.jdbc.Driver");
3. Use properties configuration files
- Declare a file jdbc.properties under src. The contents (no quotes, no semicolons) are as follows:
driverClass = com.mysql.cj.jdbc.Driver url = jdbc:mysql://localhost/javatest?serverTimezone=UTC name = root passwd = 52151
- In the tool class, use static code blocks to read attributes
static String driverClass = null; static String url = null; static String name = null; static String passwd = null; static { try { //Create a property configuration object Properties properties = new Properties(); InputStream is = JDBCUtil.class.getClassLoader().getResourceAsStream("jdbc.properties"); //Import Input Flow properties.load(is); //read attribute driverClass = properties.getProperty("driverClass"); url = properties.getProperty("url"); name = properties.getProperty("name"); passwd = properties.getProperty("passwd"); } catch (Exception e) { e.printStackTrace(); } }
CRUD operation of database
- Insert
//insert returns the number of rows affected > 0 if the operation succeeds or fails sql = "INSERT INTO peo VALUES(\"5\",\"ds5\",\"1513213\");"; int results = st.executeUpdate(sql); if(results > 0 ) { System.out.println("Added Successfully"); }else { System.out.println("Failure to add"); }
- Delete
sql = "DELETE FROM peo where Pno= '5';"; results = st.executeUpdate(sql); if(results > 0 ) { System.out.println("Successful deletion"); }else { System.out.println("Delete failed"); }
- Query
String sql = "select * from peo"; rs = st.executeQuery(sql); //Traversal result set while(rs.next()) { String id = rs.getString("Pno"); String name = rs.getString("Pname"); String pwd = rs.getString("Paswd"); System.out.println("id: "+id+" name: "+name+" pwd: "+pwd); }
- Update
sql = "UPDATE peo SET Paswd = '88889' WHERE Pno = '4';"; results = st.executeUpdate(sql); if(results > 0 ) { System.out.println("Update Successful"); }else { System.out.println("Update failed"); }
Using unit testing JUNIT to test code steps
- Define a class, such as TestDemo.java, which defines the method testXXX. It must start with test.
- Adding Junit support
Right-click Project - > Add Library - > Junit - > Junit4/5
Note that you added it to Classpath - With annotations to the method, it's actually a tag that Junit doesn't know without the @Test tag.
@Test public void testQuery() { ... }
- The cursor selects the method name and right-clicks the unit test (run as). Or open the outline attempt and select the method name to execute.
Dao model
Date Access Object Data Access Object
- Create a new dao interface peoDao.java, which declares database access rules
package com.yl.dao.demo; import java.util.List; import java.util.Map; public interface peoDao { //Query all void findAll(); //Sign in void login(String username,String password); //Add to void insert(String username,String password); //delete void delete(String id); //Update user name based on id void update(String id,String username); //Traverse the output by returning a List List< Map<String,String> > findall(); //Return to int to get several rows affected int delete1(String id); }
- Create a new dao implementation class peoDaoImpl.java to implement the previously defined rules
package com.yl.dao.impl; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.Statement; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.yl.dao.demo.peoDao; import com.yl.dao.util.JDBCUtil; public class peoDaoImpl implements peoDao { @Override public void findAll() { Connection conn = null; Statement st = null; ResultSet rs = null; try { // Get the connection object conn = JDBCUtil.getConn(); // Create Statement st = conn.createStatement(); String sql = "select * from p_user"; rs = st.executeQuery(sql); // Traversal result set while (rs.next()) { String id = rs.getString("Pno"); String name = rs.getString("Pname"); String pwd = rs.getString("Paswd"); System.out.println("id: " + id + " name: " + name + " pwd: " + pwd); } } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } finally { JDBCUtil.release(conn, st, rs); } } @Override public void login(String username, String password) { Connection conn = null; Statement st = null; ResultSet rs = null; try { // TODO Auto-generated method stub // Get the connection object conn = JDBCUtil.getConn(); // Create Statement String sql = "select * from p_user where Pname = ? and Paswd = ?"; // Execute the grammar check of sql statement beforehand, and the corresponding content will be treated as a string no matter what comes in later. PreparedStatement ps = conn.prepareStatement(sql);// Safer than Statement // ? The corresponding index starts from 1. ps.setString(1, username); ps.setString(2, password); rs = ps.executeQuery(); // Traversal result set if (rs.next()) { System.out.println("Successful login"); } else System.out.println("Landing Failure"); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } finally { JDBCUtil.release(conn, st, rs); } } @Override public void insert(String username, String password) { // TODO Auto-generated method stub Connection conn = null; PreparedStatement ps = null; int res; try { // TODO Auto-generated method stub // Get the connection object conn = JDBCUtil.getConn(); // Create Statement String sql = "insert into p_user values('10' , ? , ?);"; // Execute the grammar check of sql statement beforehand, and the corresponding content will be treated as a string no matter what comes in later. ps = conn.prepareStatement(sql);// Safer than Statement // ? The corresponding index starts from 1. ps.setString(1, username); ps.setString(2, password); res = ps.executeUpdate(); // Traversal result set if (res > 0) { System.out.println("Successful insertion"); } else System.out.println("Insertion failure"); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } finally { JDBCUtil.release(conn, ps); } } @Override public void delete(String id) { // TODO Auto-generated method stub Connection conn = null; PreparedStatement ps = null; int res; try { // TODO Auto-generated method stub // Get the connection object conn = JDBCUtil.getConn(); // Create Statement String sql = "delete from p_user where Pno = ?"; // Execute the grammar check of sql statement beforehand, and the corresponding content will be treated as a string no matter what comes in later. ps = conn.prepareStatement(sql);// Safer than Statement // ? The corresponding index starts from 1. ps.setString(1, id); res = ps.executeUpdate(); // Traversal result set if (res > 0) { System.out.println("Successful deletion"); } else System.out.println("Delete failed"); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } finally { JDBCUtil.release(conn, ps); } } @Override public void update(String id, String username) { Connection conn = null; PreparedStatement ps = null; int res; try { // TODO Auto-generated method stub // Get the connection object conn = JDBCUtil.getConn(); // Create Statement String sql = "update p_user set Pname = ? where Pno = ? "; // Execute the grammar check of sql statement beforehand, and the corresponding content will be treated as a string no matter what comes in later. ps = conn.prepareStatement(sql);// Safer than Statement // ? The corresponding index starts from 1. ps.setString(1, username); ps.setString(2, id); res = ps.executeUpdate(); // Traversal result set if (res > 0) { System.out.println("Update Successful"); } else System.out.println("Update failed"); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } finally { JDBCUtil.release(conn, ps); } } @Override public List<Map<String, String>> findall() { List< Map<String,String> > peos= new ArrayList<>(); Map<String,String> peo = new HashMap<>(); Connection conn = null; Statement st = null; ResultSet rs = null; try { // TODO Auto-generated method stub // Get the connection object conn = JDBCUtil.getConn(); // Create Statement st = conn.createStatement(); String sql = "select * from p_user"; rs = st.executeQuery(sql); // Traversal result set while (rs.next()) { String id = rs.getString("Pno");//id String name = rs.getString("Pname");//name peo.put(id,name); //System.out.println("id: " + id + " name: " + name + " pwd: " + pwd); } peos.add(peo); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } finally { JDBCUtil.release(conn, st, rs); } return peos; } @Override public int delete1(String id) { Connection conn = null; PreparedStatement ps = null; int res = 0; try { // TODO Auto-generated method stub // Get the connection object conn = JDBCUtil.getConn(); // Create Statement String sql = "delete from p_user where Pno = ?"; // Execute the grammar check of sql statement beforehand, and the corresponding content will be treated as a string no matter what comes in later. ps = conn.prepareStatement(sql);// Safer than Statement // ? The corresponding index starts from 1. ps.setString(1, id); res = ps.executeUpdate(); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } finally { JDBCUtil.release(conn, ps); } return res; } }
- Create a new TestDemoDaoImpl direct-use implementation
package com.yl.dao.test; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import org.junit.Test; import com.yl.dao.demo.peoDao; import com.yl.dao.impl.peoDaoImpl; public class TestUserDaoImpl { @Test public void testFindAll() { peoDao dao = new peoDaoImpl(); dao.findAll(); } @Test public void testLogin() { peoDao dao = new peoDaoImpl(); dao.login("yl", "123456"); // dao.login("yl","123456 ' or '1=1'"); } @Test public void testInsert() { peoDao dao = new peoDaoImpl(); dao.insert("zk", "123147"); } @Test public void testDelete() { peoDao dao = new peoDaoImpl(); dao.delete("10"); } @Test public void testUpdate() { peoDao dao = new peoDaoImpl(); dao.update("4", "hhh"); } @Test public void testFindall() { List< Map<String,String> > peos = new ArrayList<>(); peoDao dao = new peoDaoImpl(); peos = dao.findall(); for(Map<String, String> map : peos) { Iterator<String> it = map.keySet().iterator(); while(it.hasNext()) { String key = it.next(); System.out.println("id:"+key+" name:"+map.get(key)); } } } @Test public void testDelete1() { peoDao dao = new peoDaoImpl(); int ans = dao.delete1("5"); //There are three in the mysql table System.out.println(ans+"Row receives impact"); //Completion } }
Statement security issues
- Statement execution is actually splicing sql statements. Splice sql statements first, and then execute them together.
SELECT * FROM peo WHERE username='admin' AND PASSWORD='100234khsdf88' or '1=1' Before splicing sql statements, if the variables contain database keywords, then they are considered keywords. I don't think it's a normal string.
So PrepareStatement is generally used.
PrepareStatement
This object replaces the previous state object.
Compared with previous statements, a given sql statement is preprocessed and grammar checked. Use? Placeholders in sql statements to replace subsequent variables to be passed in. The value of the variable that comes in later will be treated as a string and will not produce any keywords.
String sql = "insert into t_user values(null , ? , ?)"; ps = conn.prepareStatement(sql); //Assign placeholders from left to right. 1 represents the first question mark. You always start with 1. ps.setString(1, userName); ps.setString(2, password);
End?maybe......