http://blog.csdn.net/zhyl8157121/article/details/8169172 http://blog.csdn.net/zhyl8157121/article/details/8169172 其实之前发过一篇这样的博文http://blog.csdn.net/zhyl8157121/article/details/7709552,但那个只是简单记录了一些自己的想法,并没有
http://blog.csdn.net/zhyl8157121/article/details/8169172
http://blog.csdn.net/zhyl8157121/article/details/8169172
其实之前发过一篇这样的博文http://blog.csdn.net/zhyl8157121/article/details/7709552,但那个只是简单记录了一些自己的想法,并没有想作为教程来看,后来由于一些朋友想要源代码,就附上了下载地址,但并没有做什么讲解,从现在开始,准备做一份详细的Android如何连接Sqlserver的教程.由于本人才疏学浅,如果有什么不对的地方欢迎大家批评指正.
为了避免再次被说标题党,这里先说明些事情:
第一,android没法直接连接SQLServer,起码我没有发现方法,想想看,sqlserver安装之后有多大,android程序是跑在手机上的,想让程序直接访问sqlserver,那手机要多大的内存?
第二,本文是通过一个“桥梁”——webservice来间接访问SQLServer的,当然还有其他方法,感兴趣的同学可以自行百度。
如果理解了上面两点,好了咱们继续。
教程会拿一个具体的例子来讲,一步一步来,也许细节上还可以继续加工,但大致的流程就是这样的。
本教程有五个部分:
项目说明
开发环境部署
数据库设计
服务器端程序设计
客户端(android端)程序设计
项目说明
这个项目意在实现一个简单的android连接Sqlserver的功能。
就做一个简单的库存管理功能,包括对仓库内现有货物的查看、货物信息的增加&删除。
开发环境的部署
今天主要讲解第一个部分,开发环境的部署.
操作系统:Windows764bit旗舰版
当然这个是什么基本无所谓,只是我是在这上面开发的,不过家庭普通版的貌似不能配置IIS,就是咱们后面要使用的一个服务.
android端:eclipse + ADT集成开发环境
相信看到这个教程的基本都知道如何做这些了.如果真的是有哪位同学android开发环境没有配置好而来看这篇教程,请先移步->www.google.com
服务器端:VisualStudio 2010旗舰版
这个是用来写website/webservice的,开发语言使用C# (即.net)
数据库:SQLServer2008 R2
其实这个是什么版本也无所谓吧,教程使用的都是比较基本的东西,所以版本的差异基本可以忽略。
IIS 7.5:正确配置并开启IIS服务
如果想将website/webservice发布出去就要开启这个服务。但是如果仅仅是在本地进行测试就不需要配置,直接在VS中运行就可以。
其实我在开发的时候也只是配置IIS的时候遇到了一些问题,这里给出IIS的配置方法.
http://wenku.baidu.com/view/95cf9fd9ad51f01dc281f1af.html这篇文库给的还是很详细的,我当初就是照着这个配置的。
数据库设计
数据库名称:StockManage
表设计
表名称:C
表说明:
列名
中文名称
数据型态
必填
说明
Cno
货物编号
Int
V
主键,自增
Cname
货物名称
String
Cnum
货物数量
Int
下图是设计表的时候的截图。
向表中输入内容
吐槽一下:为什么这里猫、狗、电话都有,甚至还有Surface?!这只能说当时LZ在想这些……
服务器端程序设计(Webservice)
其实服务端可以写成webservice也可以写成website,前者只是提供一种服务,而后者是可以提供用户界面等具体的页面,后者也就是咱们平时所说的“网站”。
两者的区别:
Web Service 只提供程序和接口,不提供用户界面
Web Site 提供程序和接口,也提供用户界面(网页)
由于咱们只是需要一个中介来访问sqlserver,所以写成webservice足够了。
目标:写一个Website访问Sqlserver,获取数据并转换成xml格式,然后传递给android客户端。
1. 新建一个Webservice工程
2. 视图 -> 其它窗口 -> 服务器资源管理器
3. 右键数据连接 -> 添加连接
4. 选择Microsoft Sqlserver
5. 如下图所示选择(可以点击测试连接来检测连接是否成功,然后点击确定)
6. 数据库的查看和编辑也可以在VS中进行了
7. 先查看一下数据库属性并记录下连接属性
8. 新建一个类DBOperation,代码如下:
[csharp] view
plaincopyprint?
usingSystem;
usingSystem.Data;
usingSystem.Configuration;
usingSystem.Linq;
usingSystem.Web;
usingSystem.Web.Security;
usingSystem.Web.UI;
usingSystem.Web.UI.HtmlControls;
usingSystem.Web.UI.WebControls;
usingSystem.Web.UI.WebControls.WebParts;
usingSystem.Xml.Linq;
usingSystem.Data.SqlClient;
usingSystem.Text.RegularExpressions;
usingSystem.Collections;
usingSystem.Collections.Generic;
namespaceStockManageWebservice
{
///
/// 一个操作数据库的类,所有对SQLServer的操作都写在这个类中,使用的时候实例化一个然后直接调用就可以
///
publicclassDBOperation:IDisposable
{
publicstaticSqlConnection sqlCon;//用于连接数据库
//将下面的引号之间的内容换成上面记录下的属性中的连接字符串
privateString ConServerStr = @"Data Source=BOTTLE-PC;Initial Catalog=StockManage;Integrated Security=True";
//默认构造函数
publicDBOperation()
{
if(sqlCon ==null)
{
sqlCon = newSqlConnection();
sqlCon.ConnectionString = ConServerStr;
sqlCon.Open();
}
}
//关闭/销毁函数,相当于Close()
publicvoidDispose()
{
if(sqlCon !=null)
{
sqlCon.Close();
sqlCon = null;
}
}
///
/// 获取所有货物的信息
///
/// 所有货物信息
publicList selectAllCargoInfor()
{
List list =newList();
try
{
stringsql ="select * from C";
SqlCommand cmd = newSqlCommand(sql,sqlCon);
SqlDataReader reader = cmd.ExecuteReader();
while(reader.Read())
{
//将结果集信息添加到返回向量中
list.Add(reader[0].ToString());
list.Add(reader[1].ToString());
list.Add(reader[2].ToString());
}
reader.Close();
cmd.Dispose();
}
catch(Exception)
{
}
returnlist;
}
///
/// 增加一条货物信息
///
/// 货物名称
/// 货物数量
publicboolinsertCargoInfo(stringCname,intCnum)
{
try
{
stringsql ="insert into C (Cname,Cnum) values ('"+ Cname +"',"+ Cnum +")";
SqlCommand cmd = newSqlCommand(sql, sqlCon);
cmd.ExecuteNonQuery();
cmd.Dispose();
returntrue;
}
catch(Exception)
{
returnfalse;
}
}
///
/// 删除一条货物信息
///
/// 货物编号
publicbooldeleteCargoInfo(stringCno)
{
try
{
stringsql ="delete from C where Cno="+ Cno;
SqlCommand cmd = newSqlCommand(sql, sqlCon);
cmd.ExecuteNonQuery();
cmd.Dispose();
returntrue;
}
catch(Exception)
{
returnfalse;
}
}
}
}
9. 修改Service1.asmx.cs代码如下:
[csharp] view
plaincopyprint?
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Web;
usingSystem.Web.Services;
namespaceStockManageWebservice
{
///
/// Service1 的摘要说明
///
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。
// [System.Web.Script.Services.ScriptService]
publicclassService1 : System.Web.Services.WebService
{
DBOperation dbOperation = newDBOperation();
[WebMethod]
publicstringHelloWorld()
{
return"Hello World";
}
[WebMethod(Description = "获取所有货物的信息")]
publicstring[] selectAllCargoInfor()
{
returndbOperation.selectAllCargoInfor().ToArray();
}
[WebMethod(Description = "增加一条货物信息")]
publicboolinsertCargoInfo(stringCname,intCnum)
{
returndbOperation.insertCargoInfo(Cname, Cnum);
}
[WebMethod(Description = "删除一条货物信息")]
publicbooldeleteCargoInfo(stringCno)
{
returndbOperation.deleteCargoInfo(Cno);
}
}
}
10. 运行程序(F5),会自动打开一个浏览器,可以看到如下画面:
11. 选择相应的功能并传递参数可以实现调试从浏览器中调试程序:
下图选择的是增加一条货物信息
12. 程序执行的结果:
13.另,记住这里的端口名,后面android的程序中添入的端口号就是这个:
客户端(android端)程序设计
程序代码:
1.MainActivity
[java] view
plaincopyprint?
packagecom.bottle.stockmanage;
importjava.util.ArrayList;
importjava.util.HashMap;
importjava.util.List;
importandroid.app.Activity;
importandroid.app.Dialog;
importandroid.os.Bundle;
importandroid.view.Gravity;
importandroid.view.View;
importandroid.view.View.OnClickListener;
importandroid.view.Window;
importandroid.view.WindowManager;
importandroid.widget.Button;
importandroid.widget.EditText;
importandroid.widget.ListView;
importandroid.widget.SimpleAdapter;
importandroid.widget.Toast;
publicclassMainActivityextendsActivity{
privateButton btn1;
privateButton btn2;
privateButton btn3;
privateListView listView;
privateSimpleAdapter adapter;
privateDBUtil dbUtil;
@Override
publicvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn1 = (Button) findViewById(R.id.btn_all);
btn2 = (Button) findViewById(R.id.btn_add);
btn3 = (Button) findViewById(R.id.btn_delete);
listView = (ListView) findViewById(R.id.listView);
dbUtil = newDBUtil();
btn1.setOnClickListener(newOnClickListener() {
@Override
publicvoidonClick(View v) {
hideButton(true);
setListView();
}
});
btn2.setOnClickListener(newOnClickListener() {
@Override
publicvoidonClick(View v) {
hideButton(true);
setAddDialog();
}
});
btn3.setOnClickListener(newOnClickListener() {
@Override
publicvoidonClick(View v) {
hideButton(true);
setDeleteDialog();
}
});
}
/**
* 设置弹出删除对话框
*/
privatevoidsetDeleteDialog() {
finalDialog dialog =newDialog(MainActivity.this);
dialog.setContentView(R.layout.dialog_delete);
dialog.setTitle("输入想要删除的货物的编号");
Window dialogWindow = dialog.getWindow();
WindowManager.LayoutParams lp = dialogWindow.getAttributes();
dialogWindow.setGravity(Gravity.CENTER);
dialogWindow.setAttributes(lp);
finalEditText cNoEditText = (EditText) dialog.findViewById(R.id.editText1);
Button btnConfirm = (Button) dialog.findViewById(R.id.button1);
Button btnCancel = (Button) dialog.findViewById(R.id.button2);
btnConfirm.setOnClickListener(newOnClickListener() {
@Override
publicvoidonClick(View v) {
dbUtil.deleteCargoInfo(cNoEditText.getText().toString());
dialog.dismiss();
hideButton(false);
Toast.makeText(MainActivity.this,"成功删除数据", Toast.LENGTH_SHORT).show();
}
});
btnCancel.setOnClickListener(newOnClickListener() {
@Override
publicvoidonClick(View v) {
dialog.dismiss();
hideButton(false);
}
});
dialog.show();
}
/**
* 设置弹出添加对话框
*/
privatevoidsetAddDialog() {
finalDialog dialog =newDialog(MainActivity.this);
dialog.setContentView(R.layout.dialog_add);
dialog.setTitle("输入添加的货物的信息");
Window dialogWindow = dialog.getWindow();
WindowManager.LayoutParams lp = dialogWindow.getAttributes();
dialogWindow.setGravity(Gravity.CENTER);
dialogWindow.setAttributes(lp);
finalEditText cNameEditText = (EditText) dialog.findViewById(R.id.editText1);
finalEditText cNumEditText = (EditText) dialog.findViewById(R.id.editText2);
Button btnConfirm = (Button) dialog.findViewById(R.id.button1);
Button btnCancel = (Button) dialog.findViewById(R.id.button2);
btnConfirm.setOnClickListener(newOnClickListener() {
@Override
publicvoidonClick(View v) {
dbUtil.insertCargoInfo(cNameEditText.getText().toString(), cNumEditText.getText().toString());
dialog.dismiss();
hideButton(false);
Toast.makeText(MainActivity.this,"成功添加数据", Toast.LENGTH_SHORT).show();
}
});
btnCancel.setOnClickListener(newOnClickListener() {
@Override
publicvoidonClick(View v) {
dialog.dismiss();
hideButton(false);
}
});
dialog.show();
}
/**
* 设置listView
*/
privatevoidsetListView() {
listView.setVisibility(View.VISIBLE);
List> list = newArrayList>();
list = dbUtil.getAllInfo();
adapter = newSimpleAdapter(
MainActivity.this,
list,
R.layout.adapter_item,
newString[] {"Cno","Cname","Cnum"},
newint[] { R.id.txt_Cno, R.id.txt_Cname, R.id.txt_Cnum });
listView.setAdapter(adapter);
}
/**
* 设置button的可见性
*/
privatevoidhideButton(booleanresult) {
if(result) {
btn1.setVisibility(View.GONE);
btn2.setVisibility(View.GONE);
btn3.setVisibility(View.GONE);
} else{
btn1.setVisibility(View.VISIBLE);
btn2.setVisibility(View.VISIBLE);
btn3.setVisibility(View.VISIBLE);
}
}
/**
* 返回按钮的重写
*/
@Override
publicvoidonBackPressed()
{
if(listView.getVisibility() == View.VISIBLE) {
listView.setVisibility(View.GONE);
hideButton(false);
}else{
MainActivity.this.finish();
}
}
}
2.HttpConnSoap
(改类已经过时,更多请参照
http://blog.csdn.net/zhyl8157121/article/details/8709048)
[java] view
plaincopyprint?
packagecom.bottle.stockmanage;
importjava.io.IOException;
importjava.io.InputStream;
importjava.io.OutputStream;
importjava.net.HttpURLConnection;
importjava.net.URL;
importjava.util.ArrayList;
publicclassHttpConnSoap {
publicArrayListGetWebServre(String methodName, ArrayListParameters, ArrayListParValues) {
ArrayListValues = newArrayList();
//ServerUrl是指webservice的url
//10.0.2.2是让android模拟器访问本地(PC)服务器,不能写成127.0.0.1
//11125是指端口号,即挂载到IIS上的时候开启的端口
//Service1.asmx是指提供服务的页面
String ServerUrl = "http://10.0.2.2:11125/Service1.asmx";
//String soapAction="http://tempuri.org/LongUserId1";
String soapAction = "http://tempuri.org/"+ methodName;
//String data = "";
String soap = ""
+ ""
+ "";
String tps, vps, ts;
String mreakString = "";
mreakString = "+ methodName +" xmlns=\"http://tempuri.org/\">";
for(inti =0; i < Parameters.size(); i++) {
tps = Parameters.get(i).toString();
//设置该方法的参数为.net webService中的参数名称
vps = ParValues.get(i).toString();
ts = "+ tps +">"+ vps +""+ tps +">";
mreakString = mreakString + ts;
}
mreakString = mreakString + ""+ methodName +">";
/*
+""
+"string11661"
+"string111"
+ ""
*/
String soap2 = "";
String requestData = soap + mreakString + soap2;
//System.out.println(requestData);
try{