2021.1.27 更新

已更新新版本博客,更新内容很多,因此新开了一篇博客,戳这里

1 概述

使用spring boot作为后端框架与Android端配合mysql进行基本的交互,包含了最基本的增删查改功能.

2 开发环境

  • Win
  • IDEA 2019.2
  • Tomcat 9.0.27
  • MySQL 8.0.17
  • Spring Boot 2.2.1
  • JDK 8

3 后端

3.1 新建一个Spring Boot项目

参考这里.

3.2 实体类

新建User类作为实体类:

@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name; public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}

用的其实是3.1链接中的代码,里面有详细的解释.

3.3 持久层

新建UserRepository实现增删查改:

@Repository
public interface UserRepository extends CrudRepository<User,Integer>
{
@Query(value = "select * from user where name = ?1",nativeQuery = true)
public List<User> findByName(String name); @Modifying
@Query(value = "delete from user where name = ?1",nativeQuery = true)
public int deleteByName(String name);
}

由于CrudRepository中已经包含了"增"与"改",所以按需要实现自己的"查"与"删"即可.

CrudRepository的api很简单,官方文档在这里.

  • "增"使用save即可,参数为实体类
  • "删"使用deleteById,通过主键删除,若不想通过主键删除可以自己编写sql,像上面一样
  • "查"使用findAllfindById,自定义查找的话需要自己编写SQL
  • "改"也可使用save,注意需要设置主键

@Query用于设置SQL语句,nativeQuery表示使用原生SQL.

3.4 业务层

新建一个MainService.java:

@Transactional
@Service
public class MainService {
@Autowired
private UserRepository userRepository; public Iterable<User> getAllUsers()
{
return userRepository.findAll();
} public List<User> findByName(String name)
{
return userRepository.findByName(name);
} public boolean add(String name)
{
User user = new User();
user.setName(name);
userRepository.save(user);
return true;
} public boolean modify(Integer id,String name)
{
User user = new User();
user.setName(name);
user.setId(id);
userRepository.save(user);
return true;
} public boolean deleteByName(String name)
{
return userRepository.deleteByName(name) != 0;
}
}
  • getAllUsers():返回所有行,Iterable<E>类型
  • findByName():根据name返回所有name相同的行
  • add直接使用了save,由于save返回的是实体类,原本的代码是这样写的:
return userRepository.save(user) != null;



但是文档说了不会为null,所以只能强制返回true了.

  • modify使用了id与name作为参数,新建一个user,将其作为setter的参数,然后交给save
  • deleteByName使用了自定义的删除函数,返回的是int,在UserRepository中这个int代表SQL影响的行数,删除成功则行数不为0,删除失败,或者没有这行数据则行数为0.因此将返回值与0进行比较

3.5 控制层

@Controller
@RequestMapping(path = "/demo")
public class MainController {
@Autowired
private MainService mainService; @GetMapping(path = "/getAll")
public @ResponseBody Iterable<User> getAllUsers()
{
return mainService.getAllUsers();
} @PostMapping(path = "/get")
public @ResponseBody List<User> findByName(String name)
{
return mainService.findByName(name);
} @PostMapping(path = "/add")
public @ResponseBody boolean add(@RequestParam String name)
{
return mainService.add(name);
} @PostMapping(path = "/modify")
public @ResponseBody boolean modify(@RequestParam Integer id,@RequestParam String name)
{
return mainService.modify(id,name);
} @PostMapping(path = "/delete")
public @ResponseBody boolean deleteByName(@RequestParam String name)
{
return mainService.deleteByName(name);
}
}

Controller主要就是几个注解,除了getAllUsers使用Get外,其他的都是用Post.另外就是路径设置,直接在path中设置即可.

后端的话到这里就基本完成了,剩下的打包部署操作就不说了,需要的可以参考这里.

4 Android端

什么新建工程之类的就不说了.

贴上部分MainActivity,完整代码见文末:

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
register.setOnClickListener(v ->{new Thread(()-> {
OkHttpClient okHttpClient = new OkHttpClient();
String name = ((EditText) findViewById(R.id.name)).getText().toString();
FormBody formBody = new FormBody.Builder().add("name", name).build();
Request request = new Request.Builder()
.url(Constant.ADD)
.post(formBody)
.build();
try (Response response = okHttpClient.newCall(request).execute()) {
Looper.prepare();
if (Boolean.parseBoolean(response.body().string()))
{
Toast.makeText(this, "注册成功", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(this, "注册失败", Toast.LENGTH_SHORT).show();
}
Looper.loop();
}
//...
}).start();}); login.setOnClickListener(v ->{new Thread(()-> {
OkHttpClient okHttpClient = new OkHttpClient();
String name = ((EditText) findViewById(R.id.name)).getText().toString();
FormBody formBody = new FormBody.Builder().add("name", name).build();
Request request = new Request.Builder()
.url(Constant.GET)
.post(formBody)
.build();
try (Response response = okHttpClient.newCall(request).execute()) {
List<User> users = JSONArray.parseArray(response.body().string(),User.class);
Looper.prepare();
if(users.size() == 0)
{
Toast.makeText(this,"登录失败",Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(this,"登录成功",Toast.LENGTH_SHORT).show();
}
Looper.loop();
}
//...
}).start();}); delete.setOnClickListener(v ->{new Thread(()-> {
OkHttpClient okHttpClient = new OkHttpClient();
String name = ((EditText) findViewById(R.id.name)).getText().toString();
FormBody formBody = new FormBody.Builder().add("name", name).build();
Request request = new Request.Builder()
.url(Constant.DELETE)
.post(formBody)
.build();
try (Response response = okHttpClient.newCall(request).execute()) {
Looper.prepare();
if (Boolean.parseBoolean(response.body().string()))
{
Toast.makeText(this, "删除成功", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(this, "删除失败", Toast.LENGTH_SHORT).show();
}
Looper.loop();
}
//...
}).start();}); modify.setOnClickListener(v ->{new Thread(()-> {
OkHttpClient okHttpClient = new OkHttpClient();
String name = ((EditText) findViewById(R.id.name)).getText().toString();
String id = ((EditText)findViewById(R.id.id)).getText().toString();
FormBody formBody = new FormBody.Builder()
.add("name", name)
.add("id",id)
.build();
Request request = new Request.Builder()
.url(Constant.MODIFY)
.post(formBody)
.build();
try (Response response = okHttpClient.newCall(request).execute()) {
Looper.prepare();
if (Boolean.parseBoolean(response.body().string()))
{
Toast.makeText(this, "修改成功", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(this, "修改失败", Toast.LENGTH_SHORT).show();
}
Looper.loop();
}
//...
}).start();});
}
}

下面分别进行CRUD操作.

4.1 增

OkHttpClient okHttpClient = new OkHttpClient();
String name = ((EditText) findViewById(R.id.name)).getText().toString();
FormBody formBody = new FormBody.Builder().add("name", name).build();
Request request = new Request.Builder()
.url(Constant.ADD)
.post(formBody)
.build();
try (Response response = okHttpClient.newCall(request).execute()) {
Looper.prepare();
if (Boolean.parseBoolean(response.body().string()))
{
Toast.makeText(this, "注册成功", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(this, "注册失败", Toast.LENGTH_SHORT).show();
}
Looper.loop();
} catch (IOException e) {
e.printStackTrace();
}

使用OkHttp,通过FormBody设置参数,然后创建Request通过OkHttpClient发送.

由于后端"增"的方法返回的是一个true,因此这里将response.body().string()转换成boolean判断是否操作成功.

稍微提一下,

Looper.prepare();
Looper.loop();

这两行可以在非UI线程中使用Toast.

4.2 删

OkHttpClient okHttpClient = new OkHttpClient();
String name = ((EditText) findViewById(R.id.name)).getText().toString();
FormBody formBody = new FormBody.Builder().add("name", name).build();
Request request = new Request.Builder()
.url(Constant.DELETE)
.post(formBody)
.build();
try (Response response = okHttpClient.newCall(request).execute()) {
Looper.prepare();
if (Boolean.parseBoolean(response.body().string()))
{
Toast.makeText(this, "删除成功", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(this, "删除失败", Toast.LENGTH_SHORT).show();
}
Looper.loop();
} catch (IOException e) {
e.printStackTrace();
}

删这部分也是差不多的,就是改一下url,然后....然后没有了....好像很简单的样子?2333333

4.3 查

OkHttpClient okHttpClient = new OkHttpClient();
String name = ((EditText) findViewById(R.id.name)).getText().toString();
FormBody formBody = new FormBody.Builder().add("name", name).build();
Request request = new Request.Builder()
.url(Constant.GET)
.post(formBody)
.build();
try (Response response = okHttpClient.newCall(request).execute()) {
List<User> users = JSONArray.parseArray(response.body().string(),User.class);
Looper.prepare();
if(users.size() == 0)
{
Toast.makeText(this,"登录失败",Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(this,"登录成功",Toast.LENGTH_SHORT).show();
}
Looper.loop();
} catch (IOException e) {
e.printStackTrace();
}

查这里注意一下后端返回的是List,这里借助阿里的fastjson转换成List.

List<User> users = JSONArray.parseArray(response.body().string(),User.class);

然后判断有没有的话就判断长度是否为0即可.

4.4 改

OkHttpClient okHttpClient = new OkHttpClient();
String name = ((EditText) findViewById(R.id.name)).getText().toString();
String id = ((EditText)findViewById(R.id.id)).getText().toString();
FormBody formBody = new FormBody.Builder()
.add("name", name)
.add("id",id)
.build();
Request request = new Request.Builder()
.url(Constant.MODIFY)
.post(formBody)
.build();
try (Response response = okHttpClient.newCall(request).execute()) {
Looper.prepare();
if (Boolean.parseBoolean(response.body().string()))
{
Toast.makeText(this, "修改成功", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(this, "修改失败", Toast.LENGTH_SHORT).show();
}
Looper.loop();
} catch (IOException e) {
e.printStackTrace();
}

改的话只需一个额外的ID参数,在FormBody中add一个即可,不难.

4.5 UI

UI不详细说了,就几个简单的Button,具体可以看代码中的xml文件.

4.6 依赖与其他



注意一下依赖,还有设置java8.

compileOptions{
sourceCompatibility=1.8
targetCompatibility=1.8
} dependencies{
implementation 'com.squareup.okhttp3:okhttp:x.x.x'
implementation 'com.alibaba:fastjson:x.x.x'
}
  • OkHttp最新版本戳这里查看
  • fastjson最新版本戳这里查看

4.7 网络权限

这个笔者之前的文章有说,主要就是AndroidManifest.xml中的权限设置,请看这里.

5 测试

原始数据库:



注册一个:



看看数据库:



测试登录:



试试登录一个不存在的:



修改:







最后是删除:





删除一个不存在的会删除失败.

6 源码

如果觉得文章好看,欢迎点赞。

同时欢迎关注微信公众号:氷泠之路。

后端Spring Boot+前端Android交互+MySQL增删查改的更多相关文章

  1. 后端Spring Boot+前端Android交互+MySQL增删查改(Java+Kotlin实现)

    1 前言&概述 这篇文章是基于这篇文章的更新,主要是更新了一些技术栈以及开发工具的版本,还有修复了一些Bug. 本文是SpringBoot+Android+MySQL的增删查改的简单实现,用到 ...

  2. php mysql增删查改

    php mysql增删查改代码段 $conn=mysql_connect('localhost','root','root');  //连接数据库代码 mysql_query("set na ...

  3. mysql 增删查改

    非关系型数据库关系型数据库Oracle mysql sqlserver db2 Postgresql Sqlite access sqlserver 微软db2 ibm================ ...

  4. node.js+mysql增删查改

    数据库和表: -- -- 数据库: `test` -- -- -------------------------------------------------------- -- -- 表的结构 ` ...

  5. MySQL 增删查改 必知必会

    MySQL 数据库中的基础操作 3.表的修改 对表的表名.字段.字段类型.字段长度.约束等进行修改. 3.1 表的名称修改 -- 语法: ALTER TABLE 库名.表名 RENAME TO 新表名 ...

  6. python操作mysql增删查改

    # coding=utf-8 ''' python操作mysql,需安装MySQLdb驱动 安装MySQLdb,请访问 http://sourceforge.net/projects/mysql-py ...

  7. 靠谱好用,ANDROID SQLITE 增删查改

    布局文件main实现简单的功能: 1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayo ...

  8. MySQL增删查改语句(入门)

    目录 create alter: insert delete update select 数据库定义语句: create:创建数据库及表对象 drop:删除数据库及表对象 alter:修改数据库及表对 ...

  9. mysql增删查改练习

    建表 班级表 create table class( cid int auto_increment unique, caption varchar(32) not null default '' )c ...

随机推荐

  1. banner自用图床2

  2. 扒几个 3D 模型备用

    前言 在上一篇中,我展示了 OpenGL 开发的基本过程,算是向 3D 世界迈出的一小步吧.对于简单的 3D 物体,比如立方体.球体.圆环等等,我们只需要简单的计算就可以得到他们的顶点的坐标.但是仅仅 ...

  3. Dockerfile怎么用

    目录 Docker的Dockerfile 1.常用命令 2.使用Dockerfile创建镜像 Docker的Dockerfile Dockerfile是由一系列命令和参数构成的脚本文件,这些命令应用于 ...

  4. event loop整理

    宏任务和微任务 让我们从浏览器加载 script 说起,当浏览器加载完 script 之后,不考虑 script 标签的 defer 属性,script 将被立即执行.这时,我们就创建了一个宏任务. ...

  5. 后端程序员之路 55、go redis

    redigo有点像hiredis,只提供了最基本的连接和执行命令接口. 找到个不错的redis库: https://github.com/go-redis/redis func ExampleNewC ...

  6. MATLAB中FFT_HDL_Optimized模块定点(IEEE754单精度float格式)二进制与十进制转换实现

    早些时间段,做了Matlab中FFT_HDL_Optimzed模块FFT HDL代码仿真,并与Xilinx Vivado自带的xfft IP进行单精度浮点比较(后面随笔叙述).因为FFT_HDL_Op ...

  7. Caffe介绍与测试及相关Hi35xx平台下caffe yolox的使用参考

    这一篇我大概讲讲Caffe框架下MNIST的实现与基于Hi35xx平台下caffe yolox的运用等,供大家参考 1.Caffe介绍与测试 caffe全称Caffe Convolutional Ar ...

  8. kubernetes Pod亲和性

    三种调度粘性,主要根据官方文档说明: NodeSelector(定向调度).NodeAffinity(Node亲和性).PodAffinity(Pod亲和性). 1.      nodeSelecto ...

  9. 使用 SVG transform rotate 解决画框中的数字跟随旋转的问题

    问题描述 在图片上画框标注数字,旋转画布后,数字随之旋转,可读性不强,要求修改成无论画布怎么旋转,数字都是正向显示~ 原交互图示: 解决方案 先看下 dom 的结构 然后看下下面简单的代码 // 获取 ...

  10. [个人总结]利用grad-cam实现人民币分类

    # -*- coding:utf-8 -*- import os import numpy as np import torch import cv2 import torch.nn as nn fr ...