zoukankan      html  css  js  c++  java
  • 【JDBC编程】Java 连接 MySQL数据库基础、入门和进阶

    鉴于linux系统下安装oracle数据库过于麻烦,而相关的java连接mysql基本方法的参考文章过少且参差不齐,故本人查阅了一些书和网络资料写下此文章。

    从数据库环境搭建、基本语法到封装工具类全过程,可作为参考。转载请注明来源。

    Content:

    • 常用的JDBC API

    • 数据库环境的搭建

    • 建立数据库连接

    • 数据库访问优化

    一. 常用的JDBC API

    1. DriverManager类 : 数据库管理类,用于管理一组JDBC驱动程序的基本服务。应用程序和数据库之间可以通过此类建立连接。常用的静态方法如下

    • static connection getConnection(String url, String user, String password)  -   获取指定URL的数据库连接
    • static Driver getDriver(String url)   -   返回能够打开url所制定的数据库的驱动程序

    2. Connection接口 : 用于连接数据库。每个Connection对象代表一个数据库连接会话。一个应用程序可与多个数据库建立连接。常用的静态方法如下

    • void close()  -   断开连接,释放此Connection对象的数据库和JDBC资源
    • Statement createStatement()  -   创建一个Statement对象来将SQL语句发送到数据库
    • void commit()  -   用于提交SQL语句,确认从上一次提交/回滚以来进行的所有更改
    • boolean isClosed()  -   这个就不解释了
    • CallableStatement prepareCall(String sql)  -   创建一个CallableStatement对象来调用数据库存储过程
    • PreparedStatement prepareStatement(String sql)   -   创建一个PreparedStatement对象来将参数化的SQL语句发送到数据库
    • void rollback()  -   用于取消SQL语句,取消在当前事物中进行的所有更改

    3. Statement接口 :Statement接口一般用于执行SQL语句。Statement接口的主要功能是将SQL语句传送给数据库,并返回SQL语句的执行结果。

    • boolean execute(String sql)  -   执行给定的SQL语句,该语句可能返回多个结果
    • ResultSet executeQuery(String sql)  -   执行给定的SQL语句,该语句返回单个ResultSet对象
    • int executeUpdate(String sql)  -   执行和给定SQL语句,该语句可能为INSERT、UPDATE或DELETE语句,或者不返回任何内容的SQL语句(如SQL DDL 语句)
    • Connection getConnection()  -   获取生成此Statement对象的Connection对象

    4. ResultSet接口 :用于封装结果集对象,该对象包含访问查询结果的方法。 使用Statement中的executeQuery()方法可以返回有符合查询条件的记录。

    • boolean first()  -   将游标移动到结果集的第一行
    • boolean next()  -   将游标移动到结果集的下一行
    • boolean previous()  -   将游标移动到结果集的上一行
    • void close()  -   释放此ResultSet对象的数据库和JDBC资源

    注: 以上仅是列举后面要用到的方法,更多方法请查询相关文档。

    二. 数据库环境的搭建

      在ubuntu 17.10系统下安装并配置mysql(ubuntu系统下安装mysql非常简单,过程略),使用eclispe开发环境,需要下载并配置mysql的驱动jar包(可参考:http://blog.csdn.net/Kindle_code/article/details/49531977),使用MySQL Workbench图形化软件管理数据库,执行以下语句创建一个本地数据库

      1.创建数据库

    create database CS;
    use CS;
    create table Userdetails(
        id int primary key,  -- 主键id
        username varchar(50) not null,  -- 用户名
        password varchar(50) not null,
        sex char(1) not null -- 性别,1:男,0:女
    )
    
    insert into Userdetails(id,username,password,sex) values(1,'zhangsan','zs123',1);
    insert into Userdetails(id,username,password,sex) values(2,'lisi','lisi123',1);
    insert into Userdetails(id,username,password,sex) values(3,'wangwu','wangwu123',1);
    insert into Userdetails(id,username,password,sex) values(4,'maliu','maliu123',1);
    insert into Userdetails(id,username,password,sex) values(5,'lsy','lsy123',1);

      SQL语法请查阅相关文档,要注意 MSSQL 、Oracle、MySQL 这三个常见的数据库在语法上是有一定区别的

    执行结果:

    三. 建立数据库连接

      1.加载数据库驱动

    Class.forName("com.mysql.jdbc.Driver");

      2.建立数据库连接

    String url = "jdbc:mysql://localhost:3306/CS?useSSL=false"; //注意因为版本问题要添加后面的useSSL语句
    String user = "root";
    String password = "haha";
    Connection conn = DriverManager.getConnection(url, user, password);

      3.创建Statement对象

    • createStatement()方法——用于创建一个基本的Statement对象;
    • prepareStatement(String sql)方法——根据参数化的SQL语句创建一个预编译的PreparedStatement对象;
    • prepareCall(String sql)方法——根据SQL语句来创建一个CallableStatement对象,用于调用数据库的存储过程.
    Statement stmt = conn.createStatement();

      4.执行SQL语句并访问结果集

    String sql = "SELECT id,username FROM Userdetails";
    ResultSet rs = stmt.executeQuery(sql);
    while(rs.next())
    {
        System.out.println(rs.getString(1) + " " + rs.getString("username"));
    }

    当使用getXXX()方法访问结果集中的数据时,可通过列索引或列名来获取游标所指行中的列数据

    如: getXXX(列索引)  / 如getString(...)等

    getXXX("列名") 

    完整实例代码如下:

    import java.sql.*;
    
    public class ExecuteDemo 
    {
        final static String url = "jdbc:mysql://localhost:3306/CS?useSSL=false";
        final static String user = "root";
        final static String password = "haha";
        public static void main(String [] args)
        {
            try
            {
                Class.forName("com.mysql.jdbc.Driver");
                
                Connection conn = DriverManager.getConnection(url, user, password);
                
                System.out.println("连接数据库成功!");
                Statement stmt = conn.createStatement();
                String sql = "SELECT id,username FROM Userdetails";
                ResultSet rs = stmt.executeQuery(sql);
                System.out.println("查询成功!");
                
                while(rs.next())
                {
                    System.out.println(rs.getString(1) + " " + rs.getString("username"));
                }
                rs.close();
                stmt.close();
                conn.close();
            }
            catch(ClassNotFoundException e)
            {
                e.printStackTrace();
            }
            catch(SQLException e)
            {
                e.printStackTrace();
            }
            
        }
    
    }

    执行结果:

    四. 数据库访问优化

      编写了一部分数据库访问和执行代码后能够发现一个问题:在访问数据库时,执行步骤都是相同的,不同的是每次执行SQL语句。因此,为了简化数据库访问操作、减少代码冗余、提高效率,需要将访问数据库时通用的基础代码进行封装,即程序员自己编写一个数据库访问工具类DBUtil,用于提供访问数据库时所用到的连接、查询、更新和关闭等操作的基本方法,其他类通过调用DBUtil工具类来实现数据库的访问。

      1. 编写属性文件

      为了便于后期维护,在编写DBUtil工具类之前,通常将连接数据库的参数信息保存在属性文件中。

    • 在项目的根目录下创建一个config子目录,并添加一个属性文件mysql.properties。该文件时以“键-值”对形式来保存连接mysql数据库的配置信息,内容格式如下:
    driver = com.mysql.jdbc.Driver
    url = jdbc:mysql://localhost:3306/CS?useSSL=false
    user = root
    pwd = q9a6z3

      为了读取属性文件中的配置信息,需要编写一个Config配置类,在该类中通过java.util.Properties类的get()方法来获取指定“键”所对应的“值”

    Config.java

    package util;
    import java.io.FileInputStream;
    import java.util.Properties;
    public class Config
    {
        private static Properties p = null;
        static
        {
            try
            {
                p = new Properties();
                p.load(new FileInputStream("config/mysql.properties"));
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
        }
        
        public static String getValue(String key)
        {
            return p.get(key).toString();
        }
    }

      

      2. 编写DBUtil工具类

    DBUtil.java

    package db;
    import java.sql.*;
    import util.Config;
    
    public class DBUtil
    {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        //得到数据库连接
        public Connection getConnection() throws ClassNotFoundException,
                    SQLException,InstantiationException,IllegalAccessException
        {
            String driver = Config.getValue("driver");
            String url = Config.getValue("url");
            String user = Config.getValue("user");
            String pwd = Config.getValue("pwd");
            try
            {
                Class.forName(driver);  //指定驱动程序
                conn = DriverManager.getConnection(url,user,pwd);
                return conn;
            }
            catch(Exception e)
            {
                throw new SQLException("驱动错误或链接失败!");
            }    
        }
        
      //释放资源
    public void closeAll() { if(rs != null) { try { rs.close(); } catch(SQLException e) { e.printStackTrace(); } } if(pstmt != null) { try { pstmt.close(); } catch(SQLException e) { e.printStackTrace(); } } if(conn != null) { try { conn.close(); } catch(SQLException e) { e.printStackTrace(); } } } //执行SQL语句,可以进行查询 public ResultSet executeQuery(String preparedSql,String[] param) { try { pstmt = conn.prepareStatement(preparedSql); if(param != null) { for(int i = 0; i < param.length; i++) pstmt.setString(i+1, param[i]); } rs = pstmt.executeQuery(); } catch(SQLException e) { e.printStackTrace(); } return rs; } //执行SQL语句,可以进行增、删、改的操作,不能执行查询 public int executeUpdate(String prepareSql,String [] param) { int num = 0; try { pstmt = conn.prepareStatement(prepareSql); if(param != null) { for(int i = 0; i < param.length; i++) pstmt.setString(i+1, param[i]); } num = pstmt.executeUpdate(); } catch(SQLException e) { e.printStackTrace(); } return num; } }

      3.使用DBUtil工具类

    import java.sql.ResultSet;
    import db.DBUtil;
    public class DBDemo
    {
        public static void main(String [] args)
        {
            String selectSql = "SELECT id,username,password,sex FROM Userdetails";
            String insertSql = "INSERT INTO Userdetails(id,username,password,sex) VALUES(?,?,?,?)";
            String updateSql = "UPDATE Userdetails SET password = ? WHERE username = ?";
            String deleteSql = "DELETE FROM Userdetails WHERE username = ?";
            //创建DBUtil对象
            DBUtil db = new DBUtil();
            
            try
            {
                db.getConnection(); //连接数据库
                //查询并显示原来的数据
                ResultSet rs = db.executeQuery(selectSql, null);
                System.out.println("-----------------原来的数据----------------");
                while(rs.next())
                {
                    System.out.println("行 " + rs.getRow() + ":"
                            + rs.getInt(1) + "	"
                            + rs.getString(2) + '	'
                            + rs.getString(3) + '	'
                            + (rs.getInt(4) == 1 ? "男" : "女"));
                }
                System.out.println("----------------------------------------");
                
                //执行添加
                int count = db.executeUpdate(insertSql, new String[] {"9","Rose","123456","0"});
                System.out.println("添加" + count + "行");
                
                //执行修改
                count = db.executeUpdate(updateSql, new String[] {"zs321","zhangsan"});
                System.out.println("修改" + count + "行");
                
                //执行删除
                count = db.executeUpdate(deleteSql, new String[] {"Rose"});
                System.out.println("删除" + count + "行");
                
                //查询并显示更新后的数据
                rs = db.executeQuery(selectSql, null);
                System.out.println("----------------更新后的数据------------------");
                while(rs.next())
                {
                    System.out.println("行 " + rs.getRow() + ":"
                            + rs.getInt(1) + "	"
                            + rs.getString(2) + '	'
                            + rs.getString(3) + '	'
                            + (rs.getInt(4) == 1 ? "男" : "女"));
                }
                System.out.println("----------------------------------------");
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
            finally
            {
                db.closeAll();
            }
                    
        }
    }

    执行结果:

    作者:SeanLiao

    写于2018-1-26

  • 相关阅读:
    [mysql]修改 mysql 数据库端口
    [Angular]基础饼图之我如何将鼠标显示内容的数字 " 1" 去掉
    大三总结
    有符号8位整数的冒泡排序
    康托逆展开
    判断计算机是大端还是小端存储方式及分析
    C语言细节——献给入门者(三)
    C语言复杂声明
    病毒篇
    C语言细节——献给初学者(二)
  • 原文地址:https://www.cnblogs.com/seanliao/p/8360510.html
Copyright © 2011-2022 走看看