android+spring+mysql数据库操作数据库_后端Spring Boot+前端Android交互+MySQL增删查改

2020.06.23 更新

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项目

参考这里:Spring boot+Mysql+Spring data JPA一个Web的Demo​blog.csdn.netandroid+spring+mysql数据库操作数据库_后端Spring Boot+前端Android交互+MySQL增删查改_第1张图片

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

{

@Query(value = "select * from user where name = ?1",nativeQuery = true)

public List 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,像上面一样 - "查"使用findAll或findById,自定义查找的话需要自己编写SQL - "改"也可使用save,注意需要设置主键

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

3.4 业务层

新建一个MainService.java:

@Transactional

@Service

public class MainService {

@Autowired

private UserRepository userRepository;

public Iterable getAllUsers()

{

return userRepository.findAll();

}

public List 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类型

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 getAllUsers()

{

return mainService.getAllUsers();

}

@PostMapping(path = "/get")

public @ResponseBody List 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 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,然后....然后没有了....

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 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 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 源码Github​github.com码云​gitee.com

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

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

你可能感兴趣的:(android+spring+mysql数据库操作数据库_后端Spring Boot+前端Android交互+MySQL增删查改)