JAVA 连接 MySQL 步骤

JDBC实现步骤

1、导入驱动jar包
2、注册驱动
3、获取数据库的连接对象
4、定义sql语句
5、获取执行sql语句的对象
6、执行sql并接收返回结果
7、处理结果
8、释放资源

最简单的格式

public class JdbcDemo {
    public static void main(String[] args) throws Exception {
        //1、导入驱动jar包
        //2、注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");

        //3、获取数据库的连接对象
        Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "123456");

        //4、定义sql语句
        String sql = "select * from user ";

        //5、获取执行sql语句的对象
        Statement stat = con.createStatement();

        //6、执行sql并接收返回结果
        ResultSet resultSet = stat.executeQuery(sql);

        //7、处理结果
        while (resultSet.next()) {
            System.out.println(resultSet.getString("username") + "\t" + resultSet.getString("email"));
        }

        //8、释放资源
        stat.close();
        con.close();
    }
}

封装

package dao;

import com.mysql.cj.jdbc.Driver;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.*;
import java.util.*;

/**
 * @author 86175
 */
public class DBUtil {
    // 数据库对象
    private Connection conn = null;// 连接对象
    private PreparedStatement pstmt = null;// 预编译
    private ResultSet rs = null;// 结果集
    private static Driver driver; // 注意是Mysql下的

    private static Properties prop;

    // 只需类第一次加载时执行的代码  -> 当使用JNDI连接数据库时  可以注释该静态加载
    static {
        // 新方案:模块化引入
        // driver = new OracleDriver();
        try {
            driver = new Driver();
            prop = new Properties();
            prop.setProperty("user", "root");
            prop.setProperty("password", "123456");
            prop.setProperty("driverClassName", "com.mysql.cj.jdbc.Driver");
            prop.setProperty("url", "jdbc:mysql://127.0.0.1:3306/test");
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }




    public Connection getConn() {
        try {
            conn = driver.connect(prop.getProperty("url"),prop);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }


    public int update(String sql, Object... params) {
        int result = -1;
        try {
            conn = this.getConn();// 建立连接
            pstmt = conn.prepareStatement(sql); // 预编译对象 装载SQL
            // 如何给所有占位符 一一注值
            setParams(pstmt, params);
            result = pstmt.executeUpdate(); // 千万别重复加载SQL
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            this.closes(null, pstmt, conn);
        }
        return result;
    }

    private void setParams(PreparedStatement pstmt, Object... params) {
        // 如果没有参数传递 说明执行SQL语句 没有占位符 ?
        if (null == params || params.length <= 0) {
            return;
        }
        // 有参数才进行注值操作 循环参数给预编译语句中SQL 占位符注值
        for (int i = 0, len = params.length; i < len; i++) {
            // 不清楚参数的数据类型 万物皆对象
            try {
                pstmt.setObject(i + 1, params[i]); // + 1 代表第一个 ?
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    public Map<String, Object> findSingle(String sql, Object... params) {
        Map<String, Object> map = null;

        try {
            conn = this.getConn();// 建立连接
            pstmt = conn.prepareStatement(sql); // 预编译对象 装载SQL
            // 如何给所有占位符 一一注值
            setParams(pstmt, params);
            rs = pstmt.executeQuery(); // 千万别重复加载SQL

            List<String> columnNames = getAllColumnNames(rs);

            // 处理结果集
            if (rs.next()) {
                map = new HashMap<String, Object>();

                Object value = null;// 列对应的值
                String type = null; // 列值对应类型

                // 循环列名集合 获取对应的列名
                for (String columnName : columnNames) {
                    // map.put( columnName, rs.getObject(columnName));
                    value = rs.getObject(columnName);
                    // 判空
                    if (null == value) {
                        map.put(columnName, value);
                        continue;
                    }
                    /*
                     * 问题1 不同类型如何兼容处理 BLOB java.math.BigDecimal 如果是Blob类型 该怎么办 ? 图片的处理???
                     * 想办法获取对应的数据类型?
                     */
                    type = value.getClass().getName();// 列值的类型名称
                    // System.out.println( type );

                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            this.closes(rs, pstmt, conn);
        }
        return map;
    }


    public List<Map<String, Object>> findMultiple(String sql, Object... params) {
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        Map<String, Object> map = null;
        try {
            conn = this.getConn();// 建立连接
            pstmt = conn.prepareStatement(sql); // 预编译对象 装载SQL
            // 如何给所有占位符 一一注值
            setParams(pstmt, params);
            rs = pstmt.executeQuery(); // 千万别重复加载SQL

            // 获取所有的列名
            List<String> columnNames = getAllColumnNames(rs);

            // 处理结果集
            while (rs.next()) {
                map = new HashMap<String, Object>();

                Object value = null;// 列对应的值
                String type = null; // 列值对应类型

                // 循环列名集合 获取对应的列名
                for (String columnName : columnNames) {
                    map.put(columnName, rs.getObject(columnName));

                    value = rs.getObject(columnName);
                    // 判空
                    if (null == value) {
                        map.put(columnName, value);
                        continue;
                    }
                    type = value.getClass().getName();// 列值的类型名称
                }
                // map存入list集合中
                list.add(map);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            this.closes(rs, pstmt, conn);
        }
        return list;
    }


    public List<String> getAllColumnNames(ResultSet rs) {
        // 存储查询数据中的列名
        List<String> list = new ArrayList<String>();
        try {
            // getMetaData() 检索此 ResultSet对象的列的数量,类型和属性
            ResultSetMetaData rsmd = rs.getMetaData();
            // ResultSetMetaData 可用于获取有关ResultSet对象中列的类型和属性的信息的对象
            // 获取列的数量
            int columnCount = rsmd.getColumnCount();
            // 列的范围 确定
            for (int i = 1; i <= columnCount; i++) {
                // 获取对应顺序的列名 默认 列名大写 转化成小写
                list.add(rsmd.getColumnName(i).toLowerCase());// 第一列
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return list;
    }
    // 动态SQL查询语句 对应的动态参数 多条件查询 更新 新增代码
    public Map<String, Object> findSingle(String sql, List<Object> params) {
        // 如果没有参数传递 说明执行SQL语句 没有占位符 ?
        if (null == params || params.size() <= 0) {
            return this.findSingle(sql);
        }
        return this.findSingle(sql, params.toArray());
    }
    // 多条查询
    public List<Map<String, Object>> findMultiple(String sql, List<Object> params) {
        // 如果没有参数传递 说明执行SQL语句 没有占位符 ?
        if (null == params || params.size() <= 0) {
            return this.findMultiple(sql);
        }
        return this.findMultiple(sql, params.toArray());
    }
    // 动态更新
    public int update(String sql, List<Object> params) {
        // 如果没有参数传递 说明执行SQL语句 没有占位符 ?
        if (null == params || params.size() <= 0) {
            return this.update(sql);
        }
        return this.update(sql, params.toArray());
    }


    public int update(List<String> sqls, List<List<Object>> params) throws SQLException {
        int result = -1;//定义默认的范围值
        try {
            conn = this.getConn();//获取连接

            //将提交方式设置为手动提交   JDBC 默认自动提交 true
            conn.setAutoCommit( false);
            for(int i = 0, len = sqls.size(); i < len; i ++) {
                pstmt = conn.prepareStatement(sqls.get(i));//预编译对象装载SQL -> list
                this.setParams(pstmt, params.get(i).toArray());//需要给占位符注入参数
                result = pstmt.executeUpdate();//执行更新语句
            }
            conn.commit();//事务提交
        } catch (SQLException e) {
            e.printStackTrace();
            conn.rollback();//事务提交
        } finally {
            conn.setAutoCommit( true); //恢复提交方法是 -> 自动提交
            this.closes(rs, pstmt, conn);
        }
        return result;
    }


    public  int  total(String sql, Object ... params){
        int result = 0;
        try {
            conn = this.getConn();
            pstmt = conn.prepareStatement(sql);
            // 设置参数
            setParams(pstmt, params);
            // 执行语句块
            rs = pstmt.executeQuery();

            // 处理结果集
            if(rs.next()){
                result = rs.getInt(1);// 列索引 第一列
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally{
            this.closes(rs, pstmt, conn);
        }
        return result;
    }

    // 动态SQL查询   句  对应的动态参数  多条件查询的更新或查询   新增的代码
    public <T> List<T>  findMultiple (Class<T> cls, String sql, List<Object> params) {
        // 如果没有参数传递 说明执行SQL语句 没有占位符 ?
        if( params == null || params.isEmpty() ) { // 参数列表无数据
            return this.findMultiple(cls, sql, params);
        }
        return this.findMultiple(cls, sql, params.toArray());
    }

    // 单条动态查询
    public <T> T findSingle(Class<T> cls ,String sql, List<Object> params) {
        if (null == params || params.size() <= 0) {
            return this.findSingle(cls, sql);
        }
        return this.findSingle(cls, sql, params.toArray());
    }

    // 新增动态SQL查询总数
    public int total(String sql, List<Object > params) {
        if( params == null || params.isEmpty() ) { // 参数列表无数据
            return this.total(sql);
        }
        return this.total(sql, params.toArray() );
    }


    public <T> List<T> findMultiple( Class<T> cls ,String sql, Object ... params){
        List<T> list = new ArrayList<T>();
        try {
            conn = this.getConn();//获取连接
            pstmt = conn.prepareStatement(sql);//预编译对象装载SQL
            this.setParams(pstmt, params);//需要给占位符注入参数
            rs = pstmt.executeQuery();//执行更新语句

            //现获取所有的列名
            List<String> columnNames = this.getAllColumnNames(rs);

            T t = null ; // 声明一个对象
            Object value = null;// 列所对应的值
            String typeName = "";// 列所对应的值的类型

            // 同通过反射获取当前类中所有的方法methods
            Method[] methods = cls.getDeclaredMethods();

            while( rs.next()) { //处理结果集

                //  调用无参数 的构造方法  AdminInfo admin = new AdminInfo();
                t = cls.newInstance();

                // 循环列名集合 获得对应的列名
                for(String columnName : columnNames) {
                    //列对应的类型不确定

                    value = rs.getObject(columnName);
                    //判空
                    if( null == value) {  // 数据库无数据
                        continue;
                    }

                    // 循环类中所有的方法
                    for (Method method : methods) {
                        // 是否有对应的 setXXX 方法名  set + columnName -> setAid  method的名字
                        String name = "set" +  columnName;
                        // 获取列对应值的类型
                        typeName = value.getClass().getName();
                        // System.out.println(typeName); //oracle.sql.BLOB   java.math.BigDecimal
                        // 找到对应的方法名 并激活方法
                        if( name.equalsIgnoreCase( method.getName())) {
                            // 判断数据类型
                            if("java.math.BigDecimal".equals(typeName)) {
                                try {
                                    method.invoke( t, rs.getDouble( columnName ));
                                }catch(Exception e) {
                                    method.invoke( t, rs.getString( columnName ));
                                }
                            }else if("java.lang.String".equals(typeName)) {
                                method.invoke( t, rs.getString( columnName ));
                            }else if("java.lang.Double".equals(typeName)) {
                                method.invoke( t, rs.getDouble( columnName ));
                            }else if("java.lang.Integer".equals(typeName)) {
                                method.invoke( t, rs.getInt( columnName ));
                            }else if("java.lang.Date".equals(typeName)) {
                                // MySQL 中date 数据类型 转换成JavaBean 对象中使用String
                                method.invoke( t, rs.getString( columnName ));
                            }else if("oracle.sql.BLOB".equals(typeName)) {
                                // 获取对应类型数据
                                Blob blob = rs.getBlob(columnName);
                                // 获取对应二进制流操作
                                try(InputStream is = blob.getBinaryStream()){
                                    byte [] bt = new byte[ (int)blob.length()];
                                    is.read(bt);
                                    method.invoke( t, bt);
                                }catch(IOException e) {
                                    e.printStackTrace();
                                }
                            }else {
                                // TODO 后期需要 自行扩展
                            }
                        }
                    }
                }
                list.add(t);
            }
        } catch (InstantiationException | IllegalAccessException | IllegalArgumentException |
                 InvocationTargetException | SQLException e) {
            e.printStackTrace();
        }finally {
            this.closes(rs, pstmt, conn);
        }
        return list;
    }


    public <T> T findSingle( Class<T> cls ,String sql, Object ... params){

        T t = null ; // 声明一个对象

        try {
            conn = this.getConn();//获取连接
            pstmt = conn.prepareStatement(sql);//预编译对象装载SQL
            this.setParams(pstmt, params);//需要给占位符注入参数
            rs = pstmt.executeQuery();//执行更新语句

            //现获取所有的列名
            List<String> columnNames = this.getAllColumnNames(rs);

            Object value = null;// 列所对应的值
            String typeName = "";// 列所对应的值的类型

            // 同通过反射获取当前类中所有的方法methods
            Method[] methods = cls.getDeclaredMethods();

            if( rs.next()) { //处理结果集

                //  调用无参数 的构造方法  AdminInfo admin = new AdminInfo();
                t = cls.newInstance();

                // 循环列名集合 获得对应的列名
                for(String columnName : columnNames) {
                    //列对应的类型不确定
                    value = rs.getObject(columnName);
                    //判空
                    if( null == value) {  // 数据库无数据
                        continue;
                    }
                    // 循环类中所有的方法
                    for (Method method : methods) {
                        // 是否有对应的 setXXX 方法名  set + columnName -> setAid  method的名字
                        String name = "set" +  columnName;
                        // 获取列对应值的类型
                        typeName = value.getClass().getName();

                        // 找到对应的方法名 并激活方法
                        if( name.equalsIgnoreCase( method.getName())) {
                            // 判断数据类型
                            if("java.math.BigDecimal".equals(typeName)) {
                                try {
                                    method.invoke( t, rs.getDouble( columnName ));
                                }catch(Exception e) {
                                    method.invoke( t, rs.getString( columnName ));
                                }
                            }else if("java.lang.String".equals(typeName)) {
                                method.invoke( t, rs.getString( columnName ));
                            }else if("java.lang.Double".equals(typeName)) {
                                method.invoke( t, rs.getDouble( columnName ));
                            }else if("java.lang.Integer".equals(typeName)) {
                                method.invoke( t, rs.getInt( columnName ));
                            }else if("java.sql.Date".equals(typeName)) {
                                // MySQL 中date 数据类型 转换成JavaBean 对象中使用String
                                method.invoke( t, rs.getString( columnName ));
                            }else {
                                // TODO 后期需要 自行扩展
                            }
                        }
                    }
                }
            }
        } catch ( InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException  | SQLException e) {
            e.printStackTrace();
        }finally {
            this.closes(rs, pstmt, conn);
        }
        return t;
    }

    /**
     * 多组sql语句执行
     * @param sqls
     * @param pramas
     * @return
     */
    public int update1(List<String> sqls, List<List<Object>> pramas) {
        int result = -1;//定义失败的默认返回值
        try {
            conn = this.getConn();
            // 事务原子性 要事务全部完成才能提交 所以提交改成手动提交
            conn.setAutoCommit(false);
            //循环处理SQL集合
            for (int i = 0, len = sqls.size(); i < len; i++) {
                pstmt = conn.prepareStatement(sqls.get(i));
                this.setParams(sqls.get(i), pramas.get(i).toArray());
                result = pstmt.executeUpdate();
            }
            conn.commit();// 事务提交
        } catch (SQLException e) {
            e.printStackTrace();
            try {
                result = -1;
                conn.rollback();// 事务回滚
            } catch (SQLException e1) {
                e1.printStackTrace();
//				ConstantValues.logger.info("多SQL事务更新回滚" + e1);
            }
        } finally {
            try {
                conn.setAutoCommit(true);// 回复事务自动提交
                this.closes(null, pstmt,conn);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 插入参数到sql语句中
     * @param sql
     * @param pramas
     */
    private void setParams(String sql, Object ...pramas) {
        for (int i = 0, len = pramas.length; i < len; i++) {
            try {
                pstmt.setObject(i + 1, pramas[i]);
            } catch (SQLException e) {
                e.printStackTrace();
//				ConstantValues.logger.info("第" + (i+1) + "个参数注入失败!" + e);
            }
        }
    }


    // 7、关闭资源 先开启的后关闭 后开启的先关闭 结果集 -> 语句块 -> 连接
    public void closes(ResultSet rs, PreparedStatement pstmt, Connection conn) {
        if (null != rs) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (null != pstmt) {
            try {
                pstmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (null != conn) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }


//    public static void main(String[] args) {
//        DBUtil dbUtil = new DBUtil();
//        List<Map<String, Object>> multiple = dbUtil.findMultiple("select * from user");
//        System.out.println(multiple.size());
//    }
}

posted @ 2024-10-23 13:17  虚拟式  阅读(170)  评论(0)    收藏  举报