Android之jdbc的学习

Posted 西西弗斯丶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android之jdbc的学习相关的知识,希望对你有一定的参考价值。

1.什么是jdbc:
根据Sun的声明,JDBC是一个商标的术语,并非Java DataBase Connectivity。但将其当成Java DataBase Connectivity更容易理解。jdbc是java程序访问数据库的一套接口,它结合了SQL语句。因为市场上有多种数据库,他们的访问协议不同,因此数据访问方式不同。针对于这种情况,java提供了驱动管理器与数据库驱动的概念,访问方式有数据库驱动提供,是具体的数据库厂商写的。而java程序需要哪种方式访问数据库,只需要将这种数据库的驱动注册到驱动管理器就ok了(这样java程序才知道以何种方式访问数据库)。
2.jdbc的操作步骤
(1)注册jdbc驱动:向java驱动管理器注册使用的数据库驱动。
(2)连接数据库:建立通信,先接通才能操作数据库。
(3)操作数据库:增,删,改,查等。
(4)关闭数据库。
mysql为例:
1.先要下载mysql数据库的驱动:
http://pan.baidu.com/share/link?shareid=1725761810&uk=3056808396
将其加载到编写的java工程中,刚测试了下载android无法使用jdbc访问数据,报一大堆错误,看stackoverflow上说建议使用webservice访问数据库。


2.编写代码:
(1)注册jdbc驱动

// 向驱动管理器注册一个jdbc驱动
            Class.forName(driver).newInstance();
            System.out.println("驱动注册成功");

(2)连接数据库:建立通信,先接通才能操作数据库。
conn = DriverManager.getConnection(url, username, password);
            System.out.println("获取链接成功");

(3)操作数据库:增,删,改,查等。
//实现增删改
public boolean updateDB(String sql, List<Object> params)
    
        boolean retFlag = false;
        try
        
            pstm = conn.prepareStatement(sql);
            // notice:if(params !=null && !params.equals(""))这个要加上,避免params为空
            if (params != null && !params.equals(""))
            
                for (int i = 0; i < params.size(); i++)
                
                    pstm.setObject(i + 1, params.get(i));
                
            
            return pstm.executeUpdate() > 0 ? true : false;
        
        catch (SQLException e)
        
            e.printStackTrace();
        
        
        return retFlag;
    
    //实现查询
    public Map<String, Object> QueryDB(String sql, List<Object> params)
    
        Map<String, Object> map = null;
        try
        
            pstm = conn.prepareStatement(sql);
            if (params != null && !params.equals(""))
            
                for (int i = 0; i < params.size(); i++)
                
                    pstm.setObject(i + 1, params.get(i));
                
            
            rs = pstm.executeQuery();
            ResultSetMetaData rsMetaData = rs.getMetaData();
            while (rs.next())
            
                map = new HashMap<String, Object>();
                for (int i = 0; i < rsMetaData.getColumnCount(); i++)
                
                    String columnName = rsMetaData.getColumnName(i + 1);
                    Object columnVal = rs.getObject(i + 1);
                    // 数据库中的值可能为空
                    if (columnVal == null)
                    
                        columnVal = "";
                    
                    map.put(columnName, columnVal);
                
                
            
        
        catch (SQLException e)
        
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        
        return map;
        
    
    
    // 这个完全可以代替单个查询
    public List<Map<String, Object>> QueryMoreDB(String sql, List<Object> params)
    
        List<Map<String, Object>> retList = new ArrayList<Map<String, Object>>();
        try
        
            pstm = conn.prepareStatement(sql);
            if (params != null && !params.equals(""))
            
                for (int i = 0; i < params.size(); i++)
                
                    pstm.setObject(i + 1, params.get(i));
                
            
            
            ResultSet rs = pstm.executeQuery();
            ResultSetMetaData rsMetaData = rs.getMetaData();
            while (rs.next())
            
                Map<String, Object> map = new HashMap<String, Object>();
                for (int i = 0; i < rsMetaData.getColumnCount(); i++)
                
                    String columnName = rsMetaData.getColumnName(i + 1);
                    Object columnVal = rs.getObject(i + 1);
                    if (columnVal == null)
                    
                        columnVal = "";
                    
                    map.put(columnName, columnVal);
                
                retList.add(map);
            
        
        catch (SQLException e)
        
            e.printStackTrace();
        
        return retList;
    
    
    // 利用反射机制实现数据库的操作
    public <T> T QueryDBObj(String sql, List<Object> params, Class<T> cls)
    
        T t = null;
        try
        
            pstm = conn.prepareStatement(sql);
            if (params != null && !params.equals(""))
            
                for (int i = 0; i < params.size(); i++)
                
                    pstm.setObject(i + 1, params.get(i));
                
            
            rs = pstm.executeQuery();
            ResultSetMetaData rsMetaData = rs.getMetaData();
            while (rs.next())
            
                t = cls.newInstance();
                for (int i = 0; i < rsMetaData.getColumnCount(); i++)
                
                    String columnName = rsMetaData.getColumnName(i + 1);
                    Object columnVal = rs.getObject(i + 1);
                    // 这个field是类加载器级别的,用于管理其类的属性
                    Field field = cls.getDeclaredField(columnName);
                    
                    field.setAccessible(true);
                    field.set(t, columnVal);
                
            
            return t;
        
        catch (SQLException e)
        
            e.printStackTrace();
        
        catch (InstantiationException e)
        
            e.printStackTrace();
        
        catch (IllegalAccessException e)
        
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        catch (SecurityException e)
        
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        catch (NoSuchFieldException e)
        
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        
        return t;
    
    
    // 利用反射机制实现数据库的操作,知道其cls的结构
    public <T> List<T> QueryDBMoreObj(String sql, List<Object> params, Class<T> cls)
    
        List<T> rstList = new ArrayList<T>();
        try
        
            pstm = conn.prepareStatement(sql);
            if (params != null && !params.equals(""))
            
                for (int i = 0; i < params.size(); i++)
                
                    pstm.setObject(i + 1, params.get(i));
                
            
            rs = pstm.executeQuery();
            ResultSetMetaData rsMetaData = rs.getMetaData();
            while (rs.next())
            
                T t = cls.newInstance();
                for (int i = 0; i < rsMetaData.getColumnCount(); i++)
                
                    String columnName = rsMetaData.getColumnName(i + 1);
                    Object columnVal = rs.getObject(i + 1);
                    // 这个field是类加载器级别的,用于管理其类的属性
                    Field field = cls.getDeclaredField(columnName);
                    // 应用Fied
                    field.setAccessible(true);
                    field.set(t, columnVal);
                
                rstList.add(t);
            
            return rstList;
        
        catch (SQLException e)
        
            e.printStackTrace();
        
        catch (InstantiationException e)
        
            e.printStackTrace();
        
        catch (IllegalAccessException e)
        
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        catch (SecurityException e)
        
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        catch (NoSuchFieldException e)
        
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        
        return rstList;
    
    

4.关闭数据库
public void releaseJdbc()
    
        
        try
        
            // 后生成的先释放掉
            if (rs != null)
            
                rs.close();
            
            if (pstm != null)
            
                pstm.close();
            
            if (conn != null)
            
                conn.close();
            
        
        catch (SQLException e)
        
            e.printStackTrace();
        
        
    

完整源码:
jdbcUtil.java
package utl;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class jdbcUtil

    private String url = "jdbc:mysql://localhost:3306/moondatabase";
    
    private String username = "root";
    
    private String password = "byd";
    
    private String driver = "com.mysql.jdbc.Driver";
    
    private String driver1 = "org.gjt.mm.mysql.Driver";
    
    // 预定义声明对象,用于操作数据库
    PreparedStatement pstm;
    
    // java程序与数据库建立的链接
    Connection conn;
    
    // 查询数据库返回的对象
    ResultSet rs;
    
    public jdbcUtil(String url, String username, String password)
    
        super();
        this.url = url;
        this.username = username;
        this.password = password;
        try
        
            // 向驱动管理器注册一个jdbc驱动
            Class.forName(driver).newInstance();
            System.out.println("驱动注册成功");
        
        catch (ClassNotFoundException e)
        
            e.printStackTrace();
        
        catch (InstantiationException e)
        
            e.printStackTrace();
        
        catch (IllegalAccessException e)
        
            // TODO Auto-generated catch block
            e.printStackTrace();
        
    
    
    public jdbcUtil()
    
        try
        
            // 向驱动管理器注册一个jdbc驱动
            Class.forName(driver1);
            System.out.println("驱动注册成功");
        
        catch (ClassNotFoundException e)
        
            e.printStackTrace();
        
    
    
    public void getConnection()
    
        try
        
            conn = DriverManager.getConnection(url, username, password);
            System.out.println("获取链接成功");
        
        catch (SQLException e)
        
            e.printStackTrace();
        
    
    
    public boolean updateDB(String sql, List<Object> params)
    
        boolean retFlag = false;
        try
        
            pstm = conn.prepareStatement(sql);
            // notice:if(params !=null && !params.equals(""))这个要加上,避免params为空
            if (params != null && !params.equals(""))
            
                for (int i = 0; i < params.size(); i++)
                
                    pstm.setObject(i + 1, params.get(i));
                
            
            return pstm.executeUpdate() > 0 ? true : false;
        
        catch (SQLException e)
        
            e.printStackTrace();
        
        
        return retFlag;
    
    
    public Map<String, Object> QueryDB(String sql, List<Object> params)
    
        Map<String, Object> map = null;
        try
        
            pstm = conn.prepareStatement(sql);
            if (params != null && !params.equals(""))
            
                for (int i = 0; i < params.size(); i++)
                
                    pstm.setObject(i + 1, params.get(i));
                
            
            rs = pstm.executeQuery();
            ResultSetMetaData rsMetaData = rs.getMetaData();
            while (rs.next())
            
                map = new HashMap<String, Object>();
                for (int i = 0; i < rsMetaData.getColumnCount(); i++)
                
                    String columnName = rsMetaData.getColumnName(i + 1);
                    Object columnVal = rs.getObject(i + 1);
                    // 数据库中的值可能为空
                    if (columnVal == null)
                    
                        columnVal = "";
                    
                    map.put(columnName, columnVal);
                
                
            
        
        catch (SQLException e)
        
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        
        return map;
        
    
    
    // 这个完全可以代替单个查询
    public List<Map<String, Object>> QueryMoreDB(String sql, List<Object> params)
    
        List<Map<String, Object>> retList = new ArrayList<Map<String, Object>>();
        try
        
            pstm = conn.prepareStatement(sql);
            if (params != null && !params.equals(""))
            
                for (int i = 0; i < params.size(); i++)
                
                    pstm.setObject(i + 1, params.get(i));
                
            
            
            ResultSet rs = pstm.executeQuery();
            ResultSetMetaData rsMetaData = rs.getMetaData();
            while (rs.next())
            
                Map<String, Object> map = new HashMap<String, Object>();
                for (int i = 0; i < rsMetaData.getColumnCount(); i++)
                
                    String columnName = rsMetaData.getColumnName(i + 1);
                    Object columnVal = rs.getObject(i + 1);
                    if (columnVal == null)
                    
                        columnVal = "";
                    
                    map.put(columnName, columnVal);
                
                retList.add(map);
            
        
        catch (SQLException e)
        
            e.printStackTrace();
        
        return retList;
    
    
    // 利用反射机制实现数据库的操作
    public <T> T QueryDBObj(String sql, List<Object> params, Class<T> cls)
    
        T t = null;
        try
        
            pstm = conn.prepareStatement(sql);
            if (params != null && !params.equals(""))
            
                for (int i = 0; i < params.size(); i++)
                
                    pstm.setObject(i + 1, params.get(i));
                
            
            rs = pstm.executeQuery();
            ResultSetMetaData rsMetaData = rs.getMetaData();
            while (rs.next())
            
                t = cls.newInstance();
                for (int i = 0; i < rsMetaData.getColumnCount(); i++)
                
                    String columnName = rsMetaData.getColumnName(i + 1);
                    Object columnVal = rs.getObject(i + 1);
                    // 这个field是类加载器级别的,用于管理其类的属性
                    Field field = cls.getDeclaredField(columnName);
                    
                    field.setAccessible(true);
                    field.set(t, columnVal);
                
            
            return t;
        
        catch (SQLException e)
        
            e.printStackTrace();
        
        catch (InstantiationException e)
        
            e.printStackTrace();
        
        catch (IllegalAccessException e)
        
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        catch (SecurityException e)
        
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        catch (NoSuchFieldException e)
        
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        
        return t;
    
    
    // 利用反射机制实现数据库的操作,知道其cls的结构
    public <T> List<T> QueryDBMoreObj(String sql, List<Object> params, Class<T> cls)
    
        List<T> rstList = new ArrayList<T>();
        try
        
            pstm = conn.prepareStatement(sql);
            if (params != null && !params.equals(""))
            
                for (int i = 0; i < params.size(); i++)
                
                    pstm.setObject(i + 1, params.get(i));
                
            
            rs = pstm.executeQuery();
            ResultSetMetaData rsMetaData = rs.getMetaData();
            while (rs.next())
            
                T t = cls.newInstance();
                for (int i = 0; i < rsMetaData.getColumnCount(); i++)
                
                    String columnName = rsMetaData.getColumnName(i + 1);
                    Object columnVal = rs.getObject(i + 1);
                    // 这个field是类加载器级别的,用于管理其类的属性
                    Field field = cls.getDeclaredField(columnName);
                    // 设置这个属性可以访问
                    field.setAccessible(true);
                    field.set(t, columnVal);
                
                rstList.add(t);
            
            return rstList;
        
        catch (SQLException e)
        
            e.printStackTrace();
        
        catch (InstantiationException e)
        
            e.printStackTrace();
        
        catch (IllegalAccessException e)
        
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        catch (SecurityException e)
        
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        catch (NoSuchFieldException e)
        
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        
        return rstList;
    
    
    public void releaseJdbc()
    
        
        try
        
            //后生成的先释放掉
            if (rs != null)
            
                rs.close();
            
            if (pstm != null)
            
                pstm.close();
            
            if (conn != null)
            
                conn.close();
            
        
        catch (SQLException e)
        
            e.printStackTrace();
        
        
    

Test.java
package test;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import bean.User;

import utl.jdbcUtil;

public class Test

    
    /**
     * @param args
     */
    public static void main(String[] args)
    
        jdbcUtil jUtilTest = new jdbcUtil();
        jUtilTest.getConnection();
        // sql语句通配符对应的字段
        List<Object> params = new ArrayList<Object>();
        // 创建表
        String createTable =
            "create table if not exists userinfo (id int primary key auto_increment,username varchar(64),pswd varchar(64))";
        jUtilTest.updateDB(createTable, null);
        
        // 插入数据
        for (int i = 0; i < 10; i++)
        
            String insertOne = "insert into userinfo (username,pswd) values (?,?)";
            params.clear();
            params.add("byd" + i);
            params.add("123" + i);
            jUtilTest.updateDB(insertOne, params);
        
        
        // 删除一条数据,sql语句对大小写不敏感,delete/Delete/DELETE等均可
        String deleteOne = "DeLete from userinfo where username = ?";
        params.clear();
        params.add("byd0");
        jUtilTest.updateDB(deleteOne, params);
        
        // 改变数据
        String updateOne = "update userinfo set pswd = ? where username =?";
        params.clear();
        params.add("bydxxoo");
        params.add("byd");
        jUtilTest.updateDB(updateOne, params);
        
        // 查询一条数据
        String findOne = "select * from userinfo where username = ?";
        // notice:数据库的列下标是从1开始计数的
        params.clear();
        params.add("byd2");
        Map<String, Object> rstOne = jUtilTest.QueryDB(findOne, params);
        System.out.println("-->" + rstOne);
        
        // 查询多条数据
        String findMore = "select * from userinfo";
        List<Map<String, Object>> rstMore = jUtilTest.QueryMoreDB(findMore, null);
        System.out.println("-->" + rstMore);
        
        // 反射查询一条数据
        String findOneRefl = "select * from userinfo where username =?";
        params.clear();
        params.add("byd2");
        User userOne = jUtilTest.QueryDBObj(findOneRefl, params, User.class);
        System.out.println("-->" + userOne);
        
        // 反射查询多条数据
        String findMoreRefl = "select * from userinfo";
        List<User> userMore = jUtilTest.QueryDBMoreObj(findMoreRefl, null, User.class);
        System.out.println("-->" + userMore);
        
        // 删除表
        // String sql3 = "delete from userinfo";
        // jUtilTest.updateDB(sql3, null);
        // notice:断开数据库连接前,要释放一些资源
        jUtilTest.releaseJdbc();
    
    

User.java
package bean;
public class User

    private int id;
    private String username="";
    @Override
    public String toString()
    
        return "User [id=" + id + ", username=" + username + ", pswd=" + pswd + "]";
    
    private String pswd="";
    public int getId()
    
        return id;
    
    public void setId(int id)
    
        this.id = id;
    
    public String getUsername()
    
        return username;
    
    public void setUsername(String username)
    
        this.username = username;
    
    public String getPswd()
    
        return pswd;
    
    public void setPswd(String pswd)
    
        this.pswd = pswd;
    

======================================================华丽的分隔符==============================================================

下面在说下安装mysql遇到的问题:

MySql安装包:http://pan.baidu.com/share/link?shareid=2375321572&uk=3056808396

1.安装MySQl-5.5.22老是最后一步开在start Service
安装的 MySQL 5.1.48 或是 MySQL 5.5.8,配置好最后点击 Execute 按钮了,但是进行不到 Start service 这一步。检查了下 MySQL 系统服务已添加,但是无法启动,手工也不行。这时候用事件查看器可以看到程序事件里有几个来自于 MySQL 的错误: 

Plugin 'InnoDB' registration as a STORAGE ENGINE failed. 
Unknown/unsupported table type: INNODB 

原来是因为这两版本的 MySQL 默认使用了支持事物的 INNODB 引擎,打开 my.ini 文件,在 MySQL 的安装文件夹, 如 c:program filesMySQL 中,看到: 


default-storage-engine=INNODB 
解决办法是把该设置改为 

default-storage-engine=MYISAM 


仍然使用 MyISAM 作为默认的数据库引擎,保存 my.ini 文件,然后手工启动 MySQL 服务,成功;再把刚刚的配置窗口关掉就行了。 
你完全可以在创建数据库时指定所创建数据库所用的数据库引擎,或创建表时所用的数据库引擎,或者创建后再更改都可以。 
你可以再次回忆一下刚刚配置的过程: 
安装的最后一个步骤,在点 Finish 按钮时,可以选择 Configure the MySQL Server now,或者是从开始菜单里直接运行 MySQL 的 MySQL Server Instance Configuration Wizard 来进行配置数据库,在选择 database usage 时有三个选项: 

1) Multifunctional Database 
2) Transactional Database Only 
3) No-Transactional Database Only 

默认是第一项,选第二项也会让数据库默认的引擎为 INNODB,生成的 my.ini 文件里都会是 default-storage-engine=INNODB。至于在 my.ini 中注释掉了 --skip-innodb 并不太会影响到数据库的启动,只是决定了数据库的事物特性。 

那么在最后一步 Processing configuration ... 里写完 my.ini 文件后,进行到 Start service 就不动了,也就是启动不了 MySQL 服务,在系统服务里已经加了 MySQL 服务名。 

如果你这一步选择的是第三项,不使用支持事件的数据库,那么在 my.ini 文件里就是 default-storage-engine=MYISAM,那么你也很幸运,能顺利配置成功,并启动好数据库。不过这将使你不能使用 INNODB 引擎(ERROR 1286 (42000): Unknown table engine 'InnoDB'),其实也就是把 my.ini 中的 skip-innodb 给启用了,你可以把它再次注释掉试试事物。 

作者 mywaylife

如果还是不能解决可以参考下面的方法:

安装MySQL时无法启动服务(could not start the service ) 

1、建议使用360卸载已经安装的mysql数据库,因为360会查看相关的注册信息,卸载比较彻底。 
2、检查3306端口是否已经占用,如果已经占有,杀死此进程。 
3、查看服务列表中,是否还有mysql的服务进程。 
4、要确保安装目录的访问权限是everyone,这里我建议不要把mysql安装的c盘中,因为xp有时候为了系统安全,会限制文件夹的访问权限。 
5、建议安装在干净的文件夹里,如果安装在上次安装过的文件夹,建议删除文件夹下的所有文件。 

mysql安全设置后导致mysql无法运行,建议重置运行mysql服务的登陆用户名密码,然后进服务里面重新输入刚修改的用户名与密码,这样就可以了

如果还是不可以,我们可以通过查看错误日志的方法解决:

mysql错误日志位于mysql安装目录下的扩展名为.err的文件,复制一份通过记事本等工具打开即开,如果err日志过大建议不要用记事本,可以用editplus打开 

详细出处参考:http://www.jb51.net/article/30866.htm


2.利用Navigate for MySql工具查看数据库,保存数据库等操作时报  “can't creat/write to file”

解决办法:

打开MySql的安装路径:找到my.ini,在其中的[mysqld]下面添加 tmpdir="C:/Program Files/MySQL/MySQL Server 5.5/Temp",后面指定的Temp路径,没有的话先自己建一个在指定,路径注意分隔符是否正确。

或者:
1、C:\\Windows\\TEMP 文件夹权限不够,至少也要给出 USERS 组的可读可写权限;------------你的服务器装了 MCAFEE 杀毒软件,它的访问保护禁止了 TEMP 文件可写,修改访问保护设置;
2、C:\\Windows\\TEMP 文件夹的磁盘满了,文件写不进去了,清空 TEMP 文件夹;-------------------还是MCAFEE杀毒软件的问题,解决步骤:按访问扫描属性 - 所有进程 - 检测项 - 扫描文件(在写入磁盘时 )勾去掉就好了。

3、第三方限制(如杀毒软件的限制)----------------------------关闭杀毒试试

====================================================================================================================================

本人技术很菜,如果文中存在错误,还请给位多多指出!


以上是关于Android之jdbc的学习的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot 学习笔记 -- [spring Boot配置文件之YAML格式, springBoot自动配置浅入,springboot集成JDBC]

2019-06-12 Java学习日记之JDBC

Android消息传递之Handler消息机制

Xamarin学习系列之极光消息推送

Android View之布局加载流程

JavaWeb学习总结--JDBC之批处理