JDBC连接mysql

JDBC连接数据库步骤:

一、加载驱动(先导入mysql-connector-java-5.1.49.jar      右击项目 -> BuildPath -> Configure BuildPath->AddExteranl JARs...)

二、连接数据库

三、使用语句操作数据库

四、关闭数据库连接,释放资源

    //驱动
private static String jdbcName = "com.mysql.jdbc.Driver"; /**
*jdbc:mysql://IP 地址:端口号/数据库名称
*jdbc 协议:JDBC URL 中的协议总是 jdbc
*子协议:驱动程序名或数据库连接机制(这种机制可由一个或多个驱动程序支持)的名称,如 mysql
*子名称:一种标识数据库的方法。必须遵循“//主机名:端口/子协议(数据库名)”的标准 URL 命名约定,如 //localhost:3306/test
/
private static String dbUrl = "jdbc:mysql://localhost:3306/test"; private static String user = "root"; private static String password = "root"; public static void main(String[] args) { Connection conn = null; try { //加载驱动 Class.forName(jdbcName); System.out.println("驱动加载成功");
//DriverManager驱动管理类,主要负责获取一个数据库的连接 conn
= DriverManager.getConnection(dbUrl, user, password); System.out.println("连接成功"); } catch (ClassNotFoundException e) { e.printStackTrace(); System.err.println("驱动加载失败"); } catch (SQLException e) { e.printStackTrace(); }finally { try { conn.close();//关闭连接 } catch (SQLException e) { e.printStackTrace(); } } }

工具类

import java.sql.Connection;
import java.sql.DriverManager;


public class DbUitl
{
    private static String jdbcName = "com.mysql.jdbc.Driver";
    private static String dbUrl = "jdbc:mysql://localhost:3306/test";
    private static String user = "root";
    private static String password = "root";
    
    /**
     * 获取数据库连接
     * @return
     * @throws Exception
     */
    public Connection getCon() throws Exception{
        Class.forName(jdbcName);
        Connection connection =  DriverManager.getConnection(dbUrl, user, password);
        return connection;
    }
    /**
     * 关闭连接
     * @param connection
     * @throws Exception
     */
   public  void close(Statement statement,Connection connection) throws Exception{
   if(statement != null){
    statement.close();
    if(connection != null ){
     connection.close();
    }
   }
 } }

Statement接口

作用:用于执行静态 SQL 语句并返回它所生成结果的对象。
intexecuteUpdate(String sql) 执行给定 SQL 语句,该语句可能为 INSERT、UPDATE 或 DELETE 语句,或 者不返回任何内容的 SQL 语句(如 SQLDDL 语句)。 voidclose() 立即释放此 Statement 对象的数据库和 JDBC 资源,而不是等待该对象自动关闭时发生此操作

        DbUitl dbUitl =  new DbUitl();
        String sql = "insert into t_book value(null,'java牛逼',888,'B哥',1)";
        try
        {
            Connection conn = dbUitl.getCon();//获取数据库连接
            Statement statement = conn.createStatement();//获取Statement
            int result = statement.executeUpdate(sql);//可以执行增、删、改操作
            System.out.println("操作结果:"+result+"数据");
            dbUitl.close(statement,conn);//关闭statement和conn
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

 

PreparedStatement接口

PreparedStatement 是 Statement 的子接口,属于预处理操作,与直接使用 Statement 不同的是,PreparedStatement 在操作时,是先在数据表中准备好了一条 SQL 语句,但是此 SQL 语句的具体内容暂时不设置,而是之后再进 行设置。 (以后开发一般用 PreparedStatement,不用 Statement)

        DbUitl dbUitl =  new DbUitl();
        String sql = "insert into t_book value(null,?,?,?,?)";
        try
        {
            Connection conn = dbUitl.getCon();//获取数据库连接
            PreparedStatement prestmt = conn.prepareStatement(sql);//获取Statement
            prestmt.setString(1, "节哀吧");
            prestmt.setFloat(2, 2);
            prestmt.setString(3, "我");
            prestmt.setInt(4, 2);
            int result = prestmt.executeUpdate();
            System.out.println("操作结果:"+result+"数据");
            dbUitl.close(prestmt,conn);//关闭preparedStatement和conn
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

结果集:ResultSet(光标刚开始位于第一行之前)

当我们查询数据库时,返回的是一个二维的结果集,我们这时候需要使用 ResultSet 来遍历结果集,获取每一行 的数据。

使用 ResultSet 遍历查询结果
booleannext() 将光标从当前位置向前移一行。

String getString(int columnIndex) 以 Java 编程语言中 String 的形式获取此 ResultSet 对象的当前行中指定列 的值。

            String sql = "select * from t_book";
        try
        {
            Connection conn = dbUitl.getCon();//获取数据库连接
            PreparedStatement prestmt = conn.prepareStatement(sql);//获取Statement
            //ResultSet 光标刚开始位于第一行之前
            ResultSet resultSet =  prestmt.executeQuery();//返回结果集
            while(resultSet.next()){//光标向前移动一行
                int id = resultSet.getInt(1);//获取第一列的值
                String bookName = resultSet.getString(2);//获取第二列的值
                float price = resultSet.getFloat(3);//获取第三列的值
                int bookType = resultSet.getInt(5);//获取第五列的值
                System.out.println("id="+id+"bookName="+bookName+"price="+price+"bookType="+bookType);
            }
            dbUitl.close(prestmt,conn);//关闭preparedStatement和conn
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

 

String getString(String columnLabel) 以 Java 编程语言中 String 的形式获取此 ResultSet 对象的当前行中指 定列的值

             String sql = "select * from t_book";
        try
        {
            Connection conn = dbUitl.getCon();//获取数据库连接
            PreparedStatement prestmt = conn.prepareStatement(sql);//获取Statement
            //ResultSet 光标刚开始位于第一行之前
            ResultSet resultSet =  prestmt.executeQuery();//返回结果集
            while(resultSet.next()){//光标向前移动一行
                int id = resultSet.getInt("id");//获取数据库字段为id的值
                String bookName = resultSet.getString("bookName");//获取数据库字段为bookName值
                float price = resultSet.getFloat("price");
                int bookType = resultSet.getInt("bookTypeId");
                System.out.println("id="+id+"bookName="+bookName+"price="+price+"bookType="+bookType);
            }
            dbUitl.close(prestmt,conn);//关闭preparedStatement和conn
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

大数据对象处理主要有 CLOB(characterlarge object)和 BLOB(binary large object)两种类型的字段;在 CLOB 中可以存储大字符数据对象,比如长篇小说;在 BLOB 中可以存放二进制大数据对象,比如图片,电影,音乐

处理CLOB(字符大数据对象)

DbUitl dbUitl =  new DbUitl();
        String sql = "insert into t_book value(null,?,?,?,?,?)";
        try
        {
            Connection conn = dbUitl.getCon();//获取数据库连接
            PreparedStatement prestmt = conn.prepareStatement(sql);//获取Statement
            prestmt.setString(1, "节哀吧");
            prestmt.setFloat(2, 2);
            prestmt.setString(3, "我");
            prestmt.setInt(4, 2);
            File file = new File("D:\\test\\LICENSE.txt");
            InputStream inputStream = new FileInputStream(file);
            prestmt.setAsciiStream(5, inputStream, file.length());//数据库字段为longtext
            int result = prestmt.executeUpdate();
            System.out.println("操作结果:"+result+"数据");
            dbUitl.close(prestmt,conn);//关闭preparedStatement和conn
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
String sql = "select * from t_book";
        try
        {
            Connection conn = dbUitl.getCon();//获取数据库连接
            PreparedStatement prestmt = conn.prepareStatement(sql);//获取Statement
            //ResultSet 光标刚开始位于第一行之前
            ResultSet resultSet =  prestmt.executeQuery();//返回结果集
            while(resultSet.next()){//光标向前移动一行
                int id = resultSet.getInt("id");//获取第一列的值
                String bookName = resultSet.getString("bookName");//获取第二列的值
                float price = resultSet.getFloat("price");//获取第三列的值
                int bookType = resultSet.getInt("bookTypeId");//获取第五列的值
                Clob c = resultSet.getClob("context");//获取CLOB
                String context = null;
                if(c!=null){
                     context = c.getSubString(1, (int)c.length());
                }
                System.out.println("id="+id+"bookName="+bookName+"price="+price+"bookType="+bookType+"context="+context);
            }
            dbUitl.close(prestmt,conn);//关闭preparedStatement和conn
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

 

处理BLOB(二进制大数据对象)

 

            File pic = new File("D:\\test\\1.png");
            InputStream inputStream2 = new FileInputStream(pic);
            prestmt.setBinaryStream(6, inputStream2, pic.length());//数据库类型为longbolb
                Blob b = resultSet.getBlob("pic");
                if(b!=null){
                    FileOutputStream fos = new FileOutputStream(new File("d://pic2.png"));
                    fos.write(b.getBytes(1, (int)b.length()));
                    fos.close();
                }

CallableStatement 接口:

CallableStatement 主要是调用数据库中的存储过程,CallableStatement 也是 Statement 接口的子接口。在使用 CallableStatement 时可以接收存储过程的返回值。

 

//存储过程
DELIMITER && CREATE PROCEDURE pro_getBookNameByid(IN bookId INT,OUT bN VARCHAR(20)) BEGIN SELECT bookName INTO bN FROM t_book WHERE id = bookId; END && DELIMITER ;

//数据库执行存储过程
CALL pro_getBookNameByid(1,@bookName);
SELECT @bookName;//查看值

 

使用 CallableStatement 接口调用存储过程:
voidregisterOutParameter(int parameterIndex, intsqlType) 按顺序位置 parameterIndex 将 OUT 参数注册为 JDBC 类型 sqlType

        Connection con = dbUitl.getCon();
        String sql = "{CALL pro_getBookNameByid(?,?)}";
        CallableStatement cstmt = con.prepareCall(sql);
        cstmt.setInt(1, 2);//第一个参数  输入参数 id
        cstmt.registerOutParameter(2, Types.VARCHAR); //第二个参数  输出参数
        cstmt.execute();
        String bookName = cstmt.getString("bN");  // 获取返回值
        dbUitl.close(cstmt, con);

使用 DatabaseMetaData 获取数据库基本信息

DatabaseMetaData 可以得到数据库的一些基本信息,包括数据库的名称、版本,以及得到表的信息。

StringgetDatabaseProductName() 获取此数据库产品的名称。

intgetDriverMajorVersion() 获取此 JDBC 驱动程序的主版本号。

intgetDriverMinorVersion() 获取此 JDBC 驱动程序的次版本号。

        Connection con = dbUitl.getCon();
        DatabaseMetaData dmd = con.getMetaData();
        String dbpn = dmd.getDatabaseProductName();//数据库名称  
        System.out.println(dbpn);//mysql
        System.out.println("数据库的版本号:"+
                             dmd.getDatabaseMajorVersion()+//主版本号
                             "."+
                             dmd.getDatabaseMinorVersion()//次版本号
                             );//  数据库的版本号:5.5

使用 ResultSetMetaData 获取 ResultSet 对象中的信息

ResultSetMetaData 可获取关于 ResultSet 对象中列的基本信息;

intgetColumnCount() 返回此 ResultSet 对象中的列数。

StringgetColumnName(int column) 获取指定列的名称。

intgetColumnTypeName(int column) 获取指定列的 SQL 类型名称

        Connection con = dbUitl.getCon();
        String sql = "select * from t_book";
        PreparedStatement ps = con.prepareStatement(sql);
        ResultSetMetaData rsmd = ps.getMetaData();//获取结果集的元数据
        int num = rsmd.getColumnCount();//获取元数据的总列数
        for(int i=1;i<num;i++){
            System.out.println(rsmd.getColumnName(i)+","+rsmd.getColumnTypeName(i));//获取每列的列名以及列的sql类型
        }

事务:

事务处理在数据库开发中有着非常重要的作用,所谓事务就是所有的操作要么一起成功,要么一起失败,

事务 本身具有原子性(Atomicity)、一致性(Consistency)、隔离性或独立性(Isolation) 、持久性(Durability)4 个特 性,这 4 个特性也被称为 ACID 特征。

原子性:原子性是事务最小的单元,是不可再分隔的单元,相当于一个个小的数据库操作,这些操作必须同时 成功,如果一个失败了,则一切的操作将全部失败。

一致性:指的是在数据库操作的前后是完全一致的,保证数据的有效性,如果事务正常操作则系统会维持有效 性,如果事务出现了错误,则回到最原始状态,也要维持其有效性,这样保证事务开始时和结束时系统处于一 致状态。

隔离性:多个事务可以同时进行且彼此之间无法访问,只有当事务完成最终操作时,才可以看到结果;

持久性:事务完成之后,它对于系统的影响是永久性的。该修改即使出现致命的系统故障也将一直保持。

 

 

 private static DbUitl dbUitl = new DbUitl();
//转出
public static void outCount(Connection con,String accountName,int account) throws Exception{ String sql = "update t_account set accountBalance = accountBalance - ? where accountName = ?"; PreparedStatement ps = con.prepareStatement(sql); ps.setInt(1, account); ps.setString(2,accountName); ps.executeUpdate(); }
//转入
public static void inCount(Connection con,String accountName,int account) throws Exception{ String sql = "update t_account set accountBalance = accountBalance + ? where accountName = ?"; PreparedStatement ps = con.prepareStatement(sql); ps.setInt(1, account); ps.setString(2,accountName); ps.executeUpdate(); } public static void main(String[] args) { Connection con = null; try { con = dbUitl.getCon(); System.out.println("开始转账"); con.setAutoCommit(false);//取消自动提交 int account = 500; outCount(con, "张三", account); inCount(con, "李四", account); System.out.println("转账结束"); } catch (Exception e) { try { con.rollback();//事务回滚 } catch (SQLException e1) { e1.printStackTrace(); } e.printStackTrace(); }finally { try { con.commit();//事务提交 con.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } }

 

        Connection con = null;
        Savepoint sp = null;//保存点
        try
        {
            con = dbUitl.getCon();
            System.out.println("开始转账");
            con.setAutoCommit(false);//取消自动提交
            int account = 500;
            outCount(con, "张三", account);
            int i = 1/0;
            sp = con.setSavepoint();//设置保存点 
            inCount(con, "李四", account);
            System.out.println("转账结束");
        }
        catch (Exception e)
        {
            try
            {
                con.rollback(sp);//事务回滚   回滚到保存点   转出成功   转入不管
            }
            catch (SQLException e1)
            {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }finally {
            try
            {
                con.commit();//事务提交
                con.close();
            }
            catch (SQLException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
        

 

posted @ 2020-08-13 15:56  愚蠢的程序员  阅读(771)  评论(0编辑  收藏  举报