java--原生态数据库编程

来源:互联网 发布:苹果cms解析百度云 编辑:程序博客网 时间:2024/06/10 03:04

1.先用上代码

private static void jdbcTest() {// 准备链接对象Connection connection = null;// 准备预编译的sql语句对象PreparedStatement preparedStatement = null;// 准备结果接收对象ResultSet resultSet = null;try {//加载驱动类Class.forName("com.mysql.jdbc.Driver");//通过java规定的DriverManager获取链接对象connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/world?characterEncoding=utf8&useSSL=true", "root", "123456");//准备sql语句到预编译对象String sql = "select * from city where name=?";// 构建预编译对象preparedStatement = connection.prepareStatement(sql);// 设置预编译对象参数preparedStatement.setString(1, "Kabul");// 执行预编译对象得到结果对象(用于查询)resultSet = preparedStatement.executeQuery();// 执行预编译对象得到结果对象(用于DDL或者DML语句)//preparedStatement.executeUpdate();// 循环获取结果值while (resultSet.next()) {System.out.println(resultSet.getString("name") + " " + resultSet.getString("ID"));}} catch (Exception e) {e.printStackTrace();} finally {//资源释放if (resultSet != null) {try {resultSet.close();} catch (Exception e) {e.printStackTrace();}}if (preparedStatement != null) {try {preparedStatement.close();} catch (Exception e) {e.printStackTrace();}}if (connection != null) {try {connection.close();} catch (Exception e) {e.printStackTrace();}}}}



2.转载 别人写好的总结:http://www.cnblogs.com/moonpool/p/5559294.html

SQL语句主要分为五种:

1. 查询语句:主要由select关键字完成,查询语句是SQL语句中最复杂、功能最丰富的语句;

2. DML(Data Manipulation Language,数据操作语言):包含insert、update、delete

3. DDL(Data Definition Language, 数据定义语言):包含create、 alter、drop、truncate

4. DCL(Data Control Language,数据控制语言):包含grant 、revoke

5. 事务控制语句: commit、rollback、savepoint

 

JDBC编程步骤:

1. 加载数据库驱动。通过Class类的forName()静态方法来加载驱动

Class.forName(driverClass)

2. 通过DriverManager获取数据库连接Connection对象。

DriverManager.getConnection(String url,String user,String pass)

3. 通过Connection对象创建Statement对象。创建Statement有三种方法。

  • createStatement(): 创建基本的Statement对象
  • prepareStatement(String sql): 根据传入的SQL语句创建预编译的Statement对象
  • prepareCall(String sql): 根据传入的SQL语句创建CallableStatement对象。

4. 使用Statement执行SQL语句。

execute(): 可以执行任何SQL语句,但比较麻烦,在不清SQL语句类型时,只能使用这个方法。

executeUpdate():主要用于执行DML和DDL语句。执行DML语句返回受SQL语句影响的行数,执行DDL语句返回0。

executeQuery():只能执行查询语句,执行后返回代表查询结果的ResultSet对象。

5. 操作结果集。有两类方法来操作结果集:

  • next()、 previous()、 first()、 last()、 beforeFirst()、 afterLast()、 absolute()
  • getXxx()方法获取记录指针指向行、特定列的值。

6. 回收数据库资源,包括ResultSet、Statement和Connection等资源。

import java.sql.*;public class ConnMySql{    public static void main(String[] args) throws Exception    {        // 1.加载驱动,使用反射的知识,现在记住这么写。        Class.forName("com.mysql.jdbc.Driver");        try(            // 2.使用DriverManager获取数据库连接,            // 其中返回的Connection就代表了Java程序和数据库的连接            // 不同数据库的URL写法需要查驱动文档知道,用户名、密码由DBA分配            Connection conn = DriverManager.getConnection(                "jdbc:mysql://127.0.0.1:3306/select_test"                , "root" , "32147");            // 3.使用Connection来创建一个Statment对象            Statement stmt = conn.createStatement();            // 4.执行SQL语句            /*            Statement有三种执行sql语句的方法:execute 可执行任何SQL语句。- 返回一个boolean值,              如果执行后第一个结果是ResultSet,则返回true,否则返回falseexecuteQuery 执行Select语句 - 返回查询到的结果集executeUpdate 用于执行DML语句。- 返回一个整数,              代表被SQL语句影响的记录条数            */            ResultSet rs = stmt.executeQuery("select s.* , teacher_name"                + " from student_table s , teacher_table t"                + " where t.teacher_id = s.java_teacher"))//在try语句中,执行完后会自动关闭。        {            // ResultSet有系列的getXxx(列索引 | 列名),用于获取记录指针            // 指向行、特定列的值,不断地使用next()将记录指针下移一行,            // 如果移动之后记录指针依然指向有效行,则next()方法返回true。            while(rs.next())            {                System.out.println(rs.getInt(1) + "\t"                    + rs.getString(2) + "\t"                    + rs.getString(3) + "\t"                    + rs.getString(4));            }        }    }}

 执行DDL语句的例子:

import java.util.*;import java.io.*;import java.sql.*;public class ExecuteDDL{    private String driver;    private String url;    private String user;    private String pass;    public void initParam(String paramFile)        throws Exception    {        // 使用Properties类来加载属性文件        Properties props = new Properties();        props.load(new FileInputStream(paramFile));        driver = props.getProperty("driver");        url = props.getProperty("url");        user = props.getProperty("user");        pass = props.getProperty("pass");    }    public void createTable(String sql)throws Exception //注意这个返回值类型    {        // 加载驱动        Class.forName(driver);        try(        // 获取数据库连接        Connection conn = DriverManager.getConnection(url , user , pass);        // 使用Connection来创建一个Statment对象        Statement stmt = conn.createStatement())        {            // 执行DDL,创建数据表            stmt.executeUpdate(sql);        }    }    public static void main(String[] args) throws Exception    {        ExecuteDDL ed = new ExecuteDDL();        ed.initParam("mysql.ini");        ed.createTable("create table jdbc_test "            + "( jdbc_id int auto_increment primary key, "            + "jdbc_name varchar(255), "            + "jdbc_desc text);");        System.out.println("-----建表成功-----");    }}

执行DML语句的例子 :

import java.util.*;import java.io.*;import java.sql.*;public class ExecuteDML{    private String driver;    private String url;    private String user;    private String pass;    public void initParam(String paramFile)        throws Exception    {        // 使用Properties类来加载属性文件        Properties props = new Properties();        props.load(new FileInputStream(paramFile));        driver = props.getProperty("driver");        url = props.getProperty("url");        user = props.getProperty("user");        pass = props.getProperty("pass");    }    public int insertData(String sql)throws Exception//注意这里的返回值类型    {        // 加载驱动        Class.forName(driver);        try(            // 获取数据库连接            Connection conn = DriverManager.getConnection(url                , user , pass);            // 使用Connection来创建一个Statment对象            Statement stmt = conn.createStatement())        {            // 执行DML,返回受影响的记录条数            return stmt.executeUpdate(sql);        }    }    public static void main(String[] args)throws Exception    {        ExecuteDML ed = new ExecuteDML();        ed.initParam("mysql.ini");        int result = ed.insertData("insert into jdbc_test(jdbc_name,jdbc_desc)"            + "select s.student_name , t.teacher_name "            + "from student_table s , teacher_table t "            + "where s.java_teacher = t.teacher_id;");        System.out.println("--系统中共有" + result + "条记录受影响--");    }}
当不清楚SQL语句类型时的例子:
import java.io.*;import java.sql.*;public class ExecuteSQL{    private String driver;    private String url;    private String user;    private String pass;    public void initParam(String paramFile)throws Exception    {        // 使用Properties类来加载属性文件        Properties props = new Properties();        props.load(new FileInputStream(paramFile));        driver = props.getProperty("driver");        url = props.getProperty("url");        user = props.getProperty("user");        pass = props.getProperty("pass");    }    public void executeSql(String sql)throws Exception    {        // 加载驱动        Class.forName(driver);        try(            // 获取数据库连接            Connection conn = DriverManager.getConnection(url                , user , pass);            // 使用Connection来创建一个Statement对象            Statement stmt = conn.createStatement())        {            // 执行SQL,返回boolean值表示是否包含ResultSet            boolean hasResultSet = stmt.execute(sql);            // 如果执行后有ResultSet结果集            if (hasResultSet)            {                try(                    // 获取结果集                    ResultSet rs = stmt.getResultSet())                {                    // ResultSetMetaData是用于分析结果集的元数据接口                    ResultSetMetaData rsmd = rs.getMetaData();                    int columnCount = rsmd.getColumnCount();                    // 迭代输出ResultSet对象                    while (rs.next())                    {                        // 依次输出每列的值                        for (int i = 0 ; i < columnCount ; i++ )                        {                            System.out.print(rs.getString(i + 1) + "\t");                        }                        System.out.print("\n");                    }                }            }            else            {                System.out.println("该SQL语句影响的记录有"                    + stmt.getUpdateCount() + "条");            }        }    }    public static void main(String[] args) throws Exception    {        ExecuteSQL es = new ExecuteSQL();        es.initParam("mysql.ini");        System.out.println("------执行删除表的DDL语句-----");        es.executeSql("drop table if exists my_test");        System.out.println("------执行建表的DDL语句-----");        es.executeSql("create table my_test"            + "(test_id int auto_increment primary key, "            + "test_name varchar(255))");        System.out.println("------执行插入数据的DML语句-----");        es.executeSql("insert into my_test(test_name) "            + "select student_name from student_table");        System.out.println("------执行查询数据的查询语句-----");        es.executeSql("select * from my_test");    }}
使用PreparedStatement执行SQL语句的例子(使用这种方法,可以防止SQL注入,比如在登录框中输入‘or true or’)
import java.util.*;import java.io.*;import java.sql.*;public class PreparedStatementTest{    private String driver;    private String url;    private String user;    private String pass;    public void initParam(String paramFile)throws Exception    {        // 使用Properties类来加载属性文件        Properties props = new Properties();        props.load(new FileInputStream(paramFile));        driver = props.getProperty("driver");        url = props.getProperty("url");        user = props.getProperty("user");        pass = props.getProperty("pass");        // 加载驱动        Class.forName(driver);    }    public void insertUseStatement()throws Exception    {        long start = System.currentTimeMillis();        try(            // 获取数据库连接            Connection conn = DriverManager.getConnection(url                , user , pass);            // 使用Connection来创建一个Statment对象            Statement stmt = conn.createStatement())        {            // 需要使用100条SQL语句来插入100条记录            for (int i = 0; i < 100 ; i++ )            {                stmt.executeUpdate("insert into student_table values("                    + " null ,'姓名" + i + "' , 1)");            }            System.out.println("使用Statement费时:"                + (System.currentTimeMillis() - start));        }    }    public void insertUsePrepare()throws Exception    {        long start = System.currentTimeMillis();        try(            // 获取数据库连接            Connection conn = DriverManager.getConnection(url                , user , pass);            // 使用Connection来创建一个PreparedStatement对象            PreparedStatement pstmt = conn.prepareStatement(                "insert into student_table values(null,?,1)"))        {            // 100次为PreparedStatement的参数设值,就可以插入100条记录            for (int i = 0; i < 100 ; i++ )            {                pstmt.setString(1 , "姓名" + i);                pstmt.executeUpdate();            }            System.out.println("使用PreparedStatement费时:"                + (System.currentTimeMillis() - start));        }    }    public static void main(String[] args) throws Exception    {        PreparedStatementTest pt = new PreparedStatementTest();        pt.initParam("mysql.ini");        pt.insertUseStatement();        pt.insertUsePrepare();    }}
使用CallableStatement调用存储过程的例子

import java.awt.*;import java.awt.event.*;import javax.swing.*;import java.util.*;import java.io.*;import java.sql.*;public class CallableStatementTest{    private String driver;    private String url;    private String user;    private String pass;    public void initParam(String paramFile)throws Exception    {        // 使用Properties类来加载属性文件        Properties props = new Properties();        props.load(new FileInputStream(paramFile));        driver = props.getProperty("driver");        url = props.getProperty("url");        user = props.getProperty("user");        pass = props.getProperty("pass");    }    public void callProcedure()throws Exception    {        // 加载驱动        Class.forName(driver);        try(            // 获取数据库连接            Connection conn = DriverManager.getConnection(url                , user , pass);            // 使用Connection来创建一个CallableStatment对象            CallableStatement cstmt = conn.prepareCall(                "{call add_pro(?,?,?)}"))        {            cstmt.setInt(1, 4);            cstmt.setInt(2, 5);            // 注册CallableStatement的第三个参数是int类型            cstmt.registerOutParameter(3, Types.INTEGER);            // 执行存储过程            cstmt.execute();            // 获取,并输出存储过程传出参数的值。            System.out.println("执行结果是: " + cstmt.getInt(3));        }    }    public static void main(String[] args) throws Exception    {        CallableStatementTest ct = new CallableStatementTest();        ct.initParam("mysql.ini");        ct.callProcedure();    }}


管理结果集:


可滚动、可更新的结果集

需要在创建Statement或者PrepareStatement时传入额外的参数,如下面例子:



import java.util.*;import java.io.*;import java.sql.*;public class ResultSetTest{    private String driver;    private String url;    private String user;    private String pass;    public void initParam(String paramFile)throws Exception    {        // 使用Properties类来加载属性文件        Properties props = new Properties();        props.load(new FileInputStream(paramFile));        driver = props.getProperty("driver");        url = props.getProperty("url");        user = props.getProperty("user");        pass = props.getProperty("pass");    }    public void query(String sql)throws Exception    {        // 加载驱动        Class.forName(driver);        try(            // 获取数据库连接            Connection conn = DriverManager.getConnection(url , user , pass);            // 使用Connection来创建一个PreparedStatement对象            // 传入控制结果集可滚动,可更新的参数。            PreparedStatement pstmt = conn.prepareStatement(sql                , ResultSet.TYPE_SCROLL_INSENSITIVE                , ResultSet.CONCUR_UPDATABLE);            ResultSet rs = pstmt.executeQuery())        {            rs.last();            int rowCount = rs.getRow();            for (int i = rowCount; i > 0 ; i-- )            {                rs.absolute(i);                System.out.println(rs.getString(1) + "\t"                    + rs.getString(2) + "\t" + rs.getString(3));                // 修改记录指针所有记录、第2列的值                rs.updateString(2 , "学生名" + i);                // 提交修改                rs.updateRow();            }        }    }    public static void main(String[] args) throws Exception    {        ResultSetTest rt = new ResultSetTest();        rt.initParam("mysql.ini");        rt.query("select * from student_table");    }}



处理Blob类型数据

Blob(Binary Long object)是二进制长对象的意思。使用该类可以吧图片、声音等文件的二进制数据保存在数据库中,并可以从数据库中恢复指定文件。

通过PrepareStatement的setBinaryStream(int parameterIndex,InputStream x),该方法可以指定参数传入二进制流。

如果需要从ResultSet中取出Blob数据,可以调用ResultSet的getBlob(int columnIndex)来返回一个Blob对象,然后再通过Blob对象的getBinaryStream()方法获取该Blob数据的输入流,也可以使用Blob对象的getBytes()方法直接读取该Blob对象封装的二进制数据。

 

使用ResultSetMetaData分析结果集:

 

该对象可以通过ResultSet的getMetaData()方法来放回。常用的方法有:

  • int getColumnCount():返回该ResultSet的列数量
  • String getColumnName(int column):返回指定索引的列名
  • int getColumnType(int column):返回指定索引的列类型

事务处理

 事务是由一步或几步数据库操作序列组成的逻辑执行单元,这系列操作要么全部执行,要么全部放弃执行。

事务有四个特性:原子性、一致性、隔离性、持续性。

 

数据库事务由下列语句组成。

一组DML语句,一条DDL语句,一条DCL语句。DDL和DCL语句最多只能有一条,因为DDL和DCL语句都会导致事务立即提交。

 

事务提交方式(没有提交前事务中的语句不会生效)

1.显式提交:使用commit

2.自动提交:执行DDL或DCL语句,或者程序正常退出。 

事务回滚方式:(没有生效的事务可以回滚)

1.显式回滚:使用rollback

2.自动回滚:系统错误或者强行退出 

自动提交和开始事务是对立的,开始事务功能后,就会将自动提交的功能关闭。正常情况下需要手动关闭自动提交。 

JDBC对事务的支持

可以调用Connection的setAutoCommit()方法来关闭自动提交,开启事务。getAutoCommit()返回自动提交模式。commit()提交事务。rollback()回滚事务。

例子:


import java.sql.*;import java.io.*;import java.util.*;public class TransactionTest{    private String driver;    private String url;    private String user;    private String pass;    public void initParam(String paramFile)throws Exception    {        // 使用Properties类来加载属性文件        Properties props = new Properties();        props.load(new FileInputStream(paramFile));        driver = props.getProperty("driver");        url = props.getProperty("url");        user = props.getProperty("user");        pass = props.getProperty("pass");    }    public void insertInTransaction(String[] sqls) throws Exception    {        // 加载驱动        Class.forName(driver);        try(            Connection conn = DriverManager.getConnection(url , user , pass))        {            // 关闭自动提交,开启事务            conn.setAutoCommit(false);            try(                // 使用Connection来创建一个Statment对象                Statement stmt = conn.createStatement())            {                // 循环多次执行SQL语句                for (String sql : sqls)                {                    stmt.executeUpdate(sql);                }            }            // 提交事务            conn.commit();        }    }    public static void main(String[] args) throws Exception    {        TransactionTest tt = new TransactionTest();        tt.initParam("mysql.ini");        String[] sqls = new String[]{            "insert into student_table values(null , 'aaa' ,1)",            "insert into student_table values(null , 'bbb' ,1)",            "insert into student_table values(null , 'ccc' ,1)",            // 下面这条SQL语句将会违反外键约束,            // 因为teacher_table中没有ID为5的记录。            "insert into student_table values(null , 'ccc' ,5)" //①        };        tt.insertInTransaction(sqls);    }}



使用DatabaseMetaData分析数据库信息

通过Connection提供的getMetaData()方法获取DatabaseMetaData对象。许多DatabaseMetaData方法是以ResultSet对象的形式返回查询信息,然后使用ResultSet中的常规方法获取内容。如果没有内容就返回一个空的ResultSet对象。

DatabaseMetaData的许多方法都需要传入一个xxxPattern模式字符串,这里的xxxPattern不是正则表达式,而是SQL里的模式字符串。

即用百分号(%)代表任意多个字符,使用下划线(_)代表一个字符。通常情况下,如果把该模式字符串的参数值设置为null,即表明该参数不过为过滤条件。

例子:


import java.sql.*;import java.util.*;import java.io.*;public class DatabaseMetaDataTest{    private String driver;    private String url;    private String user;    private String pass;    public void initParam(String paramFile)throws Exception    {        // 使用Properties类来加载属性文件        Properties props = new Properties();        props.load(new FileInputStream(paramFile));        driver = props.getProperty("driver");        url = props.getProperty("url");        user = props.getProperty("user");        pass = props.getProperty("pass");    }    public void info() throws Exception    {        // 加载驱动        Class.forName(driver);        try(            // 获取数据库连接            Connection conn = DriverManager.getConnection(url                , user , pass))        {            // 获取的DatabaseMetaData对象            DatabaseMetaData dbmd = conn.getMetaData();            // 获取MySQL支持的所有表类型            ResultSet rs = dbmd.getTableTypes();            System.out.println("--MySQL支持的表类型信息--");            printResultSet(rs);            // 获取当前数据库的全部数据表            rs = dbmd.getTables(null,null, "%" , new String[]{"TABLE"});            System.out.println("--当前数据库里的数据表信息--");            printResultSet(rs);            // 获取student_table表的主键            rs = dbmd.getPrimaryKeys(null , null, "student_table");            System.out.println("--student_table表的主键信息--");            printResultSet(rs);            // 获取当前数据库的全部存储过程            rs = dbmd.getProcedures(null , null, "%");            System.out.println("--当前数据库里的存储过程信息--");            printResultSet(rs);            // 获取teacher_table表和student_table之间的外键约束            rs = dbmd.getCrossReference(null,null, "teacher_table"                , null, null, "student_table");            System.out.println("--teacher_table表和student_table之间"                + "的外键约束--");            printResultSet(rs);            // 获取student_table表的全部数据列            rs = dbmd.getColumns(null, null, "student_table", "%");            System.out.println("--student_table表的全部数据列--");            printResultSet(rs);        }    }    public void printResultSet(ResultSet rs)throws SQLException    {        ResultSetMetaData rsmd = rs.getMetaData();        // 打印ResultSet的所有列标题        for (int i = 0 ; i < rsmd.getColumnCount() ; i++ )        {            System.out.print(rsmd.getColumnName(i + 1) + "\t");        }        System.out.print("\n");        // 打印ResultSet里的全部数据        while (rs.next())        {            for (int i = 0; i < rsmd.getColumnCount() ; i++ )            {                System.out.print(rs.getString(i + 1) + "\t");            }            System.out.print("\n");        }        rs.close();    }    public static void main(String[] args)        throws Exception    {        DatabaseMetaDataTest dt = new DatabaseMetaDataTest();        dt.initParam("mysql.ini");        dt.info();    }}







原创粉丝点击