后端Spring Boot+前端Android交互+MySQL增删查改

2020.06.23 更新

1 概述

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

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

参考这里.java

3.2 实体类

新建User类做为实体类:mysql

@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连接中的代码,里面有详细的解释.git

3.3 持久层

新建UserRepository实现增删查改:github

@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很简单,官方文档在这里.spring

  • "增"使用save便可,参数为实体类
  • "删"使用deleteById,经过主键删除,若不想经过主键删除能够本身编写sql,像上面同样
  • "查"使用findAllfindById,自定义查找的话须要本身编写SQL
  • "改"也可以使用save,注意须要设置主键

@Query用于设置SQL语句,nativeQuery表示使用原生SQL.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&lt;E&gt;类型
  • findByName():根据name返回全部name相同的行
  • add直接使用了save,因为save返回的是实体类,本来的代码是这样写的:
    return userRepository.save(user) != null;

    在这里插入图片描述
    可是文档说了不会为null,因此只能强制返回true了.json

  • 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 源码

若是以为文章好看,欢迎点赞。

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

在这里插入图片描述

相关文章
相关标签/搜索