zoukankan      html  css  js  c++  java
  • 基本的JDBC以及CRUD/Transaction基本操作

      先上依赖:

            <!-- mysql start -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.38</version>
            </dependency>
            <!-- mysql end -->
            <!-- junit start -->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
            <!-- junit end -->
            <!-- log start -->
            <dependency>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
                <version>1.2</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>1.7.7</version>
            </dependency>
            <!-- log end -->

    基本的JDBCUtil(DBManager):

    /**
     * JDBCUtil with mysql-connector-java-5.1.38.jar<br>
     * 
     * @author Changjiang.Chen
     *
     */
    public class JDBCUtil {
    
        private static final Log log = LogFactory.getLog(JDBCUtil.class);
        private static String URL;
        private static String USER;
        private static String PASS;
        private static String DRIVER;
        static {
            InputStream is = JDBCUtil.class.getClassLoader().getResourceAsStream("mysql.properties");
            Properties prop = new Properties();
            try {
                prop.load(is);
                URL = prop.getProperty("url");
                USER = prop.getProperty("user");
                PASS = prop.getProperty("password");
                DRIVER = prop.getProperty("driver");
                Class.forName(DRIVER);
            } catch (IOException e) {
                log.error("sth wrong with the property file loading pro", e);
            } catch (ClassNotFoundException e) {
                log.error("JDBCUtil:Class.forName(" + DRIVER + ") error", e);
            }
        }
    
        /**
         * 建立链接
         * 
         * @return
         */
        public static Connection getConnection() {
            Connection conn = null;
            try {
                conn = DriverManager.getConnection(URL, USER, PASS);
            } catch (SQLException e) {
                log.error("JDBCUtil:getConnection() error", e);
            }
            return conn;
        }
    
        /**
         * 关闭资源
         * 
         * @param conn
         * @param st
         * @param rs
         */
        public static void closeMysqlResouces(Connection conn, Statement st, ResultSet rs) {
            try {
                if (rs != null) {
                    rs.close();
                }
            } catch (Exception e) {
                log.error("JDBCUtil:rs.close() error", e);
            } finally {
                try {
                    if (st != null) {
                        st.close();
                    }
                } catch (Exception e2) {
                    log.error("JDBCUtil:st.close() error", e2);
                } finally {
                    try {
                        if (conn != null) {
                            conn.close();
                        }
                    } catch (Exception e3) {
                        log.error("JDBCUtil:conn.close() error", e3);
                    }
                }
            }
        }
    
    }

    主要是static代码块里处理资源加载与驱动,另外是提供链接和关闭资源的方法。日志使用了Apache的commons-logging。

    首先测试一下链接的建立:

    public class TestJDBCUtil {
        @Test
        public void testGetConn() {
            Object obj = JDBCUtil.getConnection();
            Assert.assertNotNull(obj);
        }
    
    }

    测试CRUD与事务的过程中,会对数据库增删改,要保证这些方法成功执行并不对原先的数据造成影响就要定义不同测试方法的执行顺序,这里采用了@FixMethodOrder(MethodSorters.NAME_ASCENDING)(4.11之后)按照方法名的字母顺序进行升序执行,保证所有方法成功执行后,数据库的数据不会改动:

    package com.changjiang.practise.demo.jdbc;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.Arrays;
    
    import org.junit.AfterClass;
    import org.junit.Assert;
    import org.junit.BeforeClass;
    import org.junit.FixMethodOrder;
    import org.junit.Test;
    import org.junit.runners.MethodSorters;
    
    /**
     * @author Changjiang.Chen
     */
    /**
     * 重新组合所有测试的执行顺序,按照字母表排序进行执行
     */
    @FixMethodOrder(MethodSorters.NAME_ASCENDING)
    public class TestCRUD {
        private static Connection conn;
        private static Statement st;
        private static ResultSet rs;
        private static PreparedStatement pst;
    
        @BeforeClass
        public static void getConn() {
            conn = JDBCUtil.getConnection();
        }
    
        @AfterClass
        public static void close() {
            JDBCUtil.closeMysqlResouces(conn, st, null);
        }
    
        @Test
        public void testAInsert() {
            try {
                st = conn.createStatement();
                String sql = "INSERT INTO content(id,type,info,num,validtime,label) VALUES(7,'测试','测试信息',0,10,'chiq3_test')";
                int r = st.executeUpdate(sql);
                Assert.assertEquals(1, r);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 参数传入方式可能引起SQL注入
         * 
         * @throws SQLException
         */
        @Test
        public void testCQuery1() {
            try {
                conn = JDBCUtil.getConnection();
                st = conn.createStatement();
                /**
                 * param may be affected
                 */
                String injectParam = "1";
                String sql = "select type from content where id = " + injectParam;
                rs = st.executeQuery(sql);
                String type = "";
                if (rs.next()) {
                    type = rs.getString("type");
                }
                Assert.assertEquals("追剧推送", type);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * preparedStatement对比Statement<br>
         * 如果可以保证sql语句不包含调用者传入的参数,可用后者,否则用前者<br>
         * 大部分情况下都倾向于使用前者,DBUtil,Hibernate都采用了pst
         * 
         * @throws SQLException
         */
        @Test
        public void testCQuery2() {
            try {
                conn = JDBCUtil.getConnection();
                /**
                 * param could not be affected
                 */
                String injectParam = "1";
                String sql = "select type from content where id = ?";
                pst = conn.prepareStatement(sql);
                pst.setString(1, injectParam);
                rs = pst.executeQuery();
                String type = "";
                if (rs.next()) {
                    type = rs.getString("type");
                }
                Assert.assertEquals("追剧推送", type);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * pst应用场景<br>
         * 1.放置sql注入 <br>
         * 2.大数据处理:用IO流处理参数 <br>
         * 3.批处理
         * 
         * @throws SQLException
         */
        @Test
        public void testCUpdate() {
            try {
                conn = JDBCUtil.getConnection();
                String injectParam = "7";
                String sql = "UPDATE content SET type = 'TEST_PUSH' WHERE id = ?";
                pst = conn.prepareStatement(sql);
                pst.setString(1, injectParam);
                int r = pst.executeUpdate();
                Assert.assertEquals(1, r);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 批量操作
         * 
         * @throws SQLException
         */
        @Test
        public void testYBatchUpdate() {
            try {
    
                conn = JDBCUtil.getConnection();
                String sql = "INSERT INTO content(id,type,info,num,validtime,label) VALUES(?,?,?,?,?,?)";
                pst = conn.prepareStatement(sql);
                for (int i = 10; i < 30; i++) {
                    pst.setInt(1, i);
                    pst.setString(2, "测试推送");
                    pst.setString(3, "测试信息");
                    pst.setInt(4, i);
                    pst.setInt(5, 10);
                    pst.setString(6, "开启测试推送模式");
                    pst.addBatch();
                }
                int[] r = pst.executeBatch();
                int[] expected = new int[20];
                for (int i = 0; i < expected.length; i++) {
                    expected[i] = 1;
                }
                Assert.assertEquals(Arrays.toString(expected), Arrays.toString(r));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * Transaction
         */
        @Test
        public void testZTransaction() {
            conn = JDBCUtil.getConnection();
            try {
                conn.setAutoCommit(false);
                st = conn.createStatement();
                int r1 = st.executeUpdate("delete from content where id = 7");
                int r2 = st.executeUpdate("DELETE FROM content WHERE validtime = 10");
                conn.commit();
                Assert.assertEquals(Arrays.toString(new int[] { r1, r2 }), Arrays.toString(new int[] { 1, 20 }));
            } catch (SQLException e) {
                e.printStackTrace();
                try {
                    conn.rollback();
                } catch (SQLException e1) {
                    e1.printStackTrace();
                }
            }
        }
    
    }
  • 相关阅读:
    减绳子 [二分查找]
    *数据删除*OJ的原题大赏
    多项式大总结
    【YBTOJ】【Luogu P6218】[USACO06NOV] Round Numbers S
    【YBTOJ】【HDU3652】B-number
    【Luogu P5752】[NOI1999] 棋盘分割
    【YBTOJ】【UVA10559】方块消除 Blocks
    【YBTOJ】【Luogu P5020】[NOIP2018 提高组] 货币系统
    【YBTOJ】【Luogu P4180】[BJWC2010]严格次小生成树
    【YBTOJ】【Luogu P2680】[NOIP2015 提高组] 运输计划
  • 原文地址:https://www.cnblogs.com/bruceChan0018/p/6053951.html
Copyright © 2011-2022 走看看