Java 面试随笔(4)

java中操作数据库中的几个重要类

DriverManager类

DriverManager类处理驱动程序的加载和建立新数据库连接。DriverManager是java.sql包中用于管理数据库驱动程序的类

通常,应用程序只使用类DriverManager的getConnection()静态方法,用来建立与数据库的连接,返回Connection对象:

static Connection getConnection(String url,String username,String password)

指定数据的URL用户名和密码创建数据库连接对象。url的语法格式是:
jdbc:<数据库的连接机制>:<ODBC数据库名>

Connection类

Connection类是java.sql包中用于处理与特定数据库连接的类。Connection对象是用来表示数据库连接的对象,Java程序对数据库的操作都在这种对象上进行。

Connection类的主要方法有:

1.Statement createStatement():创建一个Statement对象
2.PreparedStatement prepareStatement(String sql) :创建一个PreparedStatement 对象来将参数化的 SQL 语句发送到数据库
3.Statement createStatement(int resultSetType,int resultSetConcurrency):创建一个Statement对象,生成具有特定类型的结果集
4.void commit():提交对数据库的改动并释放当前持有的数据库的锁
5.void rollback():回滚当前事务中的所有改动并释放当前连接持有的数据库的锁
6.String getCatalog():获得连接对象的当前目录
7.boolean isClose():判断连接是否已关闭
8.boolean isReadOnly():判断连接是否为只读模式
9.void setReadOnly():设置连接为只读模式
10.void close():释放连接对象的数据库和JDBC资源

Statement类

Statement类是java.sql包中用于在指定的连接中处理SQL语句的类。数据库编程的要点是在程序中嵌入SQL命令。
程序需要声明和创建连接数据库的Connection对象,并让该对象连接数据库。调用类DriverManager的静态方法getConnection()获得Connection对象,实现程序与数据库的连。然后,用Statement类声明SQL语句对象,并调用Connection对象的createStatement()方法,创建SQL语句对象。

以下代码创建语句对象sql:

Statement sql = null;
try{
sql = con.createStatement();
}catch(SQLException e){}

ResultSet类

有了SQL语句对象后,调用语句对象的方法executeQuery()执行SQL查询,并将查询结果存放在一个用ResultSet类声明的对象中。

ResultSet rs = sql.executeQuery(“SELECT * FROM ksInfo”);

ResultSet对象实际上是一个由查询结果数据的表,是一个管式数据集,由统一形式的数据行组成,一行对应一条查询记录。在ResultSet对象中隐含着一个游标,一次只能获得游标当前所指的数据行,用next方法可取下一个数据行。用数据行的字段(列)名称或位置索引(自1开始)调用形如getXXX()方法获得记录的字段植 。

1.byte getByte(int columnIndex):返回指定字段的字节值。
2.Date getDate(int columnIndex):返回指定字段的日期值。
3.float getFloat(int columnIndex):返回指定字段的浮点值。
4.int getInt(int columnIndex):返回指定字段的整数值。
5.String getString(int columnIndex):返回指定字段的字符串值。
6.double getDouble(String columnName):返回指定字段的双精度值。
7.long getLong(String columnName):返回指定字段的long型整值。
8.boolean next():返回是否还有下一字段。
以上方法中的columnIndex是位置索引,用于指定字段,columnName是字段名

用户需要在查询结果集上浏览,或前后移动、或显示结果集的指定记录,这称为可滚动结果集。程序要获得一个可滚动结果集,只要在获得SQL的语句对象时,增加指定结果集的两个参数即可。

以下代码:
Statement stmt = con.createStatement(type,concurrency);
ResultSet rs = stmt.executeQuery(SQL语句)

语句对象stmt的SQL查询就能得到相应类型的结果集:

  • int 型参数type决定可滚动集的滚动方式:

ResultSet.TYPE_FORWORD_ONLY,结果集的游标只能向下滚动。
ResultSet.TYPE_SCROLL_INSENSITIVE,游标可上下移动,当数据库变化时,当前结果集不变。
ResultSet. TYPE_SCROLL_SENSITIVE,游标可上下移动,当数据库变化时,当前结果集同步改变。

  • int 型参数concurrency决定数据库是否与可滚动集同步更新:

ResultSet.CONCUR_READ_ONLY,不能用结果集更新数据库中的表。
ResultSet.CONCUR_UPDATETABLE,能用结果集更新数据库中的表。

例如,以下代码利用连接对象connect,创建Statement对象stmt,指定结果集可滚动,并以只读方式读数据库:

stmt = connect.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);

可滚动集上另外一些常用的方法如下:

1.boolean previous():将游标向上移动,当移到结果集的第一行时,返回false。
2.void beforeFirst():将游标移结果集的第一行之前。
3.void afterLast():将游标移到结果集的最后一行之后。
4.void first():将游标移到第一行。
5.void last():将游标移到最后一行。
6.boolean isAfterLast():判游标是否在最后一行之后。
7.boolean isBeforeFirst():判游标是否在第一行之前。
8.boolean isLast():判游标是否在最后一行。
9.boolean isFirst():判游标是否在第一行。
10.int getRow():获取当前所指的行(行号自1开始编号,结果集空,返回0)。
11.boolean absolute(int row):将游标移到row行。

ResultSetMetaData

可用于获取关于 ResultSet 对象中列的类型和属性信息的对象。以下代码片段创建 ResultSet 对象 rs,创建 ResultSetMetaData 对象 rsmd,并使用 rsmd 查找 rs 有多少列,以及 rs 中的第一列是否可以在 WHERE 子句中使用

ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM TABLE2");
ResultSetMetaData rsmd = rs.getMetaData();
int numberOfColumns = rsmd.getColumnCount();
boolean b = rsmd.isSearchable(1);

连接数据库操作如下:

//连接数据库配置类
public class Configure {
    // user name
    public final static String USERNAME = "root";
    // password
    public final static String PASSWORD = "password";
    // your database name
    public final static String DBNAME   = "DBGHZ";
    // mysql driver
    public final static String DRIVER   = "com.mysql.jdbc.Driver";
    // mysql url
    public final static String URL      = "jdbc:mysql://localhost:3306/" + DBNAME;
    // must bigger than the number of the keyword in your database table 
    public final static int    TABLELEN = 10;
}
//具体操作实现类
public class MysqlConnecter {
    //处理与特定数据库连接的类
    private Connection connection = null;
    private boolean connected = false;

    public MysqlConnecter() {
        try {
            Class.forName(Configure.DRIVER);
        } catch (ClassNotFoundException e) {
            System.out.println("ERROR AT MysqlConnecter");
            e.printStackTrace();
        }
        try {
            connection = DriverManager.getConnection(Configure.URL, Configure.USERNAME, Configure.PASSWORD);
            connected = true;
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public int insert(String sql)  
    {  
        int lineNum = 0;
        if (!connected) return 0;
        try{  
            PreparedStatement preStmt = connection.prepareStatement(sql);    
            lineNum = preStmt.executeUpdate();  
        }  
        catch (SQLException e)  
        {  
            e.printStackTrace();  
        }  
        return lineNum; 
    }

    public int update(String sql)
    {  
        int lineNum = 0;
        if (!connected) return 0;
        try{  
            PreparedStatement preStmt = connection.prepareStatement(sql);   
            lineNum = preStmt.executeUpdate();  
        }  
        catch (SQLException e)  
        {  
            e.printStackTrace();  
        }  
        return lineNum;
    }  
    public ArrayList<Map<String, String>> select(String sql, String tableName)
    {   
        ArrayList<Map<String, String>> result = new ArrayList<>();

        try  
        {  
            Statement stmt = connection.createStatement();  
            ResultSet rs = stmt.executeQuery(sql);
            String[] frame = getFrame(tableName);
            while (rs.next())  
            {  
                Map<String, String> tmp = new HashMap<>();
                for (String key : frame) {
                    if (key == "#") break;
                    tmp.put(key, rs.getString(key));
                }
                result.add(tmp);
            }   
        }  
        catch (SQLException e)  
        {  
            e.printStackTrace();  
        }  
        return result;  
    }
    public int delete(String sql)  
    {   
        int lineNum = 0;    
        try  
        {  
            Statement stmt = connection.createStatement();  
            lineNum = stmt.executeUpdate(sql);  
        }  
        catch (SQLException e)  
        {  
            e.printStackTrace();  
        }  
        return lineNum;  
    }  
    // 获取当前表的关键字,并以字符串数组的形式返回:如“username”,“id“等
    private String[] getFrame(String tableName) {
        String[] result = new String[Configure.TABLELEN];
         try  
            {  
                Statement stmt = connection.createStatement();  
                ResultSet rs = stmt.executeQuery("show columns from " + tableName);
                int i = 0;
                while (rs.next())  
                {  
                    result[i++] = rs.getString(1);
                }
                result[i] = "#";
            }  
            catch (SQLException e)  
            {  
                e.printStackTrace();  
            }  
        return result;
    }
}
//测试
public class Test {
    public static void main(String[] args) {
        MysqlConnecter mc = new MysqlConnecter();
        // insert
        mc.update("insert into User values(3, \"xiaoshitouer\", \"xiaoshitouer@gmail.com\", \"123\", 20160930)");
        // update
        System.out.println(mc.update("update User set passwd=\"liuxiaoliu\" where userid=2"));
        // delete
        System.out.println(mc.delete("delete from User where userid=3"));
        // select
        ArrayList<Map<String, String>> result = mc.select("select * from User", "User");
        // map的遍历方法
        for (Map<String, String> map : result) {
            System.out.println("______________________");
            for (Map.Entry<String, String> entry : map.entrySet()) {
                System.out.println(entry.getKey() + "--->" + entry.getValue());
            }
        }
    }
}