ng8 go 图片&聊天

一、angular

1、总目录
在这里插入图片描述
2、代码

chat.comment.html

<div class="chatroom">
     <div class="chathello">
          Pagge聊天室
          <button>
               <a [routerLink]="['/friends', userid]">返回</a>
          </button>
          <div style="float: right;margin: 5px;color: rgb(162, 165, 47);">{{friename}}</div>
     </div>
     <div class="p_detial" id="autore">
          <div class="p_content"  *ngFor="let users of messagelist ">
                {{  judge(users.sid )  }}   {{users.time}}  
                <br>     {{ users.message }}
                <br>
                <div  *ngIf="users.imgid!=0">
                    <img [(src)]="imgurl[users.imgid] " >
                </div>
                <!-- <div  [innerHTML]="userreceiveimg(users.imgid)"></div> -->
                 <!-- <br>              {{userreceiveimg(users.imgid)}} -->
                <hr>
            </div>
     </div>
     <div>
         <textarea class="yourwrite" placeholder="输入你的文字"  [(ngModel)]="textm" ></textarea>
         <input type="file" class="yourpicture"  id="newUpload" (change)="getUpload($event)" >

        <h6>*仅接受图片文件</h6>
         <button class="yoursent"  (click)="usersendmessage()">发送</button>
    </div>
</div>

chat.comment.scss

.chatroom{

    width: 440px;

    height: 550px;

    margin: 100px auto;

    background-color: #ffffff42;

    padding: 15px;

    border: 1px solid #0066da;

}

.chathello{

    width: 430px;

    height: 28px;

    padding: 8px;

    border: 0px solid #0066daa6;

    button{

        width: 65px;

        height: 30px;

        float: right;

   }

   img{

        width: 50px;

        height: 30px;

        margin: 0px 34px 0px 0px;

        float: right;

    }

}

.p_detial{

    width: 440px;

    height: 300px;

    background-color: #f0f6ff;

    padding: 0px;

    margin: 0px;

    border: 0px solid #0066da61;

    float: left;

    overflow: scroll;

    overflow-x: hidden;

    img{

        width: 100px;

        height: 60px;

        margin: 0px 34px 0px 0px;

        float: center;

    }

}

.yourwrite{

    width: 435px;

    height: 100px;

    margin: 5px 0px 0px 0px;

    overflow: scroll;

    overflow-x: hidden;

}

.yourpicture{

    width: 430px;

    height: 24px;

    border: 5px solid #dee2e661;

}

.yoursent{

    margin: 0px 15px 10px 364px;

    width: 63px;

    height: 40px;

}

h6{

    margin: 0px 0px 0px 0px;

}

chat.comment.ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { CommonService } from '../../services/common.service';
import { flushMicrotasks } from '@angular/core/testing';
import { DomSanitizer } from '@angular/platform-browser';

@Component({
  selector: 'app-chat',
  templateUrl: './chat.component.html',
  styleUrls: ['./chat.component.scss']
})
export class ChatComponent implements OnInit {
  // public domain:string='';
  // public list:any[]=[];
  constructor(public sanitizer: DomSanitizer,
              public route:ActivatedRoute,
              public common:CommonService ) {
      // this.domain=this.common.domain;
   }
   public userid :any
   public frieid :any
   public friename :any=""
  ngOnInit() {
    this.route.params.subscribe((value:any)=>{
        this.userid = value.userid
        this.frieid = value.frieid
        this.friename = value.friename
        this.userreceiveMessage(this.userid, this.frieid)
    })
  }

  public messagelist:any[]=[];

  userreceiveMessage(uid, fid){
    this.common.receive(uid, fid).then((Response:any)=>{
      console.log(Response);
      if(Response.status==-1){
        alert("获取消息列表失败")
        return
       }
       this.messagelist = Response.messageList
       this.userreceiveimg()
    })
    return 
  }

  judge(sid){
      if ( sid== this.userid){
        return "我"
      }else{
        return this.friename
      }
  }
  

  public imgurl :any[]=[]
  userreceiveimg(){
    this.imgurl[0]=""
    var n:any = this.messagelist.length;
    for(var i =0; i<n; i++){
      var id:any =this.messagelist[i].imgid
      if(id==0){
        continue
      }
     this.createimgurl(id)
    }
    console.log(this.imgurl)

  }
  createimgurl(id){
    this.common.receiveimg(id).then((Response:any)=>{
      //   this.createImageFromBlob(Response);
        console.log( Response);
        let reader = new FileReader();
        reader.readAsDataURL(Response);
        reader.onload = () => {
        var fileBase64 = <string>reader.result  //读取该文件base64编码
        //  var url = "data:image/jpeg;base64,"+fileBase64
        // var url = fileBase64
         this.imgurl[id] = this.sanitizer.bypassSecurityTrustResourceUrl(fileBase64); 
        }

      })
  }





  public textm :any=""
  public imgm :any
  public imageid:any
  
  public getUpload(e) {
    if (e.target.files[0]) {
      this.imgm = e.target.files[0];
    }
  }


  usersendmessage(){

    // var files = $('#images').prop('files');
      // console.log(files);
      // var data = new FormData();
      // data.append('image',this.imgm);
      console.log( this.imgm)

    if( this.imgm ){
      this.common.sendimg(this.imgm).then((Response:any)=>{
        console.log(Response);
        // var list = Object.assign([], Response);
        // console.log("list :"+list);
        if(Response.stauts==-1){
          alert("发送图片失败 "+ Response.msg)
          return
         }
         this.imageid = Response.id+""
        // var imid :String = Response.id
        //  console.log("imgid: "+ this.imageid);
         console.log("imgid: "+ this.imageid);
         console.log(typeof  this.imageid);

          this.common.send(this.userid, this.frieid, this.textm, this.imageid).then((Response:any)=>{
           console.log(Response);
              if(Response.status==-1){
                  alert("发送消息失败")
              }
           })
      })
    }else{
      this.imageid="0"
      console.log("textm: "+ this.textm);
      console.log("imgid: "+ this.imageid);
      this.common.send(this.userid, this.frieid, this.textm, this.imageid).then((Response:any)=>{
        console.log(Response)
        if(Response.status==-1){
          alert("发送消息失败:"+Response.msg)
         }
      })
    }
    window.location.reload()
   
    return 
  }

}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { HttpClientModule,HttpClientJsonpModule } from '@angular/common/http';
import { CommonService } from './services/common.service';
import { FormsModule } from '@angular/forms';
import {RouterModule} from '@angular/router';
import { CookieService } from 'ngx-cookie-service';
// import {ChangeDetectionStrategy } from '@angular/core';


import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { UserloginComponent } from './components/userlogin/userlogin.component';
import { UserregisterComponent } from './components/userregister/userregister.component';
import { ChatComponent } from './components/chat/chat.component';
import { FriendsComponent } from './components/friends/friends.component';
import { ManageComponent } from './components/manage/manage.component';

@NgModule({
  declarations: [
    AppComponent,
    UserloginComponent,
    UserregisterComponent,
    ChatComponent,
    FriendsComponent,
    ManageComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    HttpClientJsonpModule,
    FormsModule,
    RouterModule,
    
  ],
  providers: [
    CookieService,
    CommonService
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

comment.service.ts

import { Injectable } from '@angular/core';
import { HttpClient,HttpHeaders} from '@angular/common/http';


@Injectable({
  providedIn: 'root'
})

export class CommonService {
  
  constructor(public http:HttpClient) { }
  // get(api){
  //    return new Promise((resolve,reject)=>{
  //      this.http.get(this.domain+api).subscribe((response)=>{
  //         resolve(response);
  //      });
  //    })
  // }

  public domain:string='http://localhost:8888'; 
  register(name, phone, mail, pw){
    var url =this.domain+"/register"
    const headers = new HttpHeaders({'Content-Type': 'application/x-www-form-urlencoded'});
    let data = { 
      username: name, 
      userphone: phone, 
      usermail: mail, 
      password: pw
    };
    return new Promise((resolve,reject)=>{
      this.http.post(url, data, {headers: headers}).subscribe((response)=>{
         resolve(response);
      });
    })
  }

  login(info, pw){
    var url =this.domain+"/login"
    const headers = new HttpHeaders({'Content-Type': 'application/x-www-form-urlencoded'});
    let data = { 
      useraccount: info, 
      password: pw
    };
    return new Promise((resolve,reject)=>{
      this.http.post(url, data, {headers: headers}).subscribe((response)=>{
         resolve(response);
      });
    })
  }

  show(id){
    var url =this.domain+"/show"
    const headers = new HttpHeaders({'Content-Type': 'application/x-www-form-urlencoded'});
    let data = { 
      userid: id
    };
    return new Promise((resolve,reject)=>{
      this.http.post(url, data, {headers: headers}).subscribe((response)=>{
         resolve(response);
      });
    })
  }

  check(id){
    var url =this.domain+"/check"
    const headers = new HttpHeaders({'Content-Type': 'application/x-www-form-urlencoded'});
    let data = { 
      userid: id
    };
    return new Promise((resolve,reject)=>{
      this.http.post(url, data, {headers: headers}).subscribe((response)=>{
         resolve(response);
      });
    })
  }

  receive(uid, fid){
    var url =this.domain+"/receive"
    const headers = new HttpHeaders({'Content-Type': 'application/x-www-form-urlencoded'});
    let data = { 
      userid :uid,
      userfriendid :fid
    };
    return new Promise((resolve,reject)=>{
      this.http.post(url, data, {headers: headers}).subscribe((response)=>{
         resolve(response);
      });
    })
  }

  receiveimg(id){
    var url =this.domain+"/sendimg?id="+id
    console.log(url)
    return new Promise((resolve,reject)=>{
      this.http.get(url, { responseType: 'blob' }).subscribe((response)=>{
         resolve(response);
      });
    })
 }
//  receiveimg(id)  {
//   var url =this.domain+"/sendimg?id="+id
//   console.log(url)
//   return this.http.get(url, { responseType: 'blob' });
// }

 send(ssid, rrid, mes, mid){
  var url =this.domain+"/send"

  const headers = new HttpHeaders({'Content-Type': 'application/x-www-form-urlencoded'});
  let data = { 
    sid: ssid,
    rid: rrid,
    message: mes,
    imgid : mid
  };
  return new Promise((resolve,reject)=>{
    this.http.post(url, data, {headers: headers}).subscribe((response)=>{
       resolve(response);
    });
  })
}

sendimg(img){
  var url =this.domain+"/receiveimg"

  // const headers = new HttpHeaders({'Content-Type': 'multipart/form-data'});
  const headers = new HttpHeaders();


  let im = new FormData();
  im.append("Image", img);
  // 获取 window 的 URL 工具     
  // var URL = window.URL || window.webkitURL;     
  // var URL = window.URL;     

  // 通过 file 生成目标 url
  // var imgURL = URL.createObjectURL(img);

  // let im = { 
    // Image: img
  // };
  return new Promise((resolve,reject)=>{
    console.log(im)
    this.http.post(url, im, {headers: headers}).subscribe((response)=>{
       resolve(response);
    });
  })
}

delete(id){
  var url =this.domain+"/delete"

  const headers = new HttpHeaders({'Content-Type': 'application/x-www-form-urlencoded'});
  let data = { 
    userfriendid: id, 
  };
  return new Promise((resolve,reject)=>{
    this.http.post(url, data, {headers: headers}).subscribe((response)=>{
       resolve(response);
    });
  })
}

update(name, phone, mail, pw, id){
  var url =this.domain+"/update"

  const headers = new HttpHeaders({'Content-Type': 'application/x-www-form-urlencoded'});
  let data = { 
    username:name,
    userphone:phone,
    usermail:mail,
    password:pw,
    userfriendid: id, 
  };
  return new Promise((resolve,reject)=>{
    this.http.post(url, data, {headers: headers}).subscribe((response)=>{
       resolve(response);
    });
  })
}


}

3、运行效果

在这里插入图片描述
在这里插入图片描述
4、bug
本页面轮询功能未完成,暂时用window.location.reload()代替,会出现发送失败的bug

二、golang

1、总目录
(数据库为 postgresql)
在这里插入图片描述
2、代码

receivesendingimg.go

package servewr

import (
	"bufio"
	"bytes"

	// "crypto/md5"
	// "database/sql"
	// "encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"io"

	// "log"
	"net/http"
	"net/url"
	"os"
	"strconv"

	"../dbtable"
	// _ "github.com/lib/pq"
)

//RespProto 接口响应协议
type RespProto struct {
	ID      int    `json:"id"`
	Status  int    `json:"status"`
	Message string `json:"message"`
}

// ReceiveImg 接收图片数据,并返回图片id,接受post
func ReceiveImg(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Access-Control-Allow-Origin", "*")             //允许访问所有域
	w.Header().Add("Access-Control-Allow-Headers", "Content-Type") //header的类型
	w.Header().Set("content-type", "application/json")             //返回数据格式是json
	r.ParseMultipartForm(32 << 20)
	file, handler, err := r.FormFile("Image")
	// file, handler, err := r.File("Image")

	if err != nil {
		fmt.Println(err)
		sendErrToClient(err.Error(), w)
		return
	}
	defer file.Close()
	file1 := file
	imgBytes := make([]byte, handler.Size)
	bufr := bufio.NewReader(file1)
	_, err = bufr.Read(imgBytes)
	if err != nil {
		fmt.Println(err)
		sendErrToClient(err.Error(), w)
		return
	}

	MD5 := dbtable.Calmd5(imgBytes)
	if MD5 == "" {
		fmt.Println(fmt.Errorf("图片的md5获取失败"))
		sendErrToClient("图片的md5获取失败", w)
		return
	}

	var response RespProto
	// 检索数据库,查看是否有相同的md5的数据
	fileid, res := dbtable.CheckRepeat(MD5) // true代表该图片以存在
	if res {
		response.ID = fileid
		response.Message = "repeat and success "
		result, err := json.Marshal(response)
		if err != nil {
			fmt.Println(err)
			sendErrToClient(err.Error(), w)
			return
		}
		w.Write(result)
		return
	}
	// 将图片存入服务器
	filename := MD5 + ".png"
	filePath := "././images/" + filename

	f, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0666) //打开文件
	if err != nil {
		fmt.Println(err)
		sendErrToClient(err.Error(), w)
		return
	}
	defer f.Close()
	io.Copy(f, bytes.NewReader(imgBytes))

	// 将图片相关信息存入数据库
	dbtable.InsertData(filename, filePath, MD5)
	id, res := dbtable.CheckRepeat(MD5) // true代表已经存在
	if !res {
		fmt.Println(errors.New("存入数据库中的数据的数据id获取不成功"))
		sendErrToClient("存入数据库中的数据的数据id获取不成功", w)
		return
	}

	response.ID = id
	response.Status = 0
	response.Message = "success"
	result, err := json.Marshal(response)
	if err != nil {
		fmt.Println(err)
		sendErrToClient(err.Error(), w)
		return
	}
	w.Write(result)
}

// SendImg 接收图片id,返回相应图片,接受get
func SendImg(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Access-Control-Allow-Origin", "*") //允许访问所有域
	u := r.URL
	m, err := url.ParseQuery(u.RawQuery)
	if err != nil {
		fmt.Println(err)
		// sendErrToClient(err.Error(), w)
		return
	}
	id, err := strconv.Atoi(m["id"][0])
	if err != nil {
		fmt.Println(err)
		// sendErrToClient(err.Error(), w)
		return
	}
	if id == 0 {
		// sendErrToClient("该消息没有图片", w)
		return
	}
	filePath := dbtable.GetFilePath(id)
	imgBytes := dbtable.ReadFile(filePath)
	// log.Printf("imgbytes:"+string(imgBytes))

	w.Write(imgBytes)
}

sendreceive.go

package servewr

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"

    // 使用相对路径引用dbtable
    "../dbtable"
    
)

// SendResp send接口的响应
type SendResp struct {
    Status int `json:"status"`
}

// Send 发送接口的处理函数
func Send(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Access-Control-Allow-Origin", "*")                            // 允许访问所有域
    w.Header().Add("Access-Control-Allow-Headers", "Content-TypeAuthorization")   // header的类型
    w.Header().Set("content-type", "application/json")

    // 只处理POST请求
    if r.Method != "POST" {
        return
    }

    resp := &SendResp{
        Status: 0,
    }

    // 读取请求实体中的数据
    body, err := ioutil.ReadAll(r.Body)
    if err != nil {
        log.Printf("read http request failed, err:%v", err)
        sendErrToClient(err.Error(), w)
        return
    }

    if body == nil || len(body) == 0 {
        log.Println("http request body is null")
        sendErrToClient("http request body is null", w)
        return
    }

    defer r.Body.Close()

    data := make(map[string]interface{})

    // json反序列化请求实体中的数据
    if err = json.Unmarshal(body, &data); err != nil {
        log.Printf("json unmarshal failed, err:%v", err)
        sendErrToClient(err.Error(), w)
        return
    }

    // 类型断言
    sid, ok := data["sid"].(string)
    if !ok {
        log.Printf("type assert failed")
        sendErrToClient("type assert failed", w)
        return
    }

    rid, ok := data["rid"].(string)
    if !ok {
        log.Println("type assert failed")
        sendErrToClient("type assert failed", w)
        return
    }

    imgid, ok := data["imgid"].(string)
    if !ok {
        log.Println("type assert failed")
        sendErrToClient("type assert failed", w)
        return
    }

    message, ok := data["message"].(string)
    if !ok {
        log.Println("type assertion failed")
        sendErrToClient("type assertion failed", w)
        return
	}
	
    if message == ""&&imgid=="0" {
        log.Println("the message is empty string")
        sendErrToClient("the message is empty string", w)
        return
    }

    fmt.Printf("sid: %s \nrid: %s \nmessage: %s\n", sid, rid, message)

    // 把消息的发送者和接收者以及消息的内容存储到数据库
    err = dbtable.AddMessage(sid, rid, message, imgid)
    if err!=nil{
        log.Println(err)
        x := fmt.Sprintf("%s", err)
		sendErrToClient(x, w)
		return
    }

    // 设置成功的状态码
    resp.Status = 0

    // 将响应的数据json序列化
    respByte, err := json.Marshal(resp)
    if err != nil {
        log.Printf("json marshal failed, err:%v", err)
        sendErrToClient(err.Error(), w)
        return
    }

    // 响应数据
    _, err = w.Write(respByte)
    if err != nil {
        log.Printf("write the response failed, err:%v", err)
        sendErrToClient(err.Error(), w)
        return
	}
	
    return
}

// ReceiveResp receive接口的响应
type ReceiveResp struct {
    Status      int                  `json:"status"`
    MessageList []dbtable.MessageList `json:"messageList"` // 消息列表
}

// Receive 接收消息接口的处理函数
func Receive(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Access-Control-Allow-Origin", "*")                          //允许访问所有域
    w.Header().Add("Access-Control-Allow-Headers", "Content-TypeAuthorization") //header的类型
    w.Header().Set("content-type", "application/json")

    resp := ReceiveResp{}

    // 读取请求实体中的数据
    body, err := ioutil.ReadAll(r.Body)
    if err != nil {
        log.Printf("read http request failed, err: %v", err)
        sendErrToClient(err.Error(), w)
        return
    }

    if body == nil || len(body) == 0 {
        log.Println("http request body is null")
        sendErrToClient("http request body is null", w)
        return
    }

    defer r.Body.Close()

    data := make(map[string]interface{})

    // json反序列化请求实体中的数据
    if err = json.Unmarshal(body, &data); err != nil {
        log.Printf("json unmarshal failed, err: %v", err)
        sendErrToClient(err.Error(), w)
        return
    }

    if data == nil {
        log.Println("json unmarshal data is null")
        sendErrToClient("json unmarshal data is null", w)
        return
    }

    // 类型断言
    userid, ok := data["userid"].(string)
    if !ok {
        log.Println("type assert failed")
        sendErrToClient("type assert failed", w)
        return
    }

    if userid == "" {
        log.Println("the userid from http request is empty string")
        sendErrToClient("the userid from http request is empty string", w)
        return
	}
	
	userfriendid, ok := data["userfriendid"].(string)
    if !ok {
        log.Println("type assert failed")
        sendErrToClient("type assert failed", w)
        return
    }

    if userfriendid == "" {
        log.Println("the userfriendid from http request is empty string")
        sendErrToClient("the userfriendid from http request is empty string", w)
        return
    }


    // 根据id从数据库读取消息列表
    messageList, err := dbtable.GetMessageList(userid, userfriendid)
    if err != nil {
        log.Printf("get message list failed, err: %v", err)
        sendErrToClient(err.Error(), w)
        return
    }

    resp.Status = 0
    resp.MessageList = messageList

    for _, v := range messageList {
        fmt.Printf("发送方: %s,  接受方:%s ,  message: %s ,  time:%s, imgid:%s\n", v.Sid, v.Rid,  v.Message, v.Time, v.Imgid)
    }

    // json序列化receive接口的响应
    respByte, err := json.Marshal(resp)
    if err != nil {
        log.Printf("json marshal failed, err: %v", err)
        sendErrToClient(err.Error(), w)
        return
    }

    // 响应数据
    _, err = w.Write(respByte)
    if err != nil {
        log.Printf("write response failed, err: %v", err)
        sendErrToClient(err.Error(), w)
        return
    }
}

// CheckResp Check接口的响应
type CheckResp struct {
    Status int    `json:"status"` // 响应的状态码
    Num     int `json:"num"`     // 用户的id
}

//Check  检查未读消息接口处理函数
func Check(w http.ResponseWriter, r *http.Request){
	w.Header().Set("Access-Control-Allow-Origin", "*")                          //允许访问所有域
    w.Header().Add("Access-Control-Allow-Headers", "Content-TypeAuthorization") //header的类型
    w.Header().Set("content-type", "application/json")

    // 只处理POST请求
    if r.Method != "POST" {
        return
	}
	resp := &CheckResp{
        Status: 0,
        Num: 0,
    }

    // 读取请求实体中的数据
    body, err := ioutil.ReadAll(r.Body)
    if err != nil {
        log.Printf("read http request failed, err: %v", err)
        sendErrToClient(err.Error(), w)
        return
    }

    if body == nil || len(body) == 0 {
        log.Println("http request body is null")
        sendErrToClient("http request body is null", w)
        return
    }

    defer r.Body.Close()

    data := make(map[string]interface{})

    // json反序列化请求实体中的数据
    if err = json.Unmarshal(body, &data); err != nil {
        log.Printf("json unmarshal failed, err: %v", err)
        sendErrToClient(err.Error(), w)
        return
    }

    if data == nil {
        log.Println("json unmarshal data is null")
        sendErrToClient("json unmarshal data is null", w)
        return
    }

    // 类型断言
    userid, ok := data["userid"].(string)
    if !ok {
        log.Println("type assert failed")
        sendErrToClient("type assert failed", w)
        return
    }

    if userid == "" {
        log.Println("the userid from http request is empty string")
        sendErrToClient("the userid from http request is empty string", w)
        return
	}

    // 根据id从数据库读取消息列表
    number, err := dbtable.CheckUnreadMessage(userid)
    if err != nil {
        log.Printf("check message list failed, err: %v", err)
        sendErrToClient(err.Error(), w)
        return
    }

    resp.Status = 0
    resp.Num = number

     fmt.Printf( "用户: %s   未读消息条数:% v\n", userid, number)

    // json序列化receive接口的响应
    respByte, err := json.Marshal(resp)
    if err != nil {
        log.Printf("json marshal failed, err: %v", err)
        sendErrToClient(err.Error(), w)
        return
    }

    // 响应数据
    _, err = w.Write(respByte)
    if err != nil {
        log.Printf("write response failed, err: %v", err)
        sendErrToClient(err.Error(), w)
        return
    }
}



initDB.go

package dbtable

import (
	// "crypto/md5"
	"database/sql"
	// "encoding/hex"
	// "errors"
	"fmt"
	"log"
	"os"

	// postgres 驱动
	_ "github.com/lib/pq"
)

//全局变量,数据库实例
var db *sql.DB

//数据库连接配置
const (
	host     = "localhost"
	port     = 5432
	user     = "postgres"
	password = "postgres"
	dbname   = "postgres"
)

// Initdb 初始化连接数据库
func Initdb() (err error) {
	//打开数据库
	psqlInfo := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable", host, port, user, password, dbname)
	db, err = sql.Open("postgres", psqlInfo)
	if err != nil {
		log.Printf("初始化数据库失败, err: %v\n", err)
		return
	}

	err = db.Ping()
	if err != nil {
		log.Printf("连接数据库失败, err: %v\n", err)
		return
	}

	err = CreateUserTable()
	if err != nil {
		log.Printf("创建用户表失败, err: %v\n", err)
		return
	}

	err = CreatOfflineMessageTable()
	if err != nil {
		log.Printf("创建消息表失败, err: %v\n", err)
		return
	}

	err = CreatUserFriendListTable()
	if err != nil {
		log.Printf("创建好友表失败, err: %v\n", err)
		return
	}
	err = CreatImginfoTable()
	if err != nil {
		log.Printf("创建图片表失败, err: %v\n", err)
		return
	}
	fmt.Println("数据库连接成功!!")
	return
}

//InitDir 创建文件夹
func InitDir() (err error) {
	dir := "././images"
	exist, err := PathExists(dir)
	if err != nil {
		fmt.Println(err)
		return
	}
	if exist {
		fmt.Printf("![%v] has been existed\n", dir)
	} else {

		err := os.Mkdir(dir, os.ModePerm)
		if err != nil {
			log.Fatal(fmt.Sprintf("mkdir failed![%v]\n", err))
		} else {
			fmt.Printf("mkdir success!\n")
		}
	}
	return nil
}

// CreateUserTable 创建用户表
func CreateUserTable() (err error) {
	// //如果表存在, 先删除表
	// statement := `DROP TABLE IF EXISTS myusers;`
	// _, err = db.Exec(statement)
	// if err != nil {
	// 	log.Printf("drop table myusers failed, err: %v", err)
	// 	return
	// }
	// CREATE TABLE IF NOT EXISTS `db_database_user` (SQL)
	statement := `CREATE TABLE  IF NOT EXISTS myusers (
        id VARCHAR(64) NOT NULL,
		username VARCHAR(64) NOT NULL,
        userphone VARCHAR(64) NOT NULL,
        usermail VARCHAR(64) NOT NULL,		
        password VARCHAR(64) NOT NULL
    );`

	_, err = db.Exec(statement)
	if err != nil {
		// log.Printf("create user table failed, err: %v", err)
		return
	}
	return
}

// CreatOfflineMessageTable 创建数据库离线消息表
func CreatOfflineMessageTable() (err error) {
	//如果表存在, 先删除表
	// statement := `DROP TABLE IF EXISTS offlinemessage;`
	// _, err = db.Exec(statement)
	// if err != nil {
	// 	log.Printf("drop table offlinemessage failed, err: %v", err)
	// 	return
	// }

	statement := `CREATE TABLE   IF NOT EXISTS  offlinemessage (
        id serial NOT NULL primary key,
        sid VARCHAR(64) NOT NULL,
		rid VARCHAR(64) NOT NULL,
        imgid INT NOT NULL,
        message VARCHAR(64) NULL DEFAULT NULL,
        datime TIMESTAMP,
        readwhether BOOLEAN
    );`

	_, err = db.Exec(statement)
	if err != nil {
		// log.Printf("create offlineMessage table failed, err: %v", err)
		return
	}
	return
}

//CreatUserFriendListTable 创建用户好友联系表
func CreatUserFriendListTable() (err error) {
	//如果表存在, 先删除表
	// statement := `DROP TABLE IF EXISTS offlinemessage;`
	// _, err = db.Exec(statement)
	// if err != nil {
	// 	log.Printf("drop table offlinemessage failed, err: %v", err)
	// 	return
	// }

	statement := `CREATE TABLE   IF NOT EXISTS  userfriendlist (
		id serial NOT NULL primary key,
        userid VARCHAR(64) NOT NULL,
        userfriendid VARCHAR(64) NOT NULL
    );`

	_, err = db.Exec(statement)
	if err != nil {
		// log.Printf("create offlineMessage table failed, err: %v", err)
		return
	}
	return
}

//CreatImginfoTable 创建图片表
func CreatImginfoTable() (err error) {
	//如果表存在, 先删除表
	// statement := `DROP TABLE IF EXISTS offlinemessage;`
	// _, err = db.Exec(statement)
	// if err != nil {
	// 	log.Printf("drop table offlinemessage failed, err: %v", err)
	// 	return
	// }

	statement := `CREATE TABLE   IF NOT EXISTS  imginfo (
		id serial,
		name varchar(255) NOT NULL,
		type varchar(255),
		size varchar(255),
		path varchar(255) NOT NULL,
		md5 varchar(255),
		time timestamp with time zone default current_timestamp
    );`

	_, err = db.Exec(statement)
	if err != nil {
		// log.Printf("create offlineMessage table failed, err: %v", err)
		return
	}
	return
}

// Close 关闭数据库
func Close() {
	db.Close()
}

handleDB.go
在下列代码中寻找相应的函数

package dbtable

import (
	"bufio"
	"crypto/md5"
	"encoding/hex"
	"errors"
	"fmt"
	"log"
	"os"
	"regexp"
	"time"
)

// GetMd5String 根据账号生成64位md5字符串
func GetMd5String(username string) (string, error) {
	if username == "" {
		log.Printf("the username is null")
		return "", errors.New("the username is null")
	}
	usernameHash := md5.New()
	_, err := usernameHash.Write([]byte(username))
	if err != nil {
		log.Printf("create md5 string by username failed, err: %v", err)
		return "", err
	}
	return hex.EncodeToString(usernameHash.Sum(nil)), nil
}

//VerifyEmailFormat 验证邮箱是否正确
func VerifyEmailFormat(email string) bool {
	//pattern := `\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*` //匹配电子邮箱
	pattern := `^[0-9a-z][_.0-9a-z-]{0,31}@([0-9a-z][0-9a-z-]{0,30}[0-9a-z]\.){1,4}[a-z]{2,4}$`
	reg := regexp.MustCompile(pattern)
	return reg.MatchString(email)
}

//VerifyMobileFormat 验证手机是否正确
func VerifyMobileFormat(mobileNum string) bool {
	regular := "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$"

	reg := regexp.MustCompile(regular)
	fmt.Println(reg.MatchString(mobileNum))
	return reg.MatchString(mobileNum)
}

//VerifyNameFormat 验证用户名是否正确
func VerifyNameFormat(name string) bool {
	pattern := "^[a-zA-Z][a-zA-Z0-9_]{4,15}$"
	reg := regexp.MustCompile(pattern)
	fmt.Println(reg.MatchString(name))
	return reg.MatchString(name)
}

// CreateUser 系统初始化就生成2个已经注册的用户
func CreateUser() error {

	rows, err := db.Query(" select * from myusers where username=$1", "xiaoming")
	if rows.Next() {
		log.Println("小明已存在")
		rows.Close()
		return nil
	}
	rows, err = db.Query(" select * from myusers where username=$1", "xiaohei")
	if rows.Next() {
		log.Println("小黑已存在")
		rows.Close()
		return nil
	}
	defer rows.Close()

	id1, err := GetMd5String("xiaoming")
	if err != nil {
		log.Println("get md5 string failed:", err)
		return err
	}
	id2, err := GetMd5String("xiaohei")
	if err != nil {
		log.Println("get md5 string failed:", err)
		return err
	}

	stmt, err := db.Prepare(`insert into myusers(id,username,userphone, usermail, password) values($1,$2,$3,$4,$5)`)
	if err != nil {
		log.Fatal(err)
		return err
	}
	defer stmt.Close()

	_, err = stmt.Exec(id1, "xiaoming", "13726845659", "123456@qq.com", "123456")
	if err != nil {
		log.Println("insert user failed:", err)
		return err
	}
	_, err = stmt.Exec(id2, "xiaohei", "19926849899", "abcde@abx.com", "234567")
	if err != nil {
		log.Println("insert user failed:", err)
		return err
	}
	return nil
}

// CreateXiaohuaFriend 系统初始化就生成小华的好友
func CreateXiaohuaFriend() error {
	var id1, id2, id3 string
	rows, err := db.Query(" select id from myusers where username=$1", "xiaohua")
	defer rows.Close()
	if err != nil {
		log.Println("get friends id failed")
		rows.Close()
		return nil
	}
	for rows.Next() {
		if err = rows.Scan(&id1); err != nil {
			log.Printf("rows scan failed, err: %v", err)
			return err
		}
	}
	if id1 == "" {
		log.Printf("xiaohua not exit , err: %v", err)
		return err
	}
	rowscheckinit, err := db.Query(" select userid from userfriendlist where userid=$1", id1)
	if rowscheckinit.Next() {
		log.Println("小华好友已初始化")
		rowscheckinit.Close()
		return nil
	}
	defer rowscheckinit.Close()

	rows, err = db.Query(" select id from myusers where username=$1", "xiaoming")
	if err != nil {
		log.Println("get friends id failed")
		rows.Close()
		return nil
	}
	for rows.Next() {
		if err = rows.Scan(&id2); err != nil {
			log.Printf("rows scan failed, err: %v", err)
			return err
		}
	}
	rows, err = db.Query(" select id from myusers where username=$1", "xiaohei")
	if err != nil {
		log.Println("get friends id failed")
		rows.Close()
		return nil
	}
	for rows.Next() {
		if err = rows.Scan(&id3); err != nil {
			log.Printf("rows scan failed, err: %v", err)
			return err
		}
	}
	defer rows.Close()

	statement := `insert into userfriendlist(userid,userfriendid) values($1,$2)`
	_, err = db.Exec(statement, id1, id1)
	if err != nil {
		log.Println("insert user failed:", err)
		return err
	}
	_, err = db.Exec(statement, id1, id2)
	if err != nil {
		log.Println("insert user failed:", err)
		return err
	}
	//双向绑定
	_, err = db.Exec(statement, id2, id1)
	if err != nil {
		log.Println("insert user failed:", err)
		return err
	}
	_, err = db.Exec(statement, id1, id3)
	if err != nil {
		log.Println("insert user failed:", err)
		return err
	}
	_, err = db.Exec(statement, id3, id1)
	if err != nil {
		log.Println("insert user failed:", err)
		return err
	}
	return nil
}

// StorageUserInfoToDB 把用户信息存储进数据库
func StorageUserInfoToDB(username, userphone, usermail, password string) (id string, err error) {
	//检查是否为空
	if username == "" {
		log.Println("the username is empty string")
		return "",errors.New("the username is empty string")
	}
	if userphone == "" {
		log.Println("the userphone is empty string")
		return "",errors.New("the userphone is empty string")
	}
	if usermail == "" {
		log.Println("the username is empty string")
		return "",errors.New("the usermail is empty string")
	}
	if password == "" {
		log.Println("the password is empty string")
		return "",errors.New("the password is empty string")
	}
	//验证格式是否正确
	verify := VerifyMobileFormat(userphone)
	if verify == false {
		log.Println("the userphone is improper")
		return "",errors.New("the userphone is improper")
	}
	verify = VerifyEmailFormat(usermail)
	if verify == false {
		log.Println("the usermail is improper")
		return "",errors.New("the usermail is improper")
	}
	verify = VerifyNameFormat(username)
	if verify == false {
		log.Println("the username is improper")
		return "",errors.New("the username is improper")
	}
	//检查是否重复
	rows, err := db.Query(" select * from myusers where username=$1", username)
	defer rows.Close()
	if rows.Next() {
		log.Println("the username  has existed")
		return "",errors.New("tthe username  has existed")
	}
	rows, err = db.Query(" select * from myusers where userphone=$1", userphone)
	if rows.Next() {
		log.Println("the userphone  has existed")
		return "",errors.New("tthe userphone  has existed")
	}
	rows, err = db.Query(" select * from myusers where usermail=$1", usermail)
	if rows.Next() {
		log.Println("the usermail  has existed")
		return "",errors.New("tthe usermail  has existed")
	}

	id, err = GetMd5String(username)
	if err != nil {
		log.Println("get md5 string failed:", err)
		return "",err
	}
	statement := `insert into myusers(id, username, userphone, usermail, password) values($1, $2, $3,$4,$5)`
	_, err = db.Exec(statement, id, username, userphone, usermail, password)
	if err != nil {
		log.Printf("sql exce failed, err: %v", err)
		return
	}
	log.Printf("%s录入成功\n", username)
	return
}

// GetUserIDByUseraccountAndPassword 根据账户和密码获取用户id
func GetUserIDByUseraccountAndPassword(useraccount, password string) (id string, err error) {
	if useraccount == "" {
		log.Println("the username is empty string")
		return "", errors.New("the useraccount is empty string")
	}

	if password == "" {
		log.Println("the password is empty string")
		return "", errors.New("the password is empty string")
	}

	if db == nil {
		log.Println("the db pointer is null")
		return "", errors.New("the db pointer is null")
	}

	statement := `select id from myusers where username = $1 and password = $2`
	err = db.QueryRow(statement, useraccount, password).Scan(&id)
	if err == nil {
		return
	}
	log.Printf("query id by username and password failed, err: %v", err)

	statement = `select id from myusers where userphone = $1 and password = $2`
	err = db.QueryRow(statement, useraccount, password).Scan(&id)
	if err == nil {
		return
	}
	log.Printf("query id by userphone and password failed, err: %v", err)

	statement = `select id from myusers where usermail = $1 and password = $2`
	err = db.QueryRow(statement, useraccount, password).Scan(&id)
	if err == nil {
		return
	}
	log.Printf("query id by usermail and password failed, err: %v", err)

	return "", err
}

// AddMessage 往消息列表里面写入离线消息
func AddMessage(sid, rid, message, imgid string) (err error) {
	rows, err := db.Query(" select * from myusers where id=$1", sid)
	defer rows.Close()
	if !rows.Next() {
		log.Println("错误,发送方不存在")
		return errors.New("错误,发送方不存在")
	}
	rows, err = db.Query(" select * from myusers where id=$1", rid)
	if !rows.Next() {
		log.Println("错误,接受方不存在")
		return errors.New("错误,接受方不存在")
	}

	t := time.Now()
	b :=false
	statement := `insert into offlinemessage( sid, rid, message, datime, readwhether, imgid) values($1, $2, $3, $4, $5, $6)`
	_, err = db.Exec(statement, sid, rid, message, t, b, imgid)
	if err != nil {
		log.Printf("sql exce failed, err: %v", err)
		return
	}
	return
}

// MessageList 消息列表
type MessageList struct {
	Sid     string `json:"sid"`     // 发送方
	Rid     string `json:"rid"`     //接受方
	Message string `json:"message"` // 消息内容
	Time    string `json:"time"`    //发送时间
	Imgid   string `json:"imgid"`   //发送时间
}

// GetMessageList 获取消息列表
func GetMessageList(userid string, userfriendid string) ([]MessageList, error) {
	rows, err := db.Query(" select * from myusers where id=$1", userid)
	defer rows.Close()
	if !rows.Next() {
		log.Println("错误,user 不存在")
		return nil, errors.New("错误,user不存在")
	}
	rows, err = db.Query(" select * from myusers where id=$1", userfriendid)
	if !rows.Next() {
		log.Println("错误,user's friend 不存在")
		return nil, errors.New("错误,user's friend不存在")
	}

	messageArray := []MessageList{}
	messageList := MessageList{}
	//找出所有有关本用户的消息
	statement := `select id, sid, rid, message, datime, readwhether, imgid from offlinemessage where rid = $1 or sid = $2`
	rows, err = db.Query(statement, userid, userid)
	if err != nil {
		log.Printf("query failed, err: %v", err)
		return nil, err
	}
	var messageid int
	var changeReadWhether bool
	for rows.Next() {
		if err = rows.Scan(&messageid, &messageList.Sid, &messageList.Rid, &messageList.Message, &messageList.Time, &changeReadWhether, &messageList.Imgid); err != nil {
			log.Printf("rows scan failed, err: %v", err)
			return nil, err
		}
		if messageList.Sid == userfriendid || messageList.Rid == userfriendid {
			if changeReadWhether == false&& messageList.Sid == userfriendid {
				_, err := db.Exec("UPDATE offlinemessage SET readwhether=$1 where id=$2", true, messageid)
				if err != nil {
					log.Printf("change readwhether failed, err: %v", err)
					return nil, err
				}
			}
			messageArray = append(messageArray, messageList)
		}
	}
	return messageArray, nil
}

//CheckUnreadMessage  检查未读列表
func CheckUnreadMessage(userid string) (num int, err error) {
	rows, err := db.Query(" select * from myusers where id=$1", userid)
	defer rows.Close()
	if !rows.Next() {
		log.Println("错误,user 不存在")
		return -1, errors.New("错误,user不存在")
	}

	statement := `select  readwhether from offlinemessage where rid = $1`
	rows, err = db.Query(statement, userid)
	defer rows.Close()
	if err != nil {
		log.Printf("query failed, err: %v", err)
		return -1, err
	}
	var check bool
	num = 0
	for rows.Next() {
		if err = rows.Scan(&check); err != nil {
			log.Printf("rows scan failed, err: %v", err)
			return -1, err
		}
		if check == false {
			num++
		}
	}
	log.Printf("未读消息%v条", num)

	return num, nil
}

// UserfriendList 好友列表
type UserfriendList struct {
	Userfriendname     string `json:"userfriendname"`
	Userfriendphone    string `json:"userfriendphone"`
	Userfriendmail     string `json:"userfriendmail"`
	Userfriendpassword string `json:"userfriendpassword"`
	Userfriendid       string `json:"userfriendid"`
}

// GetUserfriendList 获取好友列表
func GetUserfriendList(userid string) ([]UserfriendList, error) {
	rows, err := db.Query(" select * from myusers where id=$1", userid)
	defer rows.Close()
	if !rows.Next() {
		log.Println("错误,user 不存在")
		return nil, errors.New("错误,user不存在")
	}

	userfriendListArray := []UserfriendList{}
	userfriendList := UserfriendList{}
	//找出所有有关本用户的消息
	statement := `select userfriendid from userfriendlist where userid = $1 `
	rows, err = db.Query(statement, userid)
	if err != nil {
		log.Printf("query failed, err: %v", err)
		return nil, err
	}
	var userfriendID string
	for rows.Next() {
		if err = rows.Scan(&userfriendID); err != nil {
			log.Printf("rows scan failed, err: %v", err)
			return nil, err
		}
		statement = `select username, userphone, usermail, password  from myusers where id = $1 `
		rowsinfo, err := db.Query(statement, userfriendID)
		defer rowsinfo.Close()
		if err != nil {
			log.Printf("query failed, err: %v", err)
			return nil, err
		}
		for rowsinfo.Next() {
			if err = rowsinfo.Scan(&userfriendList.Userfriendname, &userfriendList.Userfriendphone, &userfriendList.Userfriendmail, &userfriendList.Userfriendpassword); err != nil {
				log.Printf("rowsinfo scan failed, err: %v", err)
				return nil, err
			}
		}
		userfriendList.Userfriendid = userfriendID
		userfriendListArray = append(userfriendListArray, userfriendList)
	}

	return userfriendListArray, nil
}

// DeleteUserFromDB 把用户信息从数据库删除
func DeleteUserFromDB(userfriendid string) (err error) {
	rows, err := db.Query(" select * from myusers where id=$1", userfriendid)
	defer rows.Close()
	if !rows.Next() {
		log.Println("错误,user 不存在")
		return errors.New("错误,user不存在")
	}

	stmt, err := db.Prepare("DELETE from myusers where id=$1")
	defer stmt.Close()

	if err != nil {
		log.Println("SQL语句设置失败:", err)
		return err
	}
	result, err := stmt.Exec(userfriendid)
	if err != nil {
		log.Println("参数添加失败:", err)
		return err
	}
	num, err := result.RowsAffected()
	if err != nil {
		log.Println("从myusers删除失败:", err)
		return err
	}
	log.Printf("从myusers删除行数:%v", num)

	stmt, err = db.Prepare("DELETE from userfriendlist where userid=$1")
	if err != nil {
		log.Println("SQL语句设置失败:", err)
		return err
	}
	result, err = stmt.Exec(userfriendid)
	if err != nil {
		log.Println("参数添加失败:", err)
		return err
	}
	num, err = result.RowsAffected()
	if err != nil {
		log.Println("从userfriendlist  userid删除失败:", err)
		return err
	}
	log.Printf("从userfriendlist  userid删除行数:%v", num)
	stmt, err = db.Prepare("DELETE from userfriendlist where userfriendid=$1")
	if err != nil {
		log.Println("SQL语句设置失败:", err)
		return err
	}
	result, err = stmt.Exec(userfriendid)
	if err != nil {
		log.Println("参数添加失败:", err)
		return err
	}
	num, err = result.RowsAffected()
	if err != nil {
		log.Println("从userfriendlist  userfriendid删除失败:", err)
		return err
	}
	log.Printf("从userfriendlist  userfriendid删除行数:%v", num)

	stmt, err = db.Prepare("DELETE from offlinemessage where rid=$1")
	if err != nil {
		log.Println("SQL语句设置失败:", err)
		return err
	}
	result, err = stmt.Exec(userfriendid)
	if err != nil {
		log.Println("参数添加失败:", err)
		return err
	}
	num, err = result.RowsAffected()
	if err != nil {
		log.Println("从offlinemessage  rid删除失败:", err)
		return err
	}
	log.Printf("从offlinemessage  rid删除行数:%v", num)

	stmt, err = db.Prepare("DELETE from offlinemessage where sid=$1")
	if err != nil {
		log.Println("SQL语句设置失败:", err)
		return err
	}
	result, err = stmt.Exec(userfriendid)
	if err != nil {
		log.Println("参数添加失败:", err)
		return err
	}
	num, err = result.RowsAffected()
	if err != nil {
		log.Println("从offlinemessage  sid删除失败:", err)
		return err
	}
	log.Printf("从offlinemessage  sid删除行数:%v", num)

	log.Println("删除成功")

	return nil
}

// UpdateUserInfo 修改用户信息
func UpdateUserInfo(username, userphone, usermail, password, userfriendid string) (err error) {
	rows, err := db.Query(" select * from myusers where id=$1", userfriendid)
	if !rows.Next() {
		rows.Close()
		log.Println("用户不存在")
		return errors.New("the username is empty string")
	}
	defer rows.Close()

	nf := true
	pf := true
	mf := true
	//检查是否为空
	if username == "" {
		nf = false
	}
	if userphone == "" {
		pf = false
	}
	if usermail == "" {
		mf = false
	}

	if nf == false && pf == false && mf == false && password == "" {
		log.Println("nothing change")
		return errors.New("nothing change")
	}

	if nf == false {
		rows, err := db.Query(" select username from myusers where id=$1", userfriendid)
		for rows.Next() {
			if err = rows.Scan(&username); err != nil {
				log.Printf("rows scan failed, err: %v", err)
				return err
			}
		}
	}
	if pf == false {
		rows, err := db.Query(" select userphone from myusers where id=$1", userfriendid)
		for rows.Next() {
			if err = rows.Scan(&userphone); err != nil {
				log.Printf("rows scan failed, err: %v", err)
				return err
			}
		}
	}
	if mf == false {
		rows, err := db.Query(" select usermail from myusers where id=$1", userfriendid)
		for rows.Next() {
			if err = rows.Scan(&usermail); err != nil {
				log.Printf("rows scan failed, err: %v", err)
				return err
			}
		}
	}
	if password == "" {
		rows, err := db.Query(" select password from myusers where id=$1", userfriendid)
		for rows.Next() {
			if err = rows.Scan(&password); err != nil {
				log.Printf("rows scan failed, err: %v", err)
				return err
			}
		}
	}
	//验证格式是否正确
	verify := VerifyMobileFormat(userphone)
	if verify == false {
		log.Println("the userphone is improper")
		return errors.New("the userphone is improper")
	}
	verify = VerifyEmailFormat(usermail)
	if verify == false {
		log.Println("the usermail is improper")
		return errors.New("the usermail is improper")
	}
	verify = VerifyNameFormat(username)
	if verify == false {
		log.Println("the username is improper")
		return errors.New("the username is improper")
	}

	//检查是否重复
	var checkflag string
	checknum := 0
	rows, err = db.Query(" select id from myusers where username=$1", username)
	if rows.Next() {
		if err = rows.Scan(&checkflag); err != nil {
			log.Printf("rows scan failed, err: %v", err)
			return err
		}
		checknum++
		if checkflag != userfriendid {
			log.Println("the username  has existed")
			return errors.New("the username  has existed")
		}
	}
	rows, err = db.Query(" select id from myusers where userphone=$1", userphone)
	if rows.Next() {
		if err = rows.Scan(&checkflag); err != nil {
			log.Printf("rows scan failed, err: %v", err)
			return err
		}
		checknum++
		if checkflag != userfriendid {
			log.Println("the userphone  has existed")
			return errors.New("tthe userphone  has existed")
		}
	}
	rows, err = db.Query(" select id from myusers where usermail=$1", usermail)
	if rows.Next() {
		if err = rows.Scan(&checkflag); err != nil {
			log.Printf("rows scan failed, err: %v", err)
			return err
		}
		checknum++
		if checkflag != userfriendid {
			log.Println("the usermail  has existed")
			return errors.New("tthe usermail  has existed")
		}
	}

	rows, err = db.Query(" select id from myusers where password=$1", password)
	if rows.Next() {
		if err = rows.Scan(&checkflag); err != nil {
			log.Printf("rows scan failed, err: %v", err)
			return err
		}
		if checkflag != userfriendid {
			checknum++
		}
	}
	if checknum == 4 {
		log.Println("the userinfo didn't change")
		return errors.New("用户没有修改信息")
	}

	stmt, err := db.Prepare("UPDATE myusers SET username=$1, userphone=$2,  usermail=$3,  password=$4  where id=$5")
	if err != nil {
		log.Println("SQL语句设置失败:", err)
		return err
	}

	_, err = stmt.Exec(username, userphone, usermail, password, userfriendid)
	if err != nil {
		log.Println("参数添加失败:", err)
		return err
	}

	log.Printf("修改成功")
	defer stmt.Close()

	return
}

// InsertData 插入数据
func InsertData(filename string, filePath string, MD5 string) {
	res, err := db.Exec("INSERT INTO imginfo (name,path,md5) VALUES ($1,$2,$3)", filename, filePath, MD5)
	if err != nil {
		fmt.Println(err)
		return
	}
	var affectedRows int64
	affectedRows, err = res.RowsAffected()
	if err != nil {
		fmt.Println(err)
		return
	}

	if affectedRows == 0 {
		fmt.Println(errors.New("0 row affected"))
		return
	}
}

//PathExists 判断文件夹是否存在
func PathExists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

// Calmd5 计算MD5
func Calmd5(bytes []byte) (md5str string) {
	MD5 := md5.New()
	MD5.Write(bytes)
	md5str = hex.EncodeToString(MD5.Sum(nil))
	return
}

// CheckRepeat 查重,若文件已存在,则返回其id
func CheckRepeat(MD5 string) (fileid int, res bool) {
	row := db.QueryRow("select id from   imginfo where md5 = $1", MD5)
	err := row.Scan(&fileid)
	if err != nil {
		fmt.Println(err)
		return
	}
	return fileid, true
}

// GetFilePath 获取文件的存储路径
func GetFilePath(fileid int) (filePath string) {
	row := db.QueryRow("SELECT path FROM   imginfo where id = $1", fileid)

	err := row.Scan(&filePath)
	if err != nil {
		fmt.Println(err)
		return
	}

	if filePath == "" {
		fmt.Println(fmt.Errorf("the submit of the problem %d is null", fileid))
		return
	}
	return filePath
}

// ReadFile 读取文件内容
func ReadFile(filePath string) (bytes []byte) {
	file, err := os.Open(filePath)
	if err != nil {
		fmt.Println(err)
		return
	}

	defer file.Close()
	stats, err := file.Stat()
	if err != nil {
		fmt.Println(err)
		return
	}

	var size = stats.Size()
	bytes = make([]byte, size)
	bufr := bufio.NewReader(file)
	_, err = bufr.Read(bytes)
	if err != nil {
		fmt.Println(err)
		return
	}

	return
}

// ConetFriendXiaohua 成为小华的好友
func ConetFriendXiaohua(username string) error {
	var id1, id2 string
	rows, err := db.Query(" select id from myusers where username=$1", "xiaohua")
	defer rows.Close()
	if err != nil {
		log.Println("get friends id failed")
		rows.Close()
		return err
	}
	for rows.Next() {
		if err = rows.Scan(&id1); err != nil {
			log.Printf("rows scan failed, err: %v", err)
			return err
		}
	}
	if id1 == "" {
		log.Printf("xiaohua not exit , err: %v", err)
		return errors.New("小华为空")
	}

	rows, err = db.Query(" select id from myusers where username=$1", username)
	if err != nil {
		log.Println("get friends id failed")
		rows.Close()
		return nil
	}
	for rows.Next() {
		if err = rows.Scan(&id2); err != nil {
			log.Printf("rows scan failed, err: %v", err)
			return err
		}
	}
	defer rows.Close()

	statement := `insert into userfriendlist(userid,userfriendid) values($1,$2)`
	_, err = db.Exec(statement, id1, id2)
	if err != nil {
		log.Println("insert user failed:", err)
		return err
	}
	//双向绑定
	_, err = db.Exec(statement, id2, id1)
	if err != nil {
		log.Println("insert user failed:", err)
		return err
	}
	return nil
}

handleErr.go

package servewr

import (
    "encoding/json"
    "log"
    "net/http"
)

// 错误的响应
type errResp struct {
    Status int    `json:"status"`
    Msg    string `json:"msg"`
}

// sendErrToClient 把接口处理函数中遇到的错误返回给前端(客户端)
func sendErrToClient(errMsg string, w http.ResponseWriter) {
    resp := errResp{}
    resp.Status = -1
    resp.Msg = errMsg
    data, err := json.Marshal(resp)
    if err != nil {
        log.Printf("json marshal failed, err: %v", err)
        return
    }
    _, err = w.Write(data)
    if err != nil {
        log.Printf("write response failed, err: %v", err)
        return
    }
}

main.go

package main

import (
	"fmt"
	"log"
	"net/http"

	// 使用相对路径引用自定义包
	"./dbtable"
	"./servewr"
)

func main() {
	// 设置log打印文件和行号
	log.SetFlags(log.Lshortfile | log.LstdFlags)

	// 初始化数据库
	err := dbtable.Initdb()
	if err != nil {
		log.Printf("init database failed, err: %v", err)
		dbtable.Close()
		return
	}
	defer dbtable.Close()

	err = dbtable.InitDir()
	if err != nil {
		log.Printf("init images file failed, err: %v", err)
		dbtable.Close()
		return
	}


	err = dbtable.CreateUser()
	if err != nil {
		log.Println("create user failed:", err)
		dbtable.Close()
		return
	}

	mux := http.NewServeMux()
	mux.HandleFunc("/login", servewr.Login)
	mux.HandleFunc("/register", servewr.Register)

	mux.HandleFunc("/send", servewr.Send)
	mux.HandleFunc("/receive", servewr.Receive)
	mux.HandleFunc("/check", servewr.Check)

	mux.HandleFunc("/show", servewr.Show)
	mux.HandleFunc("/delete", servewr.Delete)
	mux.HandleFunc("/update", servewr.Update)

	mux.HandleFunc("/receiveimg", servewr.ReceiveImg)
	mux.HandleFunc("/sendimg", servewr.SendImg)

	// 添加receive接口
	// mux.HandleFunc("/receive", controllers.Receive)

	fmt.Println("Web服务器启动...端口:8888")
	err = http.ListenAndServe(":8888", mux)
	if err != nil {
		log.Printf("listen and server failed, err: %v", err)
		dbtable.Close()
		return
	}
}

3,运行
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的&ldquo;一带一路&rdquo;海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在&ldquo;一带一路&rdquo;沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值