首先搭建好平台,从题目可以看出需要下载orcal数据库、Apache和PHP,各自的环境配置网上有讲,好多都是PHP+mysql,将PHP和MySQL连接我很快就弄好了,但是将PHP和orcal连接废了好多时间,主要是你要统一好版本。
https://jingyan.baidu.com/article/ce09321b7593062bfe858f6c.html,我第一次配置就是跟着这个学,如果你只是想让PHP和MySQL连接这个还是比较好多,一次就成功了。
我现在是orcal11+Apache24+PHP5,之前用的PHP7导致php.ini中不能开启extension=php_oci8_11g.dll配置。
PHP5里面只有php_oci8_12c.dll,其他两个需要自己另外下载。网址是http://windows.php.net/downloads/pecl/releases/oci8/ 找好和自己匹配的版本(这个人家整理的真不错,非常细心)。
连接成功后就可以在你所配置的放置php文件的Apache文件夹下新建php文档。文件名为conorcal.php(会用到)代码如下:
<?php
$conn = oci_connect('用户名', '密码', '主机地址/数据库名');
if ($conn) {
# code...
echo "连接成功";
}
?>
打开自己设置的主机IP:端口号/文件地址,就可以出现此页面。
成功之后就可以走向使用手机查询、插入、删除的开发之路了。首先看看最后效果。
按姓名查询
按地址查询
按年龄查询
插入
这就是最后实现的效果。
首先贴上php代码,selectbywhere.php 根据APP请求的搜索条件进行搜索
<?php
require 'conorcal.php';//上面的连接文件夹,放在同一文件夹中
$personname = $_POST['name'];
$personage = $_POST['age'];
$personaddress=$_POST['address'];
$result1=array();
if (!empty($_POST['name'])) {
# code...
$query = 'SELECT * FROM androidtest where personname=:personname';
$stid = oci_parse($conn, $query) ;// 编译SQL语句,准备执行
oci_bind_by_name($stid, ":personname", $personname);//设置绑定变量的取值
}elseif (!empty($_POST['age'])&&empty($_POST['address'])) {
# code...
$query = 'SELECT * FROM androidtest where personage=:personage ';
$stid = oci_parse($conn, $query) ;
oci_bind_by_name($stid, ":personage", $personage);
}elseif (!empty($_POST['age'])&&!empty($_POST['address'])) {
# code...
$query = 'SELECT * FROM androidtest where personage=:personage and personaddress=:personaddress '; // 查询语句
$stid = oci_parse($conn, $query) ;
oci_bind_by_name($stid, ":personage", $personage);
oci_bind_by_name($stid, ":personaddress", $personaddress);
}elseif (empty($_POST['age'])&&!empty($_POST['address'])) {
# code...
$query = 'SELECT * FROM androidtest where personaddress=:personaddress '; // 查询语句
$stid = oci_parse($conn, $query) ;
oci_bind_by_name($stid, ":personaddress", $personaddress);
}else {
# code...
$query = 'SELECT * FROM androidtest '; // 查询语句
$stid = oci_parse($conn, $query) ;
}
//$stid = oci_parse($conn, $query) ;// 编译SQL语句,准备执行
if (!$stid) {
$e = oci_error($conn);
echo($e['message']);
exit;
}
$r = oci_execute($stid);
//$r = oci_execute($stid, OCI_DEFAULT); // 执行SQL。OCI_DEFAULT表示不要自动commit
if(!$r) {
$e = oci_error($stid);
echo ($e['message']);
exit;
}
while ($row = oci_fetch_assoc($stid)) { //提取结果数据的一行到一个关联数组
$result1[] = $row;
}
if(isset($result1)){
echo json_encode($result1);
}
oci_free_statement($stid); //释放关联于语句或游标的所有资源
oci_close($conn); //关闭 Oracle数据库连接
?>
根据APP中填写的条件进行插入并显示
这是插入insert2.php
<?php
$response=array();
if (isset($_POST['name'])) {
# code...
require 'conorcal.php';
$personname = $_POST['name'];
$personage = $_POST['age'];
$personaddress=$_POST['address'];
$query='INSERT INTO androidtest (personname,personage,personaddress) values(:personname,:personage,:personaddress)';// 查询语句
$stid = oci_parse($conn, $query); // 编译SQL语句,准备执行
if (!$stid) {
$e = oci_error($conn);
echo($e['message']);
exit;
}
oci_bind_by_name($stid, ":personname", $personname);
oci_bind_by_name($stid, ":personage", $personage);
oci_bind_by_name($stid, ":personaddress", $personaddress);
$r = oci_execute($stid, OCI_COMMIT_ON_SUCCESS) or die('die'); // 执行SQL。OCI_DEFAULT表示不要自动commit
if(!$r) {
$e = oci_error($stid);
echo ($e['message']);
exit;
}
if(oci_num_rows($stid)){
require 'select.php';
}
oci_free_statement($stid); //释放关联于语句或游标的所有资源
oci_close($conn); //关闭 Oracle数据库连接
}else {
# code...
$response["success"] = 0;
$response["message"] = "name can't emply!";
echo json_encode($response);
}
?>
这是显示select.php
<?php
//require 'conorcal.php';
$query = 'SELECT * FROM androidtest'; // 查询语句
$stid = oci_parse($conn, $query); // 编译SQL语句,准备执行
if (!$stid) {
$e = oci_error($conn);
echo($e['message']);
exit;
}
$r = oci_execute($stid, OCI_DEFAULT); // 执行SQL。OCI_DEFAULT表示不要自动commit
if(!$r) {
$e = oci_error($stid);
echo ($e['message']);
exit;
}
while($row = oci_fetch_assoc($stid)) { //提取结果数据的一行到一个关联数组
$result1[]=$row;
}
if($result1){
echo json_encode($result1);
}
/*oci_free_statement($stid); //释放关联于语句或游标的所有资源
oci_close($conn); //关闭 Oracle数据库连接
*/
?>
根据APP中填写的条件进行删除并显示
这是删除 delete.php
<?php
require 'conorcal.php';
$personname = $_POST['name'];
$personage = $_POST['age'];
$personaddress=$_POST['address'];
$stid=0;
if (!empty($_POST['name'])) {
# code...
$query = 'Delete FROM androidtest where personname = :personname';
$stid = oci_parse($conn, $query) ;// 编译SQL语句,准备执行
oci_bind_by_name($stid, ":personname", $personname);//设置绑定变量的取值
}elseif (!empty($_POST['age'])&&empty($_POST['address'])) {
# code...
$query = 'Delete FROM androidtest where personage=:personage ';
$stid = oci_parse($conn, $query) ;
oci_bind_by_name($stid, ":personage", $personage);
}elseif (!empty($_POST['age'])&&!empty($_POST['address'])) {
# code...
$query = 'Delete FROM androidtest where personage=:personage and personaddress=:personaddress '; // 查询语句
$stid = oci_parse($conn, $query) ;
oci_bind_by_name($stid, ":personage", $personage);
oci_bind_by_name($stid, ":personaddress", $personaddress);
}elseif (empty($_POST['age'])&&!empty($_POST['address'])) {
# code...
$query = 'Delete FROM androidtest where personaddress=:personaddress '; // 查询语句
$stid = oci_parse($conn, $query) ;
oci_bind_by_name($stid, ":personaddress", $personaddress);
}else {
# code...
echo "没删除";
}
//$stid = oci_parse($conn, $query) ;// 编译SQL语句,准备执行
if (!$stid) {
$e = oci_error($conn);
echo($e['message']);
exit;
}
$r = oci_execute($stid);
//$r = oci_execute($stid, OCI_DEFAULT); // 执行SQL。OCI_DEFAULT表示不要自动commit
if(!$r) {
$e = oci_error($stid);
echo ($e['message']);
exit;
}
if(oci_num_rows($stid)){
require 'select.php';
}
oci_free_statement($stid); //释放关联于语句或游标的所有资源
oci_close($conn); //关闭 Oracle数据库连接
?>
显示依旧是上面select.php
其中所构成的网址为:
String phpUrlDelete = "http://192.168.1.189:8800/orcal/delete.php"; String phpUrl = "http://192.168.1.189:8800/orcal/selectbywhere.php"; String phpUrlSend = "http://192.168.1.189:8800/orcal/insert2.php";
android端我是通过OkHttp进行网络通信,向php索要自己需要的数据。php返回数据,上面php得到数据库已经转化成JSON的形式,需要做的就是通过APP端解析json得到数据,并通过RecycleView制作成表格形式显示出来。
先搭建layout
制作背景边框,使其看起来像表格一样
frame_background.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"> <stroke android:color="@android:color/black" android:width="1dp" /> </shape>
date_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/name_item" android:layout_width="0dp" android:layout_height="30dp" android:layout_weight="1" android:background="@drawable/frame_background" android:gravity="center" /> <TextView android:id="@+id/age_item" android:layout_width="0dp" android:layout_height="30dp" android:layout_weight="1" android:background="@drawable/frame_background" android:gravity="center"/> <TextView android:id="@+id/address_item" android:layout_width="0dp" android:layout_height="30dp" android:layout_weight="1" android:background="@drawable/frame_background" android:gravity="center"/> </LinearLayout>layout_form.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="@drawable/frame_background"> <LinearLayout android:layout_width="match_parent" android:layout_height="30dp"> <TextView android:text="name" android:textStyle="bold" android:layout_width="0dp" android:layout_height="30dp" android:layout_weight="1" android:background="@drawable/frame_background" android:gravity="center" /> <TextView android:text="age" android:textStyle="bold" android:layout_width="0dp" android:layout_height="30dp" android:layout_weight="1" android:background="@drawable/frame_background" android:gravity="center"/> <TextView android:text="address" android:textStyle="bold" android:layout_width="0dp" android:layout_height="30dp" android:layout_weight="1" android:background="@drawable/frame_background" android:gravity="center"/> </LinearLayout> <android.support.v7.widget.RecyclerView android:id="@+id/recycler_form" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>activity_main.xml
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.phptest.MainActivity"> <TextView android:id="@+id/textView" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:layout_marginTop="8dp" android:text="Hello World!" app:layout_constraintBottom_toTopOf="@+id/include" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@+id/editaddress" /> <Button android:id="@+id/get" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="26dp" android:layout_marginTop="20dp" android:text="select" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/editname" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="22dp" android:layout_marginStart="30dp" android:text="name" app:layout_constraintBottom_toBottomOf="@+id/editname" app:layout_constraintEnd_toStartOf="@+id/editname" app:layout_constraintStart_toStartOf="parent" /> <EditText android:id="@+id/editname" android:layout_width="0dp" android:layout_height="50dp" android:layout_marginEnd="15dp" android:ems="10" android:hint="Name" android:inputType="textPersonName" app:layout_constraintBottom_toBottomOf="@+id/get" app:layout_constraintEnd_toStartOf="@+id/get" app:layout_constraintStart_toEndOf="@+id/name" app:layout_constraintTop_toTopOf="@+id/get" /> <TextView android:id="@+id/age" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="30dp" android:text="age" app:layout_constraintBottom_toBottomOf="@+id/editage" app:layout_constraintStart_toStartOf="parent" /> <EditText android:id="@+id/editage" android:layout_width="0dp" android:layout_height="50dp" android:layout_marginBottom="37dp" android:layout_marginEnd="14dp" android:layout_marginStart="8dp" android:layout_marginTop="37dp" android:ems="10" android:hint="age" android:inputType="textPersonName" app:layout_constraintBottom_toTopOf="@+id/delete" app:layout_constraintEnd_toStartOf="@+id/send" app:layout_constraintStart_toStartOf="@+id/editname" app:layout_constraintTop_toBottomOf="@+id/editname" /> <TextView android:id="@+id/address" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="12dp" android:layout_marginEnd="22dp" android:layout_marginStart="16dp" android:text="address" app:layout_constraintBottom_toBottomOf="@+id/editaddress" app:layout_constraintEnd_toStartOf="@+id/editaddress" app:layout_constraintStart_toStartOf="parent" /> <EditText android:id="@+id/editaddress" android:layout_width="0dp" android:layout_height="50dp" android:layout_marginEnd="18dp" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:ems="10" android:hint="address" android:inputType="textPersonName" app:layout_constraintEnd_toStartOf="@+id/delete" app:layout_constraintStart_toStartOf="@+id/editage" app:layout_constraintTop_toBottomOf="@+id/editage" /> <Button android:id="@+id/send" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:layout_marginStart="8dp" android:text="insert" app:layout_constraintBottom_toBottomOf="@+id/editage" app:layout_constraintEnd_toEndOf="@+id/get" app:layout_constraintStart_toStartOf="@+id/get" app:layout_constraintTop_toTopOf="@+id/editage" /> <Button android:id="@+id/delete" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:text="delete" app:layout_constraintBottom_toBottomOf="@+id/editaddress" app:layout_constraintEnd_toEndOf="@+id/send" app:layout_constraintStart_toStartOf="@+id/send" app:layout_constraintTop_toTopOf="@+id/editaddress" /> <include android:id="@+id/include" layout="@layout/layout_form" android:layout_width="match_parent" android:layout_height="200dp" android:layout_marginBottom="48dp" android:layout_marginEnd="8dp" android:layout_marginStart="8dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintStart_toStartOf="parent" /> </android.support.constraint.ConstraintLayout>
上面这个代码是ConstraintLayout直接拖动组件画出来的,可以自己去写
下面来看java文件
DateList.java
public class DateList { String person_name; String person_age; String person_address; public DateList(String person_name, String person_age, String person_address) { this.person_name = person_name; this.person_age = person_age; this.person_address = person_address; } public String getPerson_name() { return person_name; } public String getPerson_age() { return person_age; } public String getPerson_address() { return person_address; } }DateAdapter.java
public class DateAdapter extends RecyclerView.Adapter<DateAdapter.MyViewHolder> { private List<DateList> dateLists; static class MyViewHolder extends RecyclerView.ViewHolder { TextView person_name; TextView person_age; TextView person_address; public MyViewHolder(View itemView) { super(itemView); person_name = itemView.findViewById(R.id.name_item); person_age = itemView.findViewById(R.id.age_item); person_address = itemView.findViewById(R.id.address_item); } } public DateAdapter(List<DateList> dateLists) { this.dateLists = dateLists; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.date_item, parent, false); MyViewHolder myViewHolder = new MyViewHolder(view); return myViewHolder; } @Override public void onBindViewHolder(MyViewHolder holder, int position) { DateList dateList = dateLists.get(position); holder.person_name.setText(dateList.getPerson_name()); holder.person_age.setText(dateList.getPerson_age()); holder.person_address.setText(dateList.getPerson_address()); } @Override public int getItemCount() { return dateLists.size(); } }
上面是RecycleView表格显示
重要的OkHttp通信代码
HttpUtil
public class HttpUtil { public static void sendOkHttpRequest(String address, Callback callback) { OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder().url(address).build(); client.newCall(request).enqueue(callback); } public static void sendOkHttpPost(String address, String personName,String personage, String personAddress, Callback callback) { OkHttpClient client = new OkHttpClient(); RequestBody requestBody = new FormBody.Builder() .add("name", personName)//引号中的name要和php接收$_POST['name']引号里面的一样 .add("age",personage) .add("address", personAddress) .build(); Request request = new Request.Builder() .url(address) .post(requestBody) .build(); client.newCall(request).enqueue(callback); } }
MainActivity.java
public class MainActivity extends AppCompatActivity { Button mPhp_get; Button mPhp_send; Button mPhp_delete; TextView mTxt_php; EditText mName_edt; EditText mAge_edt; EditText mAddress_edt; String name ; String age ; String address; String mPersonName_get; String mPersonAge_get; String mPersonAddress_get; RecyclerView recycler_layout; List<DateList> lists = new ArrayList<>(); DateAdapter adapter; String phpUrlDelete = "http://192.168.1.189:8800/orcal/delete.php"; String phpUrl = "http://192.168.1.189:8800/orcal/selectbywhere.php"; String phpUrlSend = "http://192.168.1.189:8800/orcal/insert2.php"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); LinearLayoutManager layoutManager = new LinearLayoutManager(this); recycler_layout.setLayoutManager(layoutManager); adapter = new DateAdapter(lists); } private void initView() { mPhp_get = findViewById(R.id.get); mPhp_send = findViewById(R.id.send); mPhp_delete = findViewById(R.id.delete); mPhp_get.setOnClickListener(new mPhpButtonListener()); mPhp_send.setOnClickListener(new mPhpSendButtonListener()); mPhp_delete.setOnClickListener(new mPhpDeleteButtonListener()); mTxt_php = findViewById(R.id.textView); mName_edt = findViewById(R.id.editname); mAge_edt = findViewById(R.id.editage); mAddress_edt = findViewById(R.id.editaddress); recycler_layout = findViewById(R.id.recycler_form); } private class mPhpButtonListener implements View.OnClickListener { @Override public void onClick(View view) { sendText2Okhttp(phpUrl); // mSendOkHttpGet(); lists.clear(); } } private void mSendOkHttpGet() { HttpUtil.sendOkHttpRequest(phpUrl, new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { final String responseDate = response.body().string(); parseJSONWithJSONObject(responseDate); runOnUiThread(new Runnable() { @Override public void run() { mTxt_php.setText(responseDate); mName_edt.setText(name); mAge_edt.setText(age); mAddress_edt.setText(address); } }); } }); } //insert private class mPhpSendButtonListener implements View.OnClickListener { @Override public void onClick(View view) { sendText2Okhttp(phpUrlSend); lists.clear(); } } //delete private class mPhpDeleteButtonListener implements View.OnClickListener { @Override public void onClick(View view) { sendText2Okhttp(phpUrlDelete); lists.clear(); } } //获取EditText里是数发送给PHP private void sendText2Okhttp(final String url) { mPersonName_get = mName_edt.getText().toString(); mPersonAge_get = mAge_edt.getText().toString(); mPersonAddress_get = mAddress_edt.getText().toString(); new Thread(new Runnable() { @Override public void run() { mSendOkHttpPost(url,mPersonName_get,mPersonAge_get, mPersonAddress_get); } }).start(); } private void mSendOkHttpPost(String url,String personname,String personage, String personAddress_get) { HttpUtil.sendOkHttpPost(url, personname,personage, personAddress_get, new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, final Response response) throws IOException { final String responseDate = response.body().string(); runOnUiThread(new Runnable() { @Override public void run() { if (responseDate .equals("[]")||responseDate .equals("") ) { Toast.makeText(MainActivity.this, "没有此数据", Toast.LENGTH_LONG).show(); mTxt_php.setText("没有此数据"); } else { mTxt_php.setText(responseDate); } parseJSONWithJSONObject(responseDate); } }); } }); } private void parseJSONWithJSONObject(String jsonDate) { try { JSONArray jsonArray = new JSONArray(jsonDate); for (int i = 0; i < jsonArray.length(); i++) { JSONObject jsonObject = jsonArray.getJSONObject(i); name = jsonObject.getString("PERSONNAME"); age = jsonObject.getString("PERSONAGE"); address = jsonObject.getString("PERSONADDRESS"); DateList dateList = new DateList(name, age, address); lists.add(dateList); recycler_layout.setAdapter(adapter); } } catch (JSONException e) { e.printStackTrace(); } } }
好了,代码完整贴上了,程序可以运行!
感想:写博客是需要耐心的~,而语言表达能力不好的我只能不停的贴代码。还需努力啊。。。
仰望一下博客写的简单易懂,而且一篇又一篇 的大神们。