zoukankan      html  css  js  c++  java
  • 后端Spring Boot+前端Android交互+MySQL增删查改

    2022.01.08 更新

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

    1 概述

    使用Spring Boot作为后端框架与Android端配合MySQL进行基本的交互,包含了最基本的增删查改功能。

    2 开发环境

    • 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;
    	//getter setter...
    }
    

    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中已经包含了"增"与"改",所以按需要实现自己的"查"与"删"即可。

    CrudRepositoryAPI很简单,官方文档

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

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

    3.4 业务层

    @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使用了idname作为参数,新建一个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就可以了。

    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参数,在FormBodyadd一个即可。

    4.5 依赖与其他

    在这里插入图片描述
    注意一下依赖,还有设置Java8

    compileOptions{
    	sourceCompatibility=1.8
    	targetCompatibility=1.8
    }
    
    dependencies{
    	implementation 'com.squareup.okhttp3:okhttp:x.x.x'
    	implementation 'com.alibaba:fastjson:x.x.x'
    }
    

    4.7 网络权限

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

    5 测试

    原始数据库:

    在这里插入图片描述

    注册一个:

    在这里插入图片描述

    看看数据库:

    在这里插入图片描述

    测试登录:

    在这里插入图片描述

    试试登录一个不存在的:

    在这里插入图片描述

    修改:

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    最后是删除:

    在这里插入图片描述

    在这里插入图片描述

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

    在这里插入图片描述

    6 源码

  • 相关阅读:
    asp.net FckEditor配置
    您请求的报表需要更多信息...
    水晶报表中如何动态增加字段
    使用JavaMail发送SMTP认证的邮件给多个收信人
    vim中删除每行行尾的空格
    转载:STUN在SIP中的工作原理及过程
    转载 URL和URI的区别
    转载 Android深入浅出Binder机制
    链接静态库的时候,命令行中库和源文件的位置问题
    使用dumpbin来查看程序的依赖
  • 原文地址:https://www.cnblogs.com/6b7b5fc3/p/12715794.html
Copyright © 2011-2022 走看看