• 基本的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();
                }
            }
        }
    
    }
  • 相关阅读:
    message:"iconv(): Detected an illegal character in input string"
    VM Mac OS 无法开机
    你的爱 歌词
    大脑结构 | 前脑 | 中脑 | 后脑 | 脑干 | 大脑发育
    【分布计算环境笔记】10 SOA、网格计算、云计算与P2P技术
    【职场Tips】Language in IBM——献给所有即将成为IBMer的童鞋
    【系统工程师的自我修养】sed篇
    【Java学习笔记】如何写一个简单的Web Service
    Unison(双向同步软件)的安装与配置【转】
    发生java.lang.OutOfMemoryError: Direct buffer memory【转】
  • 原文地址:https://www.cnblogs.com/bruceChan0018/p/6053951.html
Copyright © 2020-2023  润新知