天天看點

後端Spring Boot+前端Android互動+MySQL增删查改

後端Spring Boot+前端Android互動+MySQL增删查改

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,像上面一樣
  • "查"使用

    findAll

    findById

    ,自定義查找的話需要自己編寫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;
           
後端Spring Boot+前端Android互動+MySQL增删查改

但是文檔說了不會為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 測試

原始資料庫:

後端Spring Boot+前端Android互動+MySQL增删查改

注冊一個:

後端Spring Boot+前端Android互動+MySQL增删查改

看看資料庫:

後端Spring Boot+前端Android互動+MySQL增删查改

測試登入:

後端Spring Boot+前端Android互動+MySQL增删查改

試試登入一個不存在的:

後端Spring Boot+前端Android互動+MySQL增删查改

修改:

後端Spring Boot+前端Android互動+MySQL增删查改
後端Spring Boot+前端Android互動+MySQL增删查改
後端Spring Boot+前端Android互動+MySQL增删查改

最後是删除:

後端Spring Boot+前端Android互動+MySQL增删查改
後端Spring Boot+前端Android互動+MySQL增删查改

删除一個不存在的會删除失敗.

後端Spring Boot+前端Android互動+MySQL增删查改

6 源碼

  • Github
  • 碼雲
  • CODE.CHINA

如果覺得文章好看,歡迎點贊。

同時歡迎關注微信公衆号:氷泠之路。

後端Spring Boot+前端Android互動+MySQL增删查改

繼續閱讀