Android学习之路3——数据库SQLite的使用以及Android申请权限

2023-11-16

Android学习之路3——数据库SQLite的使用以及Android申请权限

一、实验题目

  • 数据存储
    • 学习SQLite数据库的使用
    • 学习ContentProvider的使用。
    • 复习Android的界面编程。

二、实现内容

  • 进入程序,可以选择单选按钮决定注册还是登陆
    • Register注册页面
      • 可以选择图片作为头像,如果不选程序则自动用默认图片作为头像
      • Username,Password,Confirm Password不能为空,否则点击“OK”按钮会提示错误,Password输入框和Confirm Password 输入框的内容要一致,否则点击“OK”按钮也会提示错误”Password Mismatch“。
      • 如果Username已经存在,也会提示错误username + “already exists”
      • 注册成功地话会把用户的头像,用户名,密码存入数据库
    • Login登陆界面
      • Username,Password,Confirm Password不能为空,否则点击“OK”按钮会提示错误
      • Username和Password如果不存在数据库里也没法登陆成功,提示错误“Username not existed”
      • 如果成功则跳转到评论页面。
  • 评论页面:
    • 界面是一个已发表评论的列表,一个发评论的输入框,一个按钮用于发送评论
    • 只要评论内容不为空,都能发送,如果为空,点击“Send”按钮时会提示错误。
    • 点击评论列表里的条目,短按会弹出框,里面显示发表该评论的用户名和该用户在手机通讯录里存的手机号码,如果不存在该联系人就写明“Phone number not exist”。
    • 长按评论列表里的条目,如果该评论是由现登陆的用户发出的,弹出框内容是“Delete or not”,点击“YES"会把条目删除,点击”NO“就返回页面;如果该评论是由别的用户发出的,弹出框内容是“Report or not”,点击”YES“则弹出Toast提示”Report Success…"。

三、实验结果

实验结果gif图(以下3个图是连着的)

  • 在这里插入图片描述
  • 在这里插入图片描述
  • 在这里插入图片描述

实验截图

  • 登录界面:

  • 注册界面:

  • 注册一个新用户,头像,用户名,密码存储到数据库里

  • 如果再次输入同样的用户名的话,点击注册会报错:

  • 登录进到Comment页面

  • 如果Comment输入框为空就点击“Send”按钮会提示错误:

  • 点击评论的“点赞图标”,对应的点赞数会增加,点赞图标会变色,如上图所示。

实验步骤

  • Step1 先布局

    • 主页面的布局并不麻烦,外面是官方推荐的约束性布局ConstraintLayout,中间套一个LinearLayout使得全部控件整体居中,然后就一个一个排好控件的位置即可,至于点击Login或Register界面的不同再通过代码动态使得某些控件不可见即可。

    • 评论页面外层是用LinearLayout,上方是一个ListView,下方是评论框EditText和按钮Button,这个不难,下面是ListView里每个条目Item的布局:

      <?xml version="1.0" encoding="utf-8"?>
      <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          xmlns:app="http://schemas.android.com/apk/res-auto"
          android:layout_margin="10dp">
      
          <ImageView
              android:id="@+id/item_portrait"
              android:src="@drawable/me"
              android:layout_width="40dp"
              android:layout_height="40dp" />
      
          <TextView
              android:id="@+id/item_username"
              android:text="username"
              android:textSize="18sp"
              android:textColor="@color/textColor"
              app:layout_constraintLeft_toRightOf="@id/item_portrait"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content" />
      
          <TextView
              android:id="@+id/item_date"
              android:text="20118-11-11 14:15:15"
              android:textSize="10sp"
              android:textColor="@color/textColor"
              app:layout_constraintLeft_toRightOf="@id/item_portrait"
              app:layout_constraintTop_toBottomOf="@id/item_username"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content" />
      
          <TextView
              android:id="@+id/item_comment"
              android:text="comment"
              android:textSize="20sp"
              android:textColor="@color/dividerColor"
              app:layout_constraintLeft_toRightOf="@id/item_portrait"
              app:layout_constraintTop_toBottomOf="@id/item_date"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content" />
      
          <TextView
              android:id="@+id/item_like_num"
              android:text="0"
              android:textSize="15sp"
              app:layout_constraintRight_toLeftOf="@id/item_like_pic"
              app:layout_constraintBottom_toBottomOf="@id/item_like_pic"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content" />
      
          <ImageView
              android:id="@+id/item_like_pic"
              android:src="@drawable/white"
              app:layout_constraintRight_toRightOf="parent"
              app:layout_constraintBottom_toBottomOf="@id/item_username"
              android:layout_width="20dp"
              android:layout_height="20dp" />
      </android.support.constraint.ConstraintLayout>
      
  • Step2:数据库的建立(MyDB.java)

    创建三个表格,用户信息User,评论信息Comment,用户与点赞数的关联表UC下面是MyDB.java的关键代码:

       	public static final String CREATE_USER="create table User ("
              + "username text primary key,"
              + "password text,"
              + "portrait blob)";
      
          public static  final String CREATE_COMMENT = "create table Comment ("
                  + "id integer primary key autoincrement,"
                  + "username text,"
                  + "date text,"
                  + "comment text,"
                  + "likeNum integer)";
      
          public static final String CREATE_UC = "create table UC ("
                  + "id integer primary key autoincrement,"
                  + "commentId integer,"
                  + "username text)";
      	//...
      	@Override
          public void onCreate(SQLiteDatabase db){
              db.execSQL(CREATE_USER);
              db.execSQL(CREATE_COMMENT);
              db.execSQL(CREATE_UC);
              Toast.makeText(mContext,"Create Succeeded",Toast.LENGTH_SHORT).show();
          }
    
  • Step3:为评论的条目信息创建一个类来进行操作(CommentInfo.java),头像可以根据用户名从数据库里读出来。

    public class CommentInfo implements Serializable{
        private int id;
        private String username;
        private String date;
        private String comment;
        private int likeNum;
    
        public CommentInfo(int id,String username,String date,String comment,int likeNum){
            this.id = id;
            this.username = username;
            this.date = date;
            this.comment = comment;
            this.likeNum = likeNum;
        }
    
        public int GetId(){return id;}
        public String GetUsername(){
            return username;
        }
        public String GetDate(){
            return date;
        }
        public String GetComment(){
            return comment;
        }
        public int GetLikeNum(){
            return likeNum;
        }
        public void SetLikeNum(int num){this.likeNum = num;}
    }
    
  • Step4:为ListView设置一个适配器,这个稍微麻烦一点,根据传过来的CommentInfo对象将信息实例到ListView的每一个条目里,头像就根据CommentInfo对象的用户名从User表格里查找出对应的头像;还要更具UC关联表判断对应的条目里的点赞按钮的状态,下面是MyListViewAdapter.java中的getView函数和对应的ViewHolder类。

        @Override
        public View getView(int position, View convertView, ViewGroup parent){
            final CommentInfo item = getItem(position);
            final View view;
            final ViewHolder viewHolder;
            if(convertView == null){
                view = LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
                viewHolder = new ViewHolder();
                viewHolder.portrait = (ImageView)view.findViewById(R.id.item_portrait);
                viewHolder.username = (TextView)view.findViewById(R.id.item_username);
                viewHolder.date = (TextView)view.findViewById(R.id.item_date);
                viewHolder.comment = (TextView)view.findViewById(R.id.item_comment);
                viewHolder.likeNumber = (TextView)view.findViewById(R.id.item_like_num);
                viewHolder.likePic = (ImageView) view.findViewById(R.id.item_like_pic);
                view.setTag(viewHolder);
            }else{
                view = convertView;
                viewHolder = (ViewHolder)view.getTag();
            }
            viewHolder.username.setText(item.GetUsername());
            viewHolder.date.setText(item.GetDate());
            viewHolder.comment.setText(item.GetComment());
            viewHolder.likeNumber.setText(String.valueOf(item.GetLikeNum()));
    
            MyDB dbHelper = new MyDB(view.getContext(),"User.db",null,1);
            final SQLiteDatabase db = dbHelper.getWritableDatabase();
            Cursor cursor = db.rawQuery("select * from User where username = ?",new String[]{item.GetUsername()},null);
            if(cursor.getCount() > 0){
                cursor.moveToFirst();
                byte[] in = cursor.getBlob(cursor.getColumnIndex("portrait"));
                Bitmap bitmap = BitmapFactory.decodeByteArray(in,0,in.length);
                viewHolder.portrait.setImageBitmap(bitmap);
            }
            cursor.close();
            
            cursor = db.rawQuery("select * from UC where commentId = ? and username = ?",new String[]{String.valueOf(item.GetId()),CommentActivity.username});
            if(cursor.getCount() > 0 ){
                viewHolder.likePic.setImageResource(R.drawable.red);
                viewHolder.likePic.setTag(R.drawable.red);
            }else{
                viewHolder.likePic.setImageResource(R.drawable.white);
                viewHolder.likePic.setTag(R.drawable.white);
            }
    
            viewHolder.likePic.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if( R.drawable.white == (Integer)viewHolder.likePic.getTag() ){
                        viewHolder.likePic.setImageResource(R.drawable.red);
                        viewHolder.likePic.setTag(R.drawable.red);
                        item.SetLikeNum(item.GetLikeNum()+1);
                        viewHolder.likeNumber.setText(String.valueOf(item.GetLikeNum()));
                        ContentValues values = new ContentValues();
                        values.put("likeNum",item.GetLikeNum());
                        db.update("Comment",values,"id = ?",new String[]{String.valueOf(item.GetId())});
    
                        values.clear();
                        values.put("commentId",item.GetId());
                        values.put("username",CommentActivity.username);
                        db.insert("UC",null,values);
                    }else{
                        viewHolder.likePic.setImageResource(R.drawable.white);
                        viewHolder.likePic.setTag(R.drawable.white);
                        item.SetLikeNum(item.GetLikeNum()-1);
                        viewHolder.likeNumber.setText(String.valueOf(item.GetLikeNum()));
                        ContentValues values = new ContentValues();
                        values.put("likeNum",item.GetLikeNum());
                        db.update("Comment",values,"id = ?",new String[]{String.valueOf(item.GetId())});
                        values.clear();
    
                        db.delete("UC","commentId = ? and username = ?",new String[]{String.valueOf(item.GetId()),CommentActivity.username});
                    }
                }
            });
            return view;
        }
    
        class ViewHolder{
            ImageView portrait;
            TextView username,date,comment,likeNumber;
            ImageView likePic;
        }
    
  • Step5:MainActivity.java就处理注册与登录的问题,用一个变量记录当前是登陆页面还是注册页面,然后根据状态处理点击“OK”按钮时对应的事件:

    • 如果是登陆界面就检查Username和password是否已存在数据库里 才能正确登陆。

    • 如果是注册界面就检查Username和password的合法性以及是否已经存在该用户。

       okBtn.setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                      if(TextUtils.isEmpty(usernameEdit.getText().toString())){
                          Toast.makeText(MainActivity.this,usernameEdit.getHint().toString()+" cannot be empty",Toast.LENGTH_SHORT).show();
                          return;
                      }else if(TextUtils.isEmpty(passwordEdit.getText().toString())){
                          Toast.makeText(MainActivity.this,"Password cannot be empty",Toast.LENGTH_SHORT).show();
                          return;
                      }
                      if(isInLoginPage){
                          SQLiteDatabase db = dbHelper.getWritableDatabase();
                          Cursor cursor = db.rawQuery("select * from User where username = ? and password = ?",new String[]{usernameEdit.getText().toString(),passwordEdit.getText().toString()});
                          if(cursor.getCount() <= 0){
                              Toast.makeText(MainActivity.this,"uername or password invalid",Toast.LENGTH_SHORT).show();
                              return;
                          }
                          passwordEdit.setText("");
                          Toast.makeText(MainActivity.this,"Correct Password",Toast.LENGTH_SHORT).show();
                          //跳转到评论页面
                          Intent intent = new Intent(MainActivity.this,CommentActivity.class);
                          intent.putExtra("username",usernameEdit.getText().toString());
                          startActivity(intent);
                          cursor.close();
      
                      }else{
                          if(!passwordEdit.getText().toString().equals(confirmPasswordEdit.getText().toString())){
                              Toast.makeText(MainActivity.this,"Password Mismatch",Toast.LENGTH_SHORT).show();
                          }else{
                              SQLiteDatabase db = dbHelper.getWritableDatabase();
                              Cursor cursor = db.rawQuery("select * from User where username = ?",new String[]{usernameEdit.getText().toString()});
                              if(cursor.getCount() > 0){
                                  Toast.makeText(MainActivity.this,usernameEdit.getText().toString()+" already existed",Toast.LENGTH_SHORT).show();
                                  return;
                              }
                              cursor.close();
      
                              Bitmap bitmap = null;
                              if(imageView.getTag().toString().equals("selecting")){
                                  Resources res = getResources();
                                  bitmap = BitmapFactory.decodeResource(res,R.drawable.me);
                              }else{
                                  bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();
                              }
                              ByteArrayOutputStream os = new ByteArrayOutputStream();
                              bitmap.compress(Bitmap.CompressFormat.PNG,100,os);
      
                              ContentValues values = new ContentValues();
                              values.put("username",usernameEdit.getText().toString());
                              values.put("password",passwordEdit.getText().toString());
                              values.put("portrait",os.toByteArray());
                              db.insert("User",null,values);
                              Toast.makeText(MainActivity.this,"Register success..",Toast.LENGTH_SHORT).show();
                          }
      
                      }
                  }
              });
      
    • 难点在手机图片库的读取,Android 6.0以后对程序的权限要求更严格了,除了要在AndroidManifest.xml加入权限声明,还要在代码上动态申请权限:

       imageView.setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                      //申请权限
                      if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
                          ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},RESULT_LOAD_IMAGE);
                      }
                      Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                      startActivityForResult(i,RESULT_LOAD_IMAGE);
                  }
              });
      
    • 如果成功获得权限进行图片的读取后要重写onActivityResult函数对图片进行处理:

      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
      
       	@Override
          protected void onActivityResult(int requestCode,int resultCode,Intent data){
              super.onActivityResult(requestCode,resultCode,data);
              if(requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && data != null){
                  Uri selectedImage = data.getData();
                  String[] filePathColumn = { MediaStore.Images.Media.DATA};
                  Cursor cursor = getContentResolver().query(selectedImage,filePathColumn,null,null,null);
                  cursor.moveToFirst();
                  int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                  String picturePath = cursor.getString(columnIndex);
                  cursor.close();
      
                  BitmapFactory.Options options = new BitmapFactory.Options();
                  // options 设为true时,构造出的bitmap没有图片,只有一些长宽等配置信息,但比较快,设为false时,才有图片
                  options.inJustDecodeBounds = true;
                  int scale = (int)(options.outWidth / (float)100);
                  if(scale <= 0){
                      scale = 1;
                  }
                  options.inSampleSize = scale;
                  options.inJustDecodeBounds = false;
                  Bitmap bitmap = BitmapFactory.decodeFile(picturePath,options);
                  imageView.setImageBitmap(bitmap);
                  if(bitmap != null){
                      imageView.setTag("selected");
                  }
                  Log.d("SELECEIMAGE",imageView.getTag().toString());
              }
          }
      
  • Step6:评论页面CommentActivity.java

    • 点击SEND按钮的事件处理,如果评论消息不为空即会发送成功,并写入数据库:

      sendBtn.setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                      if(TextUtils.isEmpty(commentEdit.getText().toString())){
                          Toast.makeText(CommentActivity.this,"Comment cannot be empty",Toast.LENGTH_SHORT).show();
                          return;
                      }
                      SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                      Date date = new Date(System.currentTimeMillis());
                      String dateString = simpleDateFormat.format(date);
      
                      SQLiteDatabase db = dbHelper.getWritableDatabase();
                      ContentValues values = new ContentValues();
                      values.put("username",username);
                      values.put("date",dateString);
                      values.put("comment",commentEdit.getText().toString());
                      values.put("likeNum",0);
                      db.insert("Comment",null,values);
                      Cursor cursor = db.rawQuery("select * from Comment",null,null);
                      if(cursor.moveToLast()){
                          CommentInfo item = new CommentInfo(cursor.getInt(cursor.getColumnIndex("id")),username,dateString,commentEdit.getText().toString(),0);
                          itemList.add(item);
                          myListViewAdapter.notifyDataSetChanged();
                      }
                      commentEdit.setText("");
                  }
              });
      
    • 进入该页面时先初始化页面的内容,即从数据库读取存好的评论信息然后显示在ListView里:

       	public void InitList(){
              SQLiteDatabase db = dbHelper.getWritableDatabase();
              Cursor cursor = db.rawQuery("select * from Comment",null,null);
              if(cursor.moveToFirst()){
                  do{
                      int id = cursor.getInt(cursor.getColumnIndex("id"));
                      String username = cursor.getString(cursor.getColumnIndex("username"));
                      String date = cursor.getString(cursor.getColumnIndex("date"));
                      String comment = cursor.getString(cursor.getColumnIndex("comment"));
                      int likeNum = cursor.getInt(cursor.getColumnIndex("likeNum"));
                      CommentInfo commentInfo = new CommentInfo(id,username,date,comment,likeNum);
                      itemList.add(commentInfo);
                  }while(cursor.moveToNext());
              }
              cursor.close();
          }
      
    • 对ListView列表的每一项长按是删除或举报(这取决于当前登录的用户与点击的该评论的发起者是不是同一个用户),如果是删除的话,除了要在listview上显示还要同时更新对应的数据库内容:

      listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
                  @Override
                  public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                      final int removePos = position;
                      AlertDialog.Builder dialog = new AlertDialog.Builder(CommentActivity.this);
                      if(username.equals(itemList.get(position).GetUsername())){
                          dialog.setTitle("Delete or not?");
                          dialog.setPositiveButton("YES", new DialogInterface.OnClickListener() {
                              @Override
                              public void onClick(DialogInterface dialog, int which) {
                                  SQLiteDatabase db = dbHelper.getWritableDatabase();
                                  Log.d("SELECTITEM",String.valueOf(itemList.get(removePos).GetId()));
                                  db.delete("Comment","id = ?" ,new String[]{String.valueOf(itemList.get(removePos).GetId())});
                                  itemList.remove(removePos);
                                  myListViewAdapter.notifyDataSetChanged();
                              }
                          });
                      }else{
                          dialog.setTitle("Report or not?");
                          dialog.setPositiveButton("YES", new DialogInterface.OnClickListener() {
                              @Override
                              public void onClick(DialogInterface dialog, int which) {
                                  Toast.makeText(CommentActivity.this,"Already reported.",Toast.LENGTH_SHORT).show();
                              }
                          });
                      }
      
                      dialog.setNegativeButton("NO", new DialogInterface.OnClickListener() {
                          @Override
                          public void onClick(DialogInterface dialog, int which) {
                          }
                      });
                      dialog.show();
                      return true;
                  }
              });
      
    • 对ListView列表的短按操作是读取通讯录里与当前登录的用户名相同的联系人电话信息,与读取图片一样,要在AndroidManifest申明权限还要在代码动态申请:

      <uses-permission android:name="android.permission.READ_CONTACTS"/>
      
      listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                  @Override
                  public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                      if(ContextCompat.checkSelfPermission(CommentActivity.this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED){
                          ActivityCompat.requestPermissions(CommentActivity.this, new String[]{Manifest.permission.READ_CONTACTS},1);
                      }else{
                          AlertDialog.Builder dialog = new AlertDialog.Builder(CommentActivity.this);
                          dialog.setTitle("Info").setPositiveButton("ok", new DialogInterface.OnClickListener() {
                              @Override
                              public void onClick(DialogInterface dialog, int which) {
                              }
                          });
                          Cursor cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME+" = ?",new String[]{itemList.get(position).GetUsername()},null);
                          if(cursor.moveToFirst()){
                              //String displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                              String phoneNumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                              dialog.setMessage("Username: "+itemList.get(position).GetUsername() + "\nPhone: " + phoneNumber);
                          }else{
                              dialog.setMessage("Username: "+itemList.get(position).GetUsername() + "\nPhone number not exist.");
                          }
                          dialog.show();
                          cursor.close();
                      }
                  }
              });
      

参考资料:

完整代码见我的Github

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android学习之路3——数据库SQLite的使用以及Android申请权限 的相关文章

  • 三种常用的朴素贝叶斯实现算法——高斯朴素贝叶斯、伯努利朴素贝叶斯、多项式朴素贝叶斯

    在sklearn中 提供了若干种朴素贝叶斯的实现算法 不同的朴素贝叶斯算法 主要是对P xi y 的分布假设不同 进而采用不同的参数估计方式 我们能够发现 朴素贝叶斯算法 主要就是计算P xi y 一旦P xi y 确定 最终属于每个类别的
  • 入门解决迷宫问题和算法DFS(递归+回溯)(C语言)

    代码中用for语句代用了下面的4个if语句 include
  • c 语言 多实例测试

    题目描述 求n个整数的和 输入 输入第一行是一个整数T 表示有T组测试实例 每组输入包括两行 第一行一个数n表示接下来会有n个整数 第二行空格隔开的n个数 输出 对于每组输入 在一行输出n个数的和 保证和不会超出int类型的范围 样例输入
  • Vue项目中的富文本插件表格、字号相关问题

    vue quill editor字号自定义 在近日开发项目过程中需要用到富文本 不过样式和工具栏需要按照需求来自定义 我首先想到的是用vue quill editor 不过vue quill editor的字号是以large small这类
  • FileInputFormat详解

    转载 http blog csdn net hellozpc article details 45771933 https my oschina net leejun2005 blog 133424 1 概述 我们在设置MapReduce输
  • ThinkPhp5.1快速创建模块

    快速生成模块 生成一个test模块的指令如下 gt php think build module test 表示自动生成test模块 自动生成的模块目录包含了config controller model和view目录以及common ph
  • 【内存泄漏】- 4. 使用python的gc+pyrasite模块检测python内存泄漏

    Python内存泄漏测试 1 Python内存泄漏处理机制 为了解决内存泄漏的问题 Python2 0的版本开始引入 引用计数 并基于引用计数实现了自动垃圾收集 后来为了解决循环引用导致内存泄漏的问题 又引入 标记 清除 分代回收 机制 P
  • Java实现图片上传

    使用 IDEA 软件 实现文件上传 结合JSP form表单及Servlet 实现文件上传 一 JSP界面 HTML界面 配置 实现文件上传需要配置form表单 基本设置 其中固定两个值是 提交方式只能为post enctype是固定的
  • 瑞萨电子TPS-1教学-第一讲TPS-1 PROFINET Demo Board概述 视频

    瑞萨电子TPS 1教学 第一讲TPS 1 PROFINET Demo Board概述 Renesas
  • 【深度好文】企业数字化转型的核心要素及能力架构分析

    数字化转型究竟是什么 首先我们还是摘录下百度词条上对数字化转型的一个简单说明如下 数字化转型是建立在数字化转换和数字化升级基础上 进一步触及公司核心业务 以新建一种商业模式为目标的高层次转型 数字化转型是开发数字化技术及支持能力以新建一个富
  • 72. Edit Distance

    Given two words word1 and word2 find the minimum number of steps required to convert word1 to word2 each operation is co
  • Self-attention计算方法

    三个矩阵 首先 Inputs为x1 x4 是一个sequence 每一个Input先通过一个Embedding 乘上一个Matrix得到 a1 a4 然后放入self attention 在self attention当中 每一个Input
  • Qt中的C++指针

    Qt中的C 指针 q ptr 在私有类中定义一个名字为q ptr 类型为公有类的数据指针 通过这个指针来访问公有类的数据 d ptr 在公有类中定义一个名字为d ptr 类型为私有类的数据指针 通过这个指针来访问私有类的数据 具体定义在qg
  • C语言

    要求设计的管理系统能够实现以下功能 1 每一条记录包括一个学生的学号 姓名 3个成绩 平时成绩 作业成绩 考试成绩 2 成绩录入功能 成绩信息用文件保存 可以一次完成若干条记录 3 成绩信息显示浏览功能 完成全部学生记录的显示 4 查询功能

随机推荐

  • elasticsearch 集群no known master node

    为什么80 的码农都做不了架构师 gt gt gt It is usually handled automatically If autodiscovery doesn t work Edit the elastic search conf
  • 装饰器在js中的实现原理

    在项目中总是能看到 connect Debounce 巴拉巴拉 通过百度才知道它叫做装饰器 装饰器有什么好 比如说 当我们写好了一个组件它叫做纯洁 当时在创造它的时候我们只想让它做一件事 但是突然有人告诉你我要加一个功能 可是我又不想让我的
  • 医学图像配准软件 ANTs(Advanced Normalization Tools)的安装和使用说明

    本文是关于医学图像配准软件 ANTs Advanced Normalization Tools 的安装和使用说明 ANTs ANTs 是 Advanced Normalization Tools 的缩写 是基于 C 语言的一个医学图像处理的
  • 利用openslide-python处理病理

    参考 博客总结https www jianshu com p bd5b572b5269 官方文档 https openslide org api python module openslide 获取元信息 如每个像素有多少微米 import
  • 杭电ACM 第2036题

    include
  • Linux 定时备份mysql数据并同步到其他mysql服务器中

    备份还原操作 导出数据库 usr bin mysqldump u root pwd database gt database sql 导入数据库 mysql u root p database lt database sql 备份到压缩文件
  • Android 实现WebView

    activity main xml
  • Git首次提交代码到仓库步骤(资料)

    第一步 登陆码云 第二步 创建一个 新的项目 第三步 创建成功后到这个页面 Git 全局设置 git config global user name 意米 git config global user email 142453222851
  • 数据结构<1>时间复杂度详解和leetcode例题

    文章目录 什么是时间复杂度和空间复杂度 前言 算法效率 时间复杂度的计算 空间复杂度的计算 oj练习 什么是时间复杂度和空间复杂度 前言 算法效率 算法效率分析分为两种 第一种是时间效率 第二种是空间效率 时间效率被称为时间复杂度 而空间效
  • Java与WCF交互(一):Java客户端调用WCF服务

    第一步 生成WCF服务 新建WCF解决方案 分别添加三个项目 HelloTimeService 类库 HelloTimehost 控制台程序 HelloTimeClient 控制台程序 项目结构如图 各个项目的主要代码 service Ho
  • 无人机的基本知识

    一 无人机的定义 无人驾驶飞机是指由动力驱动 不搭载操作人员的一种空中飞行器 它依靠空气动力为飞行器提供升力 能够自主或遥控飞行 能携带多种任务设备 执行多种任务 可一次性或多次重复使用的无人驾驶航空器 简称无人机 Unmanned Aer
  • Java Web JSP开发模型

    看之前先点赞 1 JSP开发模型 为了方便使用JSP技术 SUN公司玮JSP技术提供了两种开发模型 JSP Mode1 和 JSP Mode2 JSP Mode1 JSP Mode2 我们将按照Model2思想来完成用户注册功能 1 创建项
  • LUA延时控制

    LUA延时控制 与C 交互实现 其它可参考方式 Lua封装延时执行函数 LUA的延时调用功能 Sleep Function 与C 交互实现 通过C 提供Sleep函数给LUA调用即可 可以任意实现 比如超过5秒再提示相应倒计时功能 if f
  • 听说你搞过架构设计?来,我这里有个系统设计一下...

    V xin ruyuan0330 获得600 页原创精品文章汇总PDF 目录 一 前情提示 二 选择性订阅部分核心数据 三 RabbitMQ的queue与exchange的绑定回顾 四 direct exchange实现消息路由 五 按需订
  • 【云原生

    目录 K8s 控制器 Replicaset 一 Replicaset 控制器 概念 原理解读 1 1 Replicaset 概述 1 2 Replicaset 工作原理 如何管理 Pod 二 Replicaset 资源清单文件编写技巧 三
  • centos 启用远程日志功能_CentOS7下搭建Rsyslog Server记录远程主机系统日志

    rsyslog是一个快速处理收集系统日志的开源程序 提供了高性能 安全功能和模块化设计 rsyslog 是syslog 的升级版 它将多种来源输入输出转换结果到目的地 rsyslog被广泛用于Linux系统以通过TCP UDP协议转发或接收
  • yaml数组解析_YAML详解

    1 YAML简介 YAML 即YAML Ain t Markup Language的缩写 YAML 是一种简洁的非标记语言 YAML以数据为中心 使用空白 缩进 分行组织数据 从而使得表示更加简洁易读 YAML的在线Demo这个YAML转化
  • 使用卷积神经网络(CNN)算法进行多变量时间序列预测的实战教程(Python)

    使用卷积神经网络 CNN 算法进行多变量时间序列预测的实战教程 Python 深度学习在多变量时间序列预测中展现了广泛的应用前景 其中卷积神经网络是最为经典的算法之一 本篇文章将通过一个实例 介绍如何使用卷积神经网络算法来预测交通流量情况
  • 21道常见Transformer面试题(GPT4帮你搞定)

    最近看到一篇关于Transfomer的面试题 写的挺好的 美中不足的是回答的有点简单 刚好我PLUS还没过期 就想着将问题放给无所不能的GPT4来解答 有什么问题欢迎留言私信我好及时修改 不能误人子弟嘿嘿 接下来一起瞧瞧吧 目录部分 按需查
  • Android学习之路3——数据库SQLite的使用以及Android申请权限

    Android学习之路3 数据库SQLite的使用以及Android申请权限 一 实验题目 数据存储 学习SQLite数据库的使用 学习ContentProvider的使用 复习Android的界面编程 二 实现内容 进入程序 可以选择单选