数据库大作业总结 android+Java web+mysql

这是我第一次做和网络相关的程序。虽然之前做过app,但是都没有和网络交互,这次算是从零开始。废话不多说,直接上干货。


开发工具:

  • android:android studio
  • java web:myEclipse(提取密码:ia8f)各种版本,自选合适版本
  • mysql:参考这篇文章进行配置,我尝试了phpMyadmin和mysql
    workbench 来管理数据库,个人感觉phpMyadmin用的较为熟练。
  • 模拟器:genymotion,强烈推荐这个模拟器,速度快,打开android studio创建的模拟器我要开半个小时!(下载genymotion很顺利,但是下载模拟器十分艰难,具体可以参考本人的这篇文章)
  • 服务器:tomcat 7.x 配置方法参考这里

以上环境如果能配置好,基本成功一半。(学习者一定要有耐心,配置环境花个一周我认为很正常)
另外要强调的一点是要有充足的内存。本人是macbook pro 8g内存。如果是其它电脑,建议12g以上内存.


开发流程

其实可以说,要完成这个开发,你要走通3个helloworld:

  • android 端的helloworld,代表你的模拟器和android sdk配置完成
  • java web的helloworld代表你服务器端配置完成
  • 数据库端的helloworld(就是一些select语句,这里为了工整使用helloworld代表)

如果以上信息不会,可以参考android hellowrold程序java web helloworld程序

android端就是平时我们的手机客户端,java web程序放在服务器上,android与java web交互,获取信息,收到android客户端的信息后,java web向数据库请求信息。具体见下面的流程

接下来描述程序的整体流程
1. android端发出http请求(Get请求或者Post请求,不理解也没关系)
2. 服务器端java web程序接受请求。
3. 服务器端java web程序访问数据库,获得返回结果。
4. 服务器端java web程序将返回结果传输给客户端。
5. 客户端得到结果,显示给客户使用。

这里写图片描述

以上是最基本的概念,如果读者还没有跑通3个helloworld,请继续配置环境,如果是已经跑通了所有的helloworld但是对android或者java web的程序结构不太清楚可以参考一下文章,如果都已经完成,那么我们就可以开始开发了。

没有必要完全搞懂,一边做一边学习即可。


通讯过程工具+关键代码

到了这一部分,作者认为读者已经了解如何创建android和java web的程序,并且已经有了基本的sql语句的知识(增、删、查、改)。这一部分纷呈两个模块,第一个模块讲述android如何发送请求,第二个模块讲述java web如何接受请求。

使用的包:

  • gson(将数据打包成json文件格式、将json解析为对象、在android和java web端都可以使用,此包为谷歌工程师开发,必属精品)
  • xutils(此包集结了中国工程师们的智慧,帮助我们极大的简化了网络通讯,代码简化,各种高性能优点)

part one

以下是android端的核心代码,发出一个网络请求,收到查询结果。这是一个登录功能,界面就是两个EditText,当点击登录按钮时发送数据,当访问成功,接收返回数据,在responseInfo.result中,将用户信息存储在sharedPreferce中,并记住登录状态。里面用到了xutils的两个功能

  • HttpUtils:
    send函数

    * 参数:方法(Post或者Get)、访问的网址、参数、返回
    
  • ViewUtils:
    帮助我们方便的找到控件
    现在create方法中调用ViewUtils.Inject方法,在定义控件的时候采用注解的写法,就不需要使用findviewbyid了

SharedPerference是我引入的一个工具类,在后面提供工具类的代码。

LoginActivity.java

package com.example.wxc575843.hellotone.start;

import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.example.wxc575843.hellotone.Practice.PracticeMain;
import com.example.wxc575843.hellotone.R;
import com.example.wxc575843.hellotone.utils.SharePreferenceUtils;
import com.google.gson.Gson;
import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.ViewUtils;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.RequestParams;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack;
import com.lidroid.xutils.http.client.HttpRequest;
import com.lidroid.xutils.view.annotation.ViewInject;
import com.model.Global;
import com.model.User;

public class LoginActivity extends AppCompatActivity {

    private final String TAG = "LoginActivity";

    private String email;
    private String password;

    @ViewInject(R.id.login_email)
    EditText etMail;

    @ViewInject(R.id.login_password)
    EditText etPassword;

    @ViewInject(R.id.btnLogin)
    Button btnLogin;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        ViewUtils.inject(this);

        btnLogin.setOnClickListener(loginLinster);
    }

    Button.OnClickListener loginLinster = new Button.OnClickListener() {
        @Override
        public void onClick(View v) {
            email = etMail.getText().toString().trim();
            password = etPassword.getText().toString();

            Log.d(TAG+"email",email);
            Log.d(TAG+"password",password);
            if (email.isEmpty() || password.isEmpty()){
                Toast.makeText(LoginActivity.this,"sth empty",Toast.LENGTH_SHORT).show();
            }else {
                HttpUtils httpUtils = new HttpUtils();
                RequestParams requestParams = new RequestParams();
                requestParams.addBodyParameter("email",email);
                requestParams.addBodyParameter("password",password);

String url = http://172.29.105.107:8080/HelloToneWebService/servlet/SigninServlet;
            httpUtils.send(HttpRequest.HttpMethod.POST, url, requestParams, new RequestCallBack<String>() {
                    @Override
                    public void onSuccess(ResponseInfo<String> responseInfo) {
                        String rs = responseInfo.result;
                        Log.d(TAG,rs);
                        Gson gson = new Gson();
                        User user = gson.fromJson(rs, User.class);
                        Log.d(TAG,user.getStateCode()+"");
                        if (user.getStateCode()==1){
                            SharePreferenceUtils.putString(LoginActivity.this,"email",user.getEmail());
                            SharePreferenceUtils.putString(LoginActivity.this,"nickname",user.getNickName());
                            SharePreferenceUtils.putString(LoginActivity.this,"gender",user.getGender());
                            SharePreferenceUtils.putString(LoginActivity.this,"country",user.getCountry());
                            SharePreferenceUtils.putString(LoginActivity.this,"chineseLevel",user.getChineseLevel());
                            SharePreferenceUtils.putInt(LoginActivity.this, "level", user.getLevel());
                            SharePreferenceUtils.putString(LoginActivity.this, "headPicture", user.getHeadPicture());
                            SharePreferenceUtils.putInt(LoginActivity.this, "articleNum", user.getArticleNum());
                            SharePreferenceUtils.putInt(LoginActivity.this,"postNum",user.getPostNum());
                            SharePreferenceUtils.putInt(LoginActivity.this,"experience",user.getExperience());
                            SharePreferenceUtils.putString(LoginActivity.this, "password", password);
                            SharePreferenceUtils.putString(LoginActivity.this,"id",user.getId());

                            SharePreferenceUtils.putBoolean(LoginActivity.this,"loginState",true);

                            Log.d(TAG,user.getChineseLevel());

                            Intent intent = new Intent(LoginActivity.this,MainActivity.class);
                            startActivity(intent);
                            finish();
                        } else {
                            Toast.makeText(LoginActivity.this,R.string.login_wrong,Toast.LENGTH_SHORT).show();
                        }
                    }

                    @Override
                    public void onFailure(HttpException e, String s) {
                        Toast.makeText(LoginActivity.this,R.string.register_failed_network,Toast.LENGTH_SHORT).show();
                    }
                });
            }
        }
    };
}

SharePreferenceUtils.java

package com.example.wxc575843.hellotone.utils;

import android.content.Context;
import android.content.SharedPreferences;

/**
 * 专门访问和设置SharePreference的工具类, 保存和配置一些设置信息
 * 
 * @author Kevin
 * 
 */
public class SharePreferenceUtils {

    private static final String SHARE_PREFS_NAME = "preference";
    private static SharedPreferences mSharedPreferences;

    public static void putBoolean(Context ctx, String key, boolean value) {
        if (mSharedPreferences == null) {
            mSharedPreferences = ctx.getSharedPreferences(SHARE_PREFS_NAME,
                    Context.MODE_PRIVATE);
        }

        mSharedPreferences.edit().putBoolean(key, value).commit();
    }

    public static boolean getBoolean(Context ctx, String key,
            boolean defaultValue) {
        if (mSharedPreferences == null) {
            mSharedPreferences = ctx.getSharedPreferences(SHARE_PREFS_NAME,
                    Context.MODE_PRIVATE);
        }

        return mSharedPreferences.getBoolean(key, defaultValue);
    }

    public static void putString(Context ctx, String key, String value) {
        if (mSharedPreferences == null) {
            mSharedPreferences = ctx.getSharedPreferences(SHARE_PREFS_NAME,
                    Context.MODE_PRIVATE);
        }

        mSharedPreferences.edit().putString(key, value).commit();
    }

    public static String getString(Context ctx, String key, String defaultValue) {
        if (mSharedPreferences == null) {
            mSharedPreferences = ctx.getSharedPreferences(SHARE_PREFS_NAME,
                    Context.MODE_PRIVATE);
        }

        return mSharedPreferences.getString(key, defaultValue);
    }

    public static void putInt(Context ctx, String key, int value){
        if (mSharedPreferences == null) {
            mSharedPreferences = ctx.getSharedPreferences(SHARE_PREFS_NAME,
                    Context.MODE_PRIVATE);
        }

        mSharedPreferences.edit().putInt(key,value).commit();
    }

    public static int getInt(Context ctx, String key, int defaultValue) {
        if (mSharedPreferences == null) {
            mSharedPreferences = ctx.getSharedPreferences(SHARE_PREFS_NAME,
                    Context.MODE_PRIVATE);
        }

        return mSharedPreferences.getInt(key, defaultValue);
    }
}

part two

以下时对应的java web端的代码,接收了请求,进入数据库查询,讲返回结果打包成json的形式返回给用户。SigninServlet.java是响应用户请求的后台代码,后面的配置文件和SqlManager代码是连接数据库的工具类

SigninServlet.java

package app.hellotone.web.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import app.hellotone.web.dao.SigninDao;
import app.hellotone.web.model.User;

import org.json.simple.JSONObject;

import com.google.gson.Gson;


public class SigninServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);

    }


    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String email = request.getParameter("email");
        String password = request.getParameter("password");
        User user;
        try {
            SigninDao siginDao = new SigninDao();
            user = siginDao.signIn(email, password);
            Gson gson = new Gson();
            response.setContentType("application/json");
            response.setCharacterEncoding("UTF-8");
            response.getWriter().write(gson.toJson(user));
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


}

SigninDao.java

package app.hellotone.web.dao;

import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;

import app.hellotone.web.model.User;

public class SigninDao {
    SqlManager manager;
    String sql = "";
    ResultSet rs;

    public SigninDao() throws IOException, ClassNotFoundException{
        manager = SqlManager.createInstance();
    }

    public User signIn(String username, String password) throws SQLException{
        boolean success = false;
        this.sql = "select * from UserFull where Email=? and Password=?";
        Object[] params = new Object[]{username,password};
        User user = new User();
        manager.connectDB();
        rs=manager.executeQuery(sql, params);
        if(rs.next()) {
            user.setStateCode(1);
            user.setId(Integer.parseInt(rs.getString("ID")));
            user.setNickName(rs.getString("Nickname"));
            user.setEmail(rs.getString("Email"));
            user.setGender(rs.getString("Gender"));
            user.setCountry(rs.getString("Country"));
            user.setLevel(rs.getInt("ULevel"));
            user.setChineseLevel(rs.getString("汉语水平"));
            user.setHeadPicture(rs.getString("头像"));
            user.setArticleNum(rs.getInt("ArticleNum"));
            user.setPostNum(rs.getInt("PostNum"));
            user.setExperience(rs.getInt("Experience"));
        }
        manager.closeDB();
        return user;
    }
}

Config.propertise

#Set *.properties default encoding UTF-8

#\u6570\u636e\u5e93\u5e95\u5c42\u64cd\u4f5c\u7c7b\u914d\u7f6e\u6587\u4ef6

#\u6307\u5b9a\u4e3b\u673a\u5730\u5740
DBhost=localhost
#\u6307\u5b9a\u7aef\u53e3\u53f7
DBport=3306
#\u6307\u5b9a\u8fde\u63a5\u6570\u636e\u5e93
DBname=HelloTone
#\u6307\u5b9a\u7528\u6237\u540d
DBuser=root
#\u6307\u5b9a\u5bc6\u7801
DBpassword=123456

SqlManager.java

package app.hellotone.web.dao;

/*
 * 数据库操作类,进行数据库底层操作
 * 配置信息在Config.properties文件中
 * Made By:coolszy
 * 2009.07.07
 */

import java.io.IOException;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.PropertyResourceBundle;

public class SqlManager
{
    private static SqlManager manager = null; // 静态成员变量,支持单态模式
    private PropertyResourceBundle bundle; // 配置资源文件
    private static String jdbcDrive = null; // JDBC驱动类型
    private String DBhost = ""; // 数据库主机地址
    private String DBname = ""; // 数据库名
    private String DBprot = ""; // 数据库端口
    private String DBuser = ""; // 数据库用户名
    private String DBpasswd = ""; // 数据库密码
    private String strcon = null; // 连接字符串

    private Connection conn = null; // 连接对象
    private PreparedStatement pstm = null;
    private CallableStatement cstm = null;

    /**
     * 私有构造函数,不可实例化
     * 
     * @throws IOException
     */
    private SqlManager() throws IOException
    {
        // 读取配置文件
        bundle = new PropertyResourceBundle(SqlManager.class
                .getResourceAsStream("Config.properties"));
        this.DBhost = getString("DBhost"); // 读取主机名
        this.DBname = getString("DBname"); // 读取用户名
        this.DBprot = getString("DBport"); // 读取端口
        this.DBuser = getString("DBuser"); // 读取用户
        this.DBpasswd = getString("DBpassword"); // 读取密码
        // 设置mysql数据库的驱动程序和连接字符
        jdbcDrive = "com.mysql.jdbc.Driver";
        strcon = "jdbc:mysql://" + DBhost + ":" + DBprot + "/" + DBname;
    }

    /**
     * 读取配置文件中的值
     * 
     * @param key
     *            配置文件的key
     * @return key对应的值
     */
    private String getString(String key)
    {
        return this.bundle.getString(key);
    }

    /**
     * 单态模式获取实例
     * 
     * @return SqlManager对象
     * @throws IOException
     * @throws ClassNotFoundException 
     */
    public static SqlManager createInstance() throws IOException, ClassNotFoundException
    {
        if (manager == null)
        {
            manager = new SqlManager();
            manager.initDB();
        }
        return manager;
    }

    /**
     * 初始化连接参数,由指定的DBType生成
     * 
     * @throws ClassNotFoundException
     */
    public void initDB() throws ClassNotFoundException
    {
        Class.forName(jdbcDrive);
    }

    /**
     * 连接数据库
     * 
     * @throws SQLException
     */
    public void connectDB() throws SQLException
    {
        conn = DriverManager.getConnection(strcon, DBuser, DBpasswd); // 获取连接
        conn.setAutoCommit(false); // 设置自动提交为false
    }

    /**
     * 断开数据库
     * 
     * @throws SQLException
     */
    public void closeDB() throws SQLException
    {
        if (pstm != null)
        {
            pstm.close();
        }
        if (cstm != null)
        {
            cstm.close();
        }
        if (conn != null)
        {
            conn.close();
        }
    }

    /**
     * 设置PrepareStatement对象中Sql语句中的参数
     * 
     * @param sql
     *            sql语句
     * @param params
     *            参数列表
     * @throws SQLException
     */
    private void setPrepareStatementParams(String sql, Object[] params)
            throws SQLException
    {
        pstm = conn.prepareStatement(sql); // 获取对象
        if (params != null)
        {
            for (int i = 0; i < params.length; i++) // 遍历参数列表填充参数
            {
                pstm.setObject(i + 1, params[i]);
            }
        }
    }

    /**
     * 执行查询
     * 
     * @param sql
     *            sql语句
     * @param params
     *            参数列表
     * @return 返回ResultSet类型的查询结果
     * @throws SQLException
     */
    public ResultSet executeQuery(String sql, Object[] params)
            throws SQLException
    { // 执行查询数据库接口
        ResultSet rs = null;
        manager.setPrepareStatementParams(sql, params); // 填充参数
        rs = pstm.executeQuery(); // 执行查询操作
        return rs;
    }

    /**
     * 更新数据库操作
     * 
     * @param sql
     *            sql语句
     * @param params
     *            参数列表
     * @return 执行操作的结果
     * @throws SQLException
     */
    public boolean executeUpdate(String sql, Object[] params)
            throws SQLException // 执行无返回数据的数据查询,返回值是被改变的书库的数据库项数
    {
        boolean result = false;
        manager.setPrepareStatementParams(sql, params); // 填充参数
        pstm.executeUpdate(); // 执行更新
        manager.commitChange();
        result = true;
        return result;
    }

    /**
     * 提交信息到数据库
     * 
     * @throws SQLException
     */
    private void commitChange() throws SQLException
    {
        conn.commit();
    }
}

到此为止,我们已经完成了总体的交互过程,希望大家能够有所收获,如果还有不明白的,活着我没有讲清楚的地方欢迎在下面提问,我看到会尽快回答。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章