JDBC从搭建服务器,到运行到Android全集锦!!

    xiaoxiao2023-09-20  172

    引言

    经过几天的面向百度和csdn,以及和无数java中的对象谈恋爱,终于弄清除了JDBC连接数据库的来龙去脉。因此本帅决定记录下本帅从搭建服务器到运行到Android摸索的全过程,也算给小白们些许福利!话不多说,让我们开始吧!

    步骤

    JDBC(Java DataBase Connection)的前提工作

    a. JDBC如果没有服务器,首先需要搭建本地的局域网服务器

    详情见传送门大娃

    传送门大娃子:本地服务器的搭建

    b. 搭建好服务器以后,需要创建可远程访问mysql数据库权限的用户

    详情见传送门二娃

    传送门二娃子:创建可远程访问mysql数据库权限的用户

    c. 当完成好前面两步以后,需要下载MySQL Connector for Java(Mysql 提供给Java连接数据库的接口)驱动,并在Android studio 中配置好,具体配置见传送门三娃

    传送门三娃:下载并配置Mysql connector for java驱动接口

    连接JDBC

    d. 当完成好上述JDBC连接的准备工作以后,就可以着手连接JDBC了

    1.首先我们需要在mysql中创建数据库,和数据表。(如果数据表中没法插入中文,请参考传送门四娃。) 传送门四娃:phpMyAdmin中文无法插入的编码问题的解决 2.写JDBC加载驱动获得JDBC连接的代码 Class.forName(com.mysql.jdbc.Driver) 通过反射加载驱动类(按照类名加载) Connection connection = DriverManager.getConnection(url,username,password); 3.获取连接中的三个参数url,username,password String url = “jdbc:mysql://服务器ip地址:数据库的访问端口/数据库名称” String username = 创建的可远程访问mysql权限的用户的用户名 String password = 创建的可远程访问mysql权限的用户的密码 其中 服务器ip地址的获得 来自 dos命令下输入ipconfig, 数据库的访问端口来自登入phpMyadmin下,上方显示的端口(一般为3306,如果你未更改过端口的话) 通过以上的步骤,小伙伴们就能够连上远程服务器的mysql数据库的具体某个数据库啦,具体步骤请参考传送门五娃 传送门五娃:连接远程mysql数据库中的具体某个数据库

    e. 连接上mysql远程数据库中的具体数据库后,对该数据库的表的操作,需要掌握的知识:

    statement(statement(sql注入),preparedstatement等) Resultset(查询的结果集)等 由于发现JDBC的增删改查的代码存在同一耦合的代码,为4中所提到的加载驱动获取连接以及资源使用后的释放代码(connection,statement,resultset),所以单独提取除了一个工具类JDBCUtil,详情见传送门六娃:

    传送门六娃: JDBC增删改查操作以及JDBCUtil封装工具类

    f. 提取出JDBC工具类以及实现JDBC增删改查代码以后,我们需要设置两个测试,

    一个是面向Android studio的控制台的测试类(有Main方法的类,输出在Android studio控制台上) 一个是面向Android 的测试Activity(理论上来讲,能在main中运行测试以后,基本也能在手机的Activity中运行) 先在有主方法的类中测试JDBC的增删改查操作是否没有问题,部分测试代码如下:(主要提供思路,小伙伴们最好自行写代码测试哟!)

    package com.example.paoduantui.JDBC.testJDBC; import android.os.SystemClock; import com.example.paoduantui.JDBC.JDBCDAO.PositionDBDao; import com.example.paoduantui.JDBC.JDBCDAO.TaskDBDao; import com.example.paoduantui.JDBC.JDBCDAO.UserDBDao; import com.example.paoduantui.JDBC.JDBCDB.PositionDB; import com.example.paoduantui.JDBC.JDBCDB.TaskDB; import com.example.paoduantui.JDBC.JDBCDB.UserDB; import com.example.paoduantui.Task; import java.util.List; //测试JDBCDao类 /** * 创建了四个线程,分别执行了增删改查操作 * 测试了dao类 * main方法中能调用的,Activity中也可以 * */ public class testJDBCDao { public static void main(String[] args){ //插入线程 new Runnable() { @Override public void run() { //TaskDB taskDB = new TaskDB(1,1,"张大帅比",'1',"张斌真帅","","2015-06-14","2015-06-14",'7'); PositionDB positionDB = new PositionDB(1,1,1,1,"","",""); int result= PositionDBDao.insert(positionDB); if(result==1) System.out.print("插入数据成功!"); } }.run(); //查询线程 new Runnable() { @Override public void run() { List<TaskDB> list = TaskDBDao.getAll(); for(int i= 0;i<list.size();i++){ System.out.println(list.get(i).getId()+list.get(i).getUsername()); } } }.run(); //删除线程 new Runnable() { @Override public void run() { TaskDB taskDB1=new TaskDB(9,1,"张斌斌",1,"张斌斌摔倒的","","","",7); int result1 = TaskDBDao.deleteByTaskId(taskDB1); if(result1==1)System.out.println("删除数据成功!!"+taskDB1.getTaskid()); } }.run(); //更新线程 new Runnable() { @Override public void run() { TaskDB taskDB1=new TaskDB(1,1,"张斌斌",1,"张斌斌摔倒的","","","",7); int result1 = TaskDBDao.updateByTaskId(taskDB1); System.out.println("更新数据成功!!"+taskDB1.getTaskid()); } }.run(); } }

    将没有问题的方法再放入Android 的Activity中测试,此时,会发现在含有主方法的类中能运行的某些方法在Android设备上运行会闪退, 究其原因有以下几种可能:(通过检查一一排除)

    1.连接远程mysql服务器,本质是TCP连接(访问,返回数据),因此需在AndroidManifest.xml文件中添加网络权限 2.需要添加连接JDBC的许可协议(本帅也不知道这是什么鬼,望大神告知)(在需要用到JDBC的Activity的oncreat加载布局后添加上以下代码:)

    //添加许可协议,不加的话,闪退 StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); 当第一次进入界面可以成功使用JDBC的操作,而第二次进去会闪退,主要是因为,Android不支持将JDBC放在主线程中,因此需要调用线程来完成JDBC的操作

    当在含有主方法的类中以及Activity中均测试完以后,意味着Android端可以利用JDBC来成功访问远程mysql远程数据库啦!!(贴上我用来测试的Activity代码)

    package com.example.paoduantui.JDBC.testJDBC; import android.os.StrictMode; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import com.example.paoduantui.JDBC.JDBCDAO.TaskDBDao; import com.example.paoduantui.JDBC.JDBCDAO.UserDBDao; import com.example.paoduantui.JDBC.JDBCDB.TaskDB; import com.example.paoduantui.JDBC.JDBCDB.UserDB; import com.example.paoduantui.R; import java.util.List; //在main方法中或在activity中不能将JDBC操作数据库放在主线程里 public class testJDBCActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test_jdbc); final TextView textView = findViewById(R.id.textView); Button insert =findViewById(R.id.insert); Button delete =findViewById(R.id.delete); Button query = findViewById(R.id.query); Button update = findViewById(R.id.update); //添加许可协议,不加的话,闪退 StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); //开启新线程,插入数据 final Runnable runnable1=new Runnable() { @Override public void run() { TaskDB taskDB = new TaskDB(1,1,"张大帅比",'1',"张斌真帅","","2015-06-14","2015-06-14",'7'); int result=TaskDBDao.insert(taskDB); if(result==1)Toast.makeText(testJDBCActivity.this,"插入数据成功!",Toast.LENGTH_LONG).show(); else Toast.makeText(testJDBCActivity.this,"不要在点击了,已经插入成功了!!",Toast.LENGTH_LONG).show(); } }; //开启新线程,删除数据 final Runnable runnable2 = new Runnable() { @Override public void run() { TaskDB taskDB = new TaskDB(1,1,null,0,null,null,null,null,0); int result = TaskDBDao.deleteByTaskId(taskDB); if(result==1) Toast.makeText(testJDBCActivity.this,"删除数据成功!",Toast.LENGTH_LONG).show(); } }; //开启新线程,连接JDBC,防止主线程阻塞,查询 final Runnable runnable = new Runnable() { @Override public void run() { String str=""; List<TaskDB> list = TaskDBDao.getById(1, 0); for (int i = 0; i < list.size(); i++) { str += list.get(i).getId() + list.get(i).getUsername(); } //Toast.makeText(testJDBCActivity.this, str, Toast.LENGTH_LONG).show(); textView.setText(str); } }; //更新线程 final Runnable runnable3 = new Runnable() { @Override public void run() { TaskDB taskDB = new TaskDB(2,1,"彬彬",0,"","","","",0); int result = TaskDBDao.updateByTaskId(taskDB); if(result==1) Toast.makeText(testJDBCActivity.this,"更新成功!!",Toast.LENGTH_LONG).show(); } }; insert.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { runnable1.run(); } }); delete.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { runnable2.run(); } }); query.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { runnable.run(); } }); update.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { runnable3.run(); } }); //Toast.makeText(this, str, Toast.LENGTH_SHORT).show(); } }

    g.根据数据库中所建的表建相应的实体类DB类(表中字段即为类中的成员变量)
    package com.example.paoduantui.JDBC.JDBCDB; //数据库user表的实体类 public class UserDB { private int id;//id private String username;//用户名 private String password;//密码 private int image;//头像 //insert into user(id,username,password,image) values (getId,getUsername,getPassword,getImage); //表名可以通过解析对象userDB,规定user_DB为其对象,解析对象即可 //通过占位符,四个占位符,for(int i = 1;i<count;i++) ?, //ps.setObject(1,getId) 通过反射获取 //ps.setObject(4,getImage) private final int count = 4;//该表有四个字段 public UserDB() { } //构造函数以及其getter setter 方法 public UserDB(int id, String username, String password, int image) { this.id = id; this.username = username; this.password = password; this.image = image; } 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 getPassword() { return password; } public void setPassword(String password) { this.password = password; } public int getImage() { return image; } public void setImage(int image) { this.image = image; } }
    f.根据该表创建出相应的数据库操作类Dao类(本帅一般创建增删改查(其中查又细分为查所有getAll,按条件查等,getById,getCondition(如模糊查找)等)类)
    package com.example.paoduantui.JDBC.JDBCDAO; import android.widget.Switch; import com.example.paoduantui.JDBC.JDBCDB.UserDB; import com.example.paoduantui.JDBC.JDBCUtil; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; //user表的数据库操作类 /** * 里面的方法全为静态方法,用 UserDBDao.方法名 直接调用 * insert方法(增),deleteById方法(删),updateById方法(改),(参数均为UserDB) * getAll(返回为UserDB的链表集合)(无参数)以及getById(返回为UserDB的链表集合)(_id ,type)(查) * */ public class UserDBDao { private static Connection connection;//获取连接(跑断腿App的连接) private static PreparedStatement ps;//准备好的sql陈述 private static ResultSet rs;//结果集 //增 /** * 返回int类型的insert数据库操作 * 参数为UserDB * */ public static int insert(UserDB userDB){ try { connection = JDBCUtil.getConnection(); String sql = "insert into user(id,username,password,image) values (?,?,?,?)"; ps = connection.prepareStatement(sql); ps.setObject(1,userDB.getId()); ps.setObject(2,userDB.getUsername()); ps.setObject(3,userDB.getPassword()); ps.setObject(4,userDB.getImage()); int result = ps.executeUpdate(); return result; } catch (SQLException e) { e.printStackTrace(); }finally { JDBCUtil.close(null,ps,connection); } return 0; } //删 /** * 返回int类型的deleteById数据库操作 * 参数为UserDB * */ public static int deleteById(UserDB userDB){ try { connection = JDBCUtil.getConnection(); String sql = "delete from user where id = ?"; ps = connection.prepareStatement(sql); ps.setObject(1,userDB.getId()); int result = ps.executeUpdate(); return result; } catch (SQLException e) { e.printStackTrace(); }finally { JDBCUtil.close(null,ps,connection); } return 0; } /** * 返回int类型的updateById数据库操作 * 参数为UserDB * */ public static int updateById(UserDB userDB){ try { connection = JDBCUtil.getConnection(); String sql = "update user set username = ? , password = ? , image = ? where id = ?"; ps = connection.prepareStatement(sql); //ps.setObject(1,userDB.getId()); ps.setObject(1,userDB.getUsername()); ps.setObject(2,userDB.getPassword()); ps.setObject(3,userDB.getImage()); ps.setObject(4,userDB.getId()); int result = ps.executeUpdate(); return result; } catch (SQLException e) { e.printStackTrace(); }finally { JDBCUtil.close(null,ps,connection); } return 0; } /** * 返回List<UserDB>类型的获取表中所有数据的数据库操作 * */ public static List<UserDB> getAll(){ List<UserDB> list = new ArrayList<>(); try { connection = JDBCUtil.getConnection(); String sql = "select * from user order by id desc";//降序排列,使得每次第一条记录永远是最新的记录 ps = connection.prepareStatement(sql); rs = ps.executeQuery(); while (rs.next()){ int id = rs.getInt(1); String username = rs.getString(2); String password = rs.getString(3); int image = rs.getInt(4); UserDB userDB = new UserDB(id,username,password,image); list.add(userDB); } return list; } catch (SQLException e) { e.printStackTrace(); }finally { JDBCUtil.close(rs,ps,connection); } return null; } /** * 返回List<UserDB>类型的根据不同id的类型获取表中数据的数据库操作 * 其中参数_id 表示id的值,type表示id的类型 0:id(用户id),1:taskid(任务id),2:jdr_id(接单人id) * */ public static List<UserDB> getById(int _id,int type){ String selection = null; List<UserDB> list = new ArrayList<>(); switch (type){ case 0: selection = "id"; break; case 1: selection="taskid"; break; case 2: selection="jdr_id"; break; } try { connection = JDBCUtil.getConnection(); String sql = "select * from user where "+ selection + "= ? ";//通过拼接的sql来查询不同id下的数据 ps = connection.prepareStatement(sql); ps.setObject(1,_id); ResultSet rs = ps.executeQuery(); while (rs.next()){//注意,此处的结果集不同于sqlite的游标集,下标是从1开始的 int id = rs.getInt(1); String username = rs.getString(2); String password = rs.getString(3); int image = rs.getInt(4); UserDB userDB = new UserDB(id,username,password,image); list.add(userDB); } return list; } catch (SQLException e) { e.printStackTrace(); }finally { JDBCUtil.close(rs,ps,connection); } return null; } }

    至此,JDBC到这儿就完美收官啦!期待与小伙伴们的再次相遇!

    最新回复(0)