zoukankan      html  css  js  c++  java
  • JDBC的学习笔记-手动实现

      JDBC是SUN公司提供的一套用于数据库操作的接口,Java程序员只需要面向这套接口编程即可。不同的数据库厂商,需要针对这套接口,提供不同实现。

      使用JDBC的好处:1、程序员不需要关注不同数据库的细节。2、编写的代码具有更好的移植性。

      下面是JDBC技术的两种实现方式,这篇文章先只介绍JDBC的手动实现,下一篇文章将介绍使用数据库连接池技术,也就是右边的路线。

      零:首先要将对应的数据库的驱动导入到项目中。

      一、获取连接

       获取连接需要四个信息,分别是:对应数据库的驱动(这里以MySQL数据库为例)url用户名密码

      但是我们一般不直接使用Driver,而是用DriverManager替换Driver来进行驱动的注册加载获取连接

      我们将获取连接所需要的四个信息放在properties文件中

      这是properties文件的代码,driverClass是对应的数据库的驱动;url的写法:jdbc:mysql:是协议,localhost:这里是ip地址,3306是对应的端口号,test是要操作的数据库的库名称。

    driverClass=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/test
    user=root
    password=1234

      接下来就是获取连接的的代码:(这里我将关闭资源、关闭连接的代码写在了一起,作为工具类使用,况且后面也会使用到)

    package jdbc_1;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.sql.Connection;
    import java.sql.Driver;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.Properties;
    
    public class JDBCUtils {
         /*
         *  获取数据库的连接
         */
        public static Connection getConnection() throws Exception {
            //1.读取配置文件
            Properties pros = new Properties();
            InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties");
            pros.load(is);
            
            String driverClass = pros.getProperty("driverClass");
            String url = pros.getProperty("url");
            String user = pros.getProperty("user");
            String password = pros.getProperty("password");
            
            //2.使用反射获取Driver的实现类对象
            Class clazz = Class.forName(driverClass);
            Driver driver = (Driver) clazz.newInstance();
            
            //3.利用DriverManager注册驱动
            DriverManager.registerDriver(driver);
            
            //4.利用DriverManager获取连接
            Connection conn = DriverManager.getConnection(url, user, password);
            
            return conn;
        }
        
        
        /*
         * 关闭资源操作
         * conn是关闭的连接
         * ps是要关闭的PreparedStatement,增删改查都用得到
         * rs是要关闭的ResultSet,查询的操作才用得到
         */
        public static void closeResource(Connection conn,Statement ps,ResultSet rs) {
            try {
                if(ps != null) {
                    ps.close();
                }
            }catch(SQLException e) {
                e.printStackTrace();
            }
                
            try {
                if(conn != null) {
                    conn.close();
                }
            }catch(SQLException e) {
                e.printStackTrace();
            }
    try { if(rs != null) { rs.close(); } }catch (SQLException e) { e.printStackTrace(); } } }

      二、使用PreparedStatement实现增删改、查操作

      注:这里我将增删改放在一起,查单独放在一边,因为查需要返回值,而增删改可以不需要返回值。

      使用PreparedStatement的好处:解决了Statement的拼接、sql注入、无法操作Blob型数据的问题,还进行更高效的批量操作。

      注意:以下的增删改查操作我都是放在JDBCUtils类里面的,作为工具使用

       /*
         *通用的增删改操作
         *sql中的占位符的个数应该与可变形参的长度相同!
         */
        public static void update(String sql,Object...args) {
            //1.获取数据库连接
            Connection conn = null;
            //2.预编译sql语句,返回PreparedStatement的实例
            PreparedStatement ps = null;
            try {
                conn = JDBCUtils.getConnection();
                
                ps = conn.prepareStatement(sql);
                
                //3.填充占位符
                for(int i = 0; i < args.length; i++) {
                    ps.setObject(i+1, args[i]);
                    //MySQL数据库中是从1开始计数的
                }
                
                //4.执行
                ps.execute();
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                //5.关闭资源,关闭连接
                JDBCUtils.closeResource(conn, ps, null);
            }
            
        }

      接下来是通用的查询操作:

       /*
         * 针对于不同的表的通用的查询操作,查询一条或多条记录
         * 第一个参数为需要从数据库表中得到的一条数据所创建的类
         * 第二个参数为查询操作的sql语句
         * 第三个参数用来填充占位符
         */
        public static <T> List<T> getForList(Class<T> clazz,String sql,Object...args) {
            Connection conn = null ;
            PreparedStatement ps = null;
            ResultSet rs = null;
            try {
                //1.获取连接
                conn = JDBCUtils.getConnection();
                //2.预编译的sql语句,获取PreparedStatement对象
                ps = conn.prepareStatement(sql);
                //3.填充占位符
                for(int i = 0; i < args.length; i++) {
                    ps.setObject(i+1, args[i]);
                }
                //4.获取结果集
                rs = ps.executeQuery();
                //5.获取结果集元数据
                ResultSetMetaData rsmd = rs.getMetaData();
                //6.获取列数
                int columnCount = rsmd.getColumnCount();
                //7.创建集合对象
                ArrayList<T> list = new ArrayList<T>();
                while(rs.next()) {
                    //8.通过获取类的实例
                    T t = clazz.newInstance();
                    for(int i = 0 ; i < columnCount; i++) {
                        //9.获取列值
                        Object columnValue = rs.getObject(i+1);
                        
                        //10.获取列的别名
                        String columnLabel = rsmd.getColumnLabel(i+1);
                        
                        //11.给每个列的别名赋予对应的列值,使用反射
                        Field field = clazz.getDeclaredField(columnLabel);
                        field.setAccessible(true);
                        field.set(t, columnValue);
                    }
                    //12.将得到的对象添加进list中
                    list.add(t);
                }
                return list;
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                //13.关闭资源
                JDBCUtils.closeResource(conn, ps, rs);
            }
                    
            return null;
        }

      三、关闭资源和关闭连接

      代码在获取连接的代码中

      以上就是本期的全部代码了,第二次写,在尽力美化排版。

      欢迎大家阅后和我交流,当然学渣能力有限,代码和知识点可能有错误,也欢迎大家告诉我!

  • 相关阅读:
    ZRender实现粒子网格动画实战
    线段树专题—ZOJ1610 Count the Colors
    LeetCode Recover Binary Search Tree
    Android跨进程訪问(AIDL服务)
    刘下记录:ImageView.scaleType 属性全解析(含视频)
    myeclipse解决JSP文件里script背景颜色的调整
    hdu 5381 The sum of gcd(线段树+gcd)
    newlisp HTTP Basic Authentication
    codeforces 132C Logo Turtle--- dp dfs
    python代码风格-PEP8
  • 原文地址:https://www.cnblogs.com/xzhm/p/12267190.html
Copyright © 2011-2022 走看看