С учетом современных тенденций в области разработки программного обеспечения гибкость и быстрая доставка программных приложений стали неотъемлемой частью ИТ-индустрии. Фактически это стало одной из основных причин эволюции многих современных технологий и тенденций, таких как одностраничные приложения, облегченные платформы и архитектура микросервисов.
Даже несмотря на значительные улучшения в технологиях, IDE и инструментах, разработчики все еще пишут много кода, чтобы выполнить свою работу. Для повышения производительности разработчиков программного обеспечения и снижения стоимости разработки программного обеспечения была создана платформа Clowiz .
Clowiz — это облачная платформа, которая позволяет разработчикам создавать программные артефакты (используя CodeGen), сквозные функции (используя FeatureGen) и полные сквозные приложения (используя AppGen) без написания одной строки кода.
В этой статье мы собираемся:
- Создайте и настройте следующие проекты:
- iOS Swift App
- Spring Boot Rest API
- Создание артефактов приложения с помощью Clowiz:
- Создайте и используйте следующие артефакты в приложении iOS:
- Список ViewController
- Добавить / Редактировать ViewController
- Посмотреть список
- Добавить / изменить вид
- модель
- Аламофире Сервис
- Создайте и используйте следующие артефакты в приложении Spring Boot:
- Репозиторий JPA
- сущность
- Rest API Controller
- Создайте и используйте следующие артефакты в приложении iOS:
- Запустите и протестируйте проект
Создать приложение iOS Swift
Используя XCode:
- Создайте новый проект iOS Storyboard с приложением Single View.
- Добавьте Alamofire POD в проект. ( Как добавить Alamofire в xCode , последнюю версию Alamofire )
- Удалите файл «Main.storyboard» и его ссылки из файла «Info.plist». ( Создать проект без раскадровки )
- Переименуйте файл «ViewController.swift» в «TabBarVC.swift».
- Измените имя класса на TabBarVC.
- Измените rootViewCntroller на a на наш TabBarVC, заменив функцию сцены в файле SceneDelegate.swift следующим:
стриж
xxxxxxxxxx
1
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
2
guard let windowScene = (scene as? UIWindowScene) else { return }
3
window = UIWindow(frame: windowScene.coordinateSpace.bounds)
4
window?.windowScene = windowScene
5
window?.rootViewController = TabBarVC()
6
window?.makeKeyAndVisible()
7
}
- Создайте новый подкласс UIViewController и назовите его «HomeVC.swift» со следующим содержанием:
стриж
xxxxxxxxxx
1
import UIKit
2
class HomeVC: UIViewController {
4
override func viewDidLoad() {
5
super.viewDidLoad()
6
view.backgroundColor = .white
7
navigationItem.title = "Home"
8
}
9
}
- Добавьте UINavigationController на свои вкладки в классе TabBarVC.
стриж
xxxxxxxxxx
1
import UIKit
2
class TabBarVC: UITabBarController {
4
override func viewDidLoad() {
5
super.viewDidLoad()
6
view.backgroundColor = .white
7
setupTabBar()
8
}
9
10
func setupTabBar() {
11
let homeVC = UINavigationController(rootViewController: HomeVC())
12
homeVC.tabBarItem.title = "Home"
13
viewControllers = [homeVC]
14
}
15
}
При запуске приложения отображается панель вкладок и пустая страница домашней навигации, теперь мы можем расширить приложение и добавить к нему больше функциональных возможностей.
Генерация iOS-артефактов
Чтобы ускорить процесс разработки, используйте функцию CodeGen от Clowiz для генерации исходного кода артефактов проекта за одну минуту для обоих приложений.
Чтобы создать артефакты для приложений, iOS и Spring Boot:
- Перейдите в Clowiz , затем перейдите к CodeGen https://www.clowiz.com/
- Из технологий выберите iOS.
- В разделе метаданных назовите свои артефакты, например, Сотрудник.
- Для первого поля в поле имени введите «Имя» и оставьте «Текст».
- Создайте еще два поля, например, Email и Salary, с типами данных email и double.
- Проверьте все поля, как требуется.
CodeGen создал следующие артефакты для проекта:
Модель.
стриж
xxxxxxxxxx
1
import UIKit
2
class Employee: NSObject, Codable {
4
5
var id: Int?
6
var name: String?
7
var email: String?
8
var salary: Double?
9
10
override init() {
11
super.init()
12
}
13
14
}
Представление ячейки: представляет данные в каждой строке таблицы:
стриж
x
1
import UIKit
2
class EmployeeCell: UITableViewCell {
4
5
var idLabel = UILabel()
6
var id = UILabel()
7
var nameLabel = UILabel()
8
var name = UILabel()
9
var emailLabel = UILabel()
10
var email = UILabel()
11
var salaryLabel = UILabel()
12
var salary = UILabel()
13
14
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
15
super.init(style: style, reuseIdentifier: reuseIdentifier)
16
addSubViews()
17
}
18
19
required init?(coder: NSCoder) {
20
super.init(coder: coder)
21
}
22
23
func addSubViews() {
24
idLabel.text = "Id:"
25
self.addSubview(idLabel)
26
self.addSubview(id)
27
nameLabel.text = "Name:"
28
self.addSubview(nameLabel)
29
self.addSubview(name)
30
emailLabel.text = "Email:"
31
self.addSubview(emailLabel)
32
self.addSubview(email)
33
salaryLabel.text = "Salary:"
34
self.addSubview(salaryLabel)
35
self.addSubview(salary)
36
37
setupFields()
38
}
39
40
func setupFields() {
41
id.anchor(top: self.topAnchor, bottom: nil, left: idLabel.rightAnchor, right: nil)
42
idLabel.anchor(top: self.topAnchor, bottom: nil, left: self.leftAnchor, right: nil)
43
name.anchor(top: id.bottomAnchor, bottom: nil, left: nameLabel.rightAnchor, right: nil)
44
nameLabel.anchor(top: idLabel.bottomAnchor, bottom: nil, left: self.leftAnchor, right: nil)
45
email.anchor(top: name.bottomAnchor, bottom: nil, left: emailLabel.rightAnchor, right: nil)
46
emailLabel.anchor(top: nameLabel.bottomAnchor, bottom: nil, left: self.leftAnchor, right: nil)
47
salary.anchor(top: email.bottomAnchor, bottom: self.bottomAnchor, left: salaryLabel.rightAnchor, right: nil)
48
salaryLabel.anchor(top: emailLabel.bottomAnchor, bottom: self.bottomAnchor, left: self.leftAnchor, right: nil)
49
}
50
51
func setEmployee(employee: Employee) {
52
id.text = String(employee.id ?? 0)
53
name.text = (employee.name?.elementsEqual(""))! ? "-" : employee.name
54
email.text = (employee.email?.elementsEqual(""))! ? "-" : employee.email
55
salary.text = String(employee.salary ?? 0.0)
56
}
57
}
Add Edit View: содержит поля ввода (имя, адрес электронной почты, поля ввода зарплаты) и их метки.
стриж
x
1
import UIKit
2
class AddEmployeeView: UIView, UITextFieldDelegate {
4
5
var nameLabel = UILabel()
6
var name = UITextField()
7
var emailLabel = UILabel()
8
var email = UITextField()
9
var salaryLabel = UILabel()
10
var salary = UITextField()
11
12
var scrollView = UIScrollView()
13
14
var textFields: [UITextField] {
15
return [name,email,salary]
16
}
17
18
override init(frame: CGRect) {
19
super.init(frame: frame)
20
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
21
self.addGestureRecognizer(tap)
22
setupScrollView()
23
setupFields()
24
}
25
26
required init?(coder: NSCoder) {
27
super.init(coder: coder)
28
}
29
30
func setupFields() {
31
textFields.forEach { $0.delegate = self }
32
nameLabel.text = "Name: *"
33
name.placeholder = "Name"
34
emailLabel.text = "Email: *"
35
email.keyboardType = .emailAddress
36
email.placeholder = "Email"
37
salaryLabel.text = "Salary: *"
38
salary.keyboardType = .decimalPad
39
salary.placeholder = "Salary"
40
41
setFieldConstraints()
42
}
43
44
func setFieldConstraints() {
45
nameLabel.anchor(top: scrollView.topAnchor, bottom: nil, left: scrollView.leftAnchor, right: nil)
46
name.anchor(top: scrollView.topAnchor, bottom: nil, left: nameLabel.rightAnchor, right: nil)
47
emailLabel.anchor(top: nameLabel.bottomAnchor, bottom: nil, left: scrollView.leftAnchor, right: nil)
48
email.anchor(top: name.bottomAnchor, bottom: nil, left: emailLabel.rightAnchor, right: nil)
49
salaryLabel.anchor(top: emailLabel.bottomAnchor, bottom: scrollView.bottomAnchor, left: scrollView.leftAnchor, right: nil)
50
salary.anchor(top: email.bottomAnchor, bottom: scrollView.bottomAnchor, left: salaryLabel.rightAnchor, right: nil)
51
}
52
53
func setupScrollView() {
54
self.addSubview(scrollView)
55
scrollView.addSubview(nameLabel)
56
scrollView.addSubview(name)
57
scrollView.addSubview(emailLabel)
58
scrollView.addSubview(email)
59
scrollView.addSubview(salaryLabel)
60
scrollView.addSubview(salary)
61
scrollView.contentSize.height = 2000
62
scrollView.anchor(top: self.topAnchor, bottom: self.bottomAnchor, left: self.leftAnchor, right: self.rightAnchor)
63
}
64
65
@objc func dismissKeyboard() {
66
self.endEditing(true)
67
}
68
69
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
70
if let selectedTextFieldIndex = textFields.firstIndex(of: textField), selectedTextFieldIndex < textFields.count - 1 {
71
textFields[selectedTextFieldIndex + 1].becomeFirstResponder()
72
} else {
73
textField.resignFirstResponder()
74
}
75
return true
76
}
77
78
}
79
extension UIView {
81
func anchor(top: NSLayoutYAxisAnchor?, bottom: NSLayoutYAxisAnchor?, left: NSLayoutXAxisAnchor?, right: NSLayoutXAxisAnchor?) {
82
translatesAutoresizingMaskIntoConstraints = false
83
if let top = top {
84
topAnchor.constraint(equalTo: top, constant: 15).isActive = true
85
}
86
if let left = left {
87
leftAnchor.constraint(equalTo: left, constant: 15).isActive = true
88
}
89
if let right = right {
90
rightAnchor.constraint(equalTo: right, constant: -15).isActive = true
91
}
92
if let bottom = bottom {
93
bottomAnchor.constraint(equalTo: bottom, constant: -15).isActive = true
94
}
95
}
96
}
Add Edit VC: используется для добавления и редактирования данных.
стриж
x
1
import UIKit
2
class AddEmployeeVC: UIViewController {
4
5
var addEmployeeView = AddEmployeeView()
6
var employeeService = EmployeeService()
7
var employee = Employee()
8
9
override func loadView() {
10
view = addEmployeeView
11
}
12
13
override func viewDidLoad() {
14
super.viewDidLoad()
15
view.backgroundColor = .white
16
isEditMode()
17
}
18
19
func isEditMode() {
20
if(employee.id != nil) {
21
addEmployeeView.name.text = employee.name
22
addEmployeeView.email.text = employee.email
23
addEmployeeView.salary.text = String(employee.salary ?? 0.0)
24
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Save", style: .plain, target: self, action: #selector(updateEmployee))
25
} else {
26
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Save", style: .plain, target: self, action: #selector(createEmployee))
27
}
28
}
29
30
@objc func createEmployee() {
31
if(validate()) {
32
employeeService.createEmployee(employee: employee){ (res) in
33
switch res {
34
case .success(_):
35
NotificationCenter.default.post(name: Notification.Name("reloadNotification"), object: nil)
36
self.navigationController?.popViewController(animated: true)
37
case .failure(_):
38
self.showAlert(withTitle: "Network Error",
39
withMessage: "Failed to create Employee",
40
parentController: self,
41
okBlock: {},
42
cancelBlock: nil)
43
}
44
}
45
}
46
}
47
48
@objc func updateEmployee() {
49
if(validate()) {
50
employeeService.updateEmployee(id: employee.id!, employee: employee){ (res) in
51
switch res {
52
case .success(_):
53
NotificationCenter.default.post(name: Notification.Name("reloadNotification"), object: nil)
54
self.navigationController?.popViewController(animated: true)
55
case .failure(_):
56
self.showAlert(withTitle: "Network Error",
57
withMessage: "Failed to update Employee",
58
parentController: self,
59
okBlock: {},
60
cancelBlock: nil)
61
}
62
}
63
}
64
}
65
66
func validate() -> Bool {
67
if(addEmployeeView.name.text!.isEmpty) {
68
showAlert(withTitle: "Failed to add Employee",
69
withMessage: "Name is required.",
70
parentController: self,
71
okBlock: {},
72
cancelBlock: nil)
73
return false
74
}
75
employee.name = addEmployeeView.name.text
76
if(addEmployeeView.email.text!.isEmpty) {
77
showAlert(withTitle: "Failed to add Employee",
78
withMessage: "Email is required.",
79
parentController: self,
80
okBlock: {},
81
cancelBlock: nil)
82
return false
83
}
84
employee.email = addEmployeeView.email.text
85
if(addEmployeeView.salary.text!.isEmpty) {
86
showAlert(withTitle: "Failed to add Employee",
87
withMessage: "Salary is required.",
88
parentController: self,
89
okBlock: {},
90
cancelBlock: nil)
91
return false
92
}
93
employee.salary = Double(addEmployeeView.salary.text ?? "0.0")
94
return true
95
}
96
97
}
98
extension UIViewController {
99
func showAlert(withTitle title : String, withMessage message: String?, parentController parent : UIViewController, okBlock : @escaping () -> (), cancelBlock : (() -> ())?) {
100
let alert : UIAlertController = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
101
let okAction : UIAlertAction = UIAlertAction(title: "OK", style: UIAlertAction.Style.default) { (alert : UIAlertAction) in
102
okBlock()
103
}
104
if (cancelBlock != nil) {
105
let cancelAction : UIAlertAction = UIAlertAction(title: "Cancel", style: UIAlertAction.Style.default) { (alert : UIAlertAction) in
106
cancelBlock!()
107
}
108
alert.addAction(cancelAction)
109
}
110
alert.addAction(okAction)
111
parent.present(alert, animated: true) {
112
}
113
}
114
}
Список VC: используется для отображения и удаления данных.
стриж
x
1
import UIKit
2
class EmployeeListVC: UIViewController {
4
5
var employeeTable = UITableView()
6
var employeeService = EmployeeService()
7
var employees: [Employee] = []
8
9
var searchBar = UISearchBar()
10
var isSearching: Bool = false
11
var searchResults: [Employee] = []
12
let refreshControl = UIRefreshControl()
13
14
override func viewDidLoad() {
15
super.viewDidLoad()
16
navigationItem.title = "Employee"
17
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Add", style: .plain, target: self, action: #selector(create))
18
NotificationCenter.default.addObserver(self, selector: #selector(reload), name: Notification.Name("reloadNotification"), object: nil)
19
self.setupSearchBar()
20
self.setupEmployeeTable()
21
self.getAllEmployees()
22
}
23
24
@objc func refresh(sender: UIRefreshControl){
25
self.getAllEmployees()
26
sender.endRefreshing()
27
}
28
29
@objc func reload(notification: NSNotification){
30
self.getAllEmployees()
31
}
32
33
@objc func create() {
34
let addEmployeeVC = AddEmployeeVC()
35
addEmployeeVC.title = "Add Employee"
36
self.navigationController?.pushViewController(addEmployeeVC, animated: true)
37
}
38
39
func getAllEmployees() {
40
employeeService.getAllEmployees() { (res) in
41
switch res {
42
case .success(let employees):
43
self.employees = employees
44
self.employeeTable.reloadData()
45
case .failure(_):
46
self.showAlert(withTitle: "Network Error",
47
withMessage: "Failed to get Employee:",
48
parentController: self,
49
okBlock: {},
50
cancelBlock: nil)
51
}
52
}
53
}
54
55
func deleteEmployee(id: Int) {
56
employeeService.deleteEmployee(id: id) { (res) in
57
switch res {
58
case .success(_):
59
self.getAllEmployees()
60
case .failure(_):
61
self.showAlert(withTitle: "Network Error",
62
withMessage: "Failed to delete Employee:",
63
parentController: self,
64
okBlock: {},
65
cancelBlock: nil)
66
}
67
}
68
}
69
70
func setupSearchBar() {
71
view.addSubview(searchBar)
72
searchBar.delegate = self
73
searchBar.anchor(top: view.safeAreaLayoutGuide.topAnchor, bottom: nil, left: view.leftAnchor, right: view.rightAnchor)
74
searchBar.placeholder = " Search..."
75
searchBar.delegate = self
76
}
77
78
func setupEmployeeTable() {
79
view.addSubview(employeeTable)
80
setEmployeeTableDelegates()
81
employeeTable.frame = self.view.frame
82
employeeTable.rowHeight = UITableView.automaticDimension
83
employeeTable.register(EmployeeCell.self, forCellReuseIdentifier: "EmployeeCell")
84
employeeTable.refreshControl = refreshControl
85
refreshControl.addTarget(self, action: #selector(refresh), for: .valueChanged)
86
employeeTable.anchor(top: searchBar.bottomAnchor, bottom: view.bottomAnchor, left: view.leftAnchor, right: view.rightAnchor)
87
}
88
89
func setEmployeeTableDelegates() {
90
employeeTable.delegate = self
91
employeeTable.dataSource = self
92
}
93
94
func dismissKeyboard() {
95
self.view.endEditing(true)
96
}
97
}
98
extension EmployeeListVC: UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate {
100
101
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
102
if(isSearching){
103
return searchResults.count
104
}
105
return employees.count
106
}
107
108
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
109
let cell = employeeTable.dequeueReusableCell(withIdentifier: "EmployeeCell") as! EmployeeCell
110
let employee = employees[indexPath.row]
111
if(isSearching){
112
cell.setEmployee(employee: searchResults[indexPath.row])
113
} else {
114
cell.setEmployee(employee: employee)
115
}
116
return cell
117
}
118
119
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
120
let delete = UIContextualAction(style: .destructive, title: "Delete", handler: { (action, view, success) in
121
let employeeId = self.employees[indexPath.row].id
122
self.deleteEmployee(id: employeeId ?? 0)
123
})
124
return UISwipeActionsConfiguration(actions: [delete])
125
}
126
127
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
128
let addEmployeeVC = AddEmployeeVC()
129
addEmployeeVC.employee = self.employees[indexPath.row]
130
addEmployeeVC.title = "Edit Employee"
131
self.navigationController?.pushViewController(addEmployeeVC, animated: true)
132
}
133
134
func searchBar(_ searchBar: UISearchBar, textDidChange textSearched: String) {
135
if(textSearched == "") {
136
dismissKeyboard()
137
isSearching = false
138
employeeTable.reloadData()
139
} else {
140
isSearching = true
141
searchResults = employees.filter {
142
$0.name!.range(of: textSearched, options: .caseInsensitive) != nil
143
}
144
employeeTable.reloadData()
145
}
146
}
147
}
Сервис: сервисный уровень, который использует Alamofire для обработки запросов API.
стриж
x
1
import UIKit
2
import Alamofire
3
class EmployeeService {
5
6
var url = "http://localhost:8080/employee/"
7
8
func getAllEmployees(completion: @escaping (Result<[Employee], Error>) -> ()) {
9
var request = URLRequest(url: URL(string: url)!)
10
request.httpMethod = HTTPMethod.get.rawValue
11
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
12
AF.request(request).validate(statusCode: 200..<300).responseJSON { response in
13
if let err = response.error {
14
completion(.failure(err))
15
return
16
}
17
18
do {
19
let employees = try JSONDecoder().decode([Employee].self, from: response.data!)
20
completion(.success(employees))
21
} catch let jsonError {
22
completion(.failure(jsonError))
23
}
24
}.resume()
25
}
26
27
func createEmployee(employee: Employee, completion: @escaping (Result<Int, Error>) -> ()) {
28
let encoder = JSONEncoder()
29
let data = try! encoder.encode(employee)
30
var request = URLRequest(url: URL(string: url)!)
31
request.httpMethod = HTTPMethod.post.rawValue
32
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
33
request.httpBody = data
34
AF.request(request).validate(statusCode: 200..<300).responseJSON { response in
35
if let err = response.error {
36
completion(.failure(err))
37
return
38
}
39
completion(.success(1))
40
}.resume()
41
}
42
43
func updateEmployee(id: Int, employee: Employee, completion: @escaping (Result<Int, Error>) -> ()) {
44
let encoder = JSONEncoder()
45
let data = try! encoder.encode(employee)
46
var request = URLRequest(url: URL(string: url + String(id))!)
47
request.httpMethod = HTTPMethod.put.rawValue
48
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
49
request.httpBody = data
50
AF.request(request).validate(statusCode: 200..<300).responseJSON { response in
51
if let err = response.error {
52
completion(.failure(err))
53
return
54
}
55
completion(.success(1))
56
}.resume()
57
}
58
59
func deleteEmployee(id: Int, completion: @escaping (Result<Int, Error>) -> ()) {
60
var request = URLRequest(url: URL(string: url + String(id))!)
61
request.httpMethod = HTTPMethod.delete.rawValue
62
AF.request(request).validate(statusCode: 200..<300).responseJSON { response in
63
if let err = response.error {
64
completion(.failure(err))
65
return
66
}
67
completion(.success(1))
68
}.resume()
69
}
70
}
Теперь давайте добавим сгенерированный код в проект, вы можете нажать « Загрузить сгенерированный код» в разделе «Сгенерированный код» в CodeGen, затем добавить загруженные файлы в папку приложения проекта или скопировать и вставить сгенерированный код в проект. (Обратите внимание, что имя файла должно соответствовать имени класса с расширением .swift)
Добавьте EmployeeListViewController на панель навигации в классе TabBar.
стриж
x
1
let employeeVC = UINavigationController(rootViewController: EmployeeListVC())
2
employeeVC.tabBarItem.title = "Employee"
3
viewControllers = [homeVC, employeeVC]
Чтобы сделать проект простым и легким в обслуживании, разделите его на группы (AddView, AddViewController, CellView, ListViewController, Model, Service).
Чтобы запустить приложение, используйте один из предоставленных имитаторов и нажмите «Выполнить».
При запуске приложения отображаются две вкладки: «Дом» и «Сотрудник». Вкладка «Сотрудник» содержит таблицу со списком всех сотрудников, панель поиска и кнопку для добавления нового сотрудника.
Как только вы открываете вкладку «Сотрудник», вы получаете ошибку сети, потому что у нас все еще нет API для обработки запросов.
Создать Spring Boot Rest API
Spring Boot сокращает время разработки и повышает производительность. Это позволяет избежать написания большого количества стандартных кодов, аннотаций и конфигурации XML, однако для начала требуется много кода, но не волнуйтесь, Clowiz поддерживает Spring Boot и может сгенерировать код для нашего API за минуту. ,
Необходимое условие:
Создайте новый проект Spring Boot, используя Spring Initializr :
- Оставьте настройки по умолчанию, такие как Maven Project, Java и версия.
- В поле Group введите: com.app
- В поле Артефакт введите: iosBackend
- Из опций измените имя пакета на com.app
- Найдите и добавьте следующие зависимости:
- Весенняя паутина
- Spring Data JPA
- MySQL Driver
- Нажмите на Generate, чтобы загрузить проект.
Используя любую затмение IDE:
- Импортируйте загруженный проект. (Файл -> Импорт -> Существующий проект Maven)
- Добавьте следующее в файл application.properties в пакете src / main / resources.
Файлы свойств
x
1
# Local IP Address
2
server.address=127.0.0.1
3
spring.jpa.hibernate.ddl-auto=update
4
# MySQL Config
5
spring.datasource.url=jdbc:mysql://localhost:3306/employee?createDatabaseIfNotExist=true
6
spring.datasource.username=mysqlUserName
7
spring.datasource.password=mysqlPassword
Нам не нужно создавать базу данных вручную; Spring JPA делает это автоматически, запомните параметр createDatabaseIfNotExist = true
в URL базы данных .
Создание весенних загрузочных артефактов
Вернемся к Clowiz, нажмите значок Spring Boot в разделе технологий, чтобы сгенерировать необходимый исходный код для API.
Для этого урока используйте следующие сгенерированные артефакты:
Hibernate JPA Entity (Модель).
Джава
xxxxxxxxxx
1
package com.app.models;
2
import javax.persistence.*;
4
5
name="employee") (
6
public class Employee{
7
9
name="id") (
10
strategy = GenerationType.IDENTITY) (
11
Integer id;
12
name="name" , nullable=false) (
14
String name;
15
name="email" , nullable=false) (
17
String email;
18
name="salary" , nullable=false) (
20
Double salary;
21
public void setId(Integer id){
24
this.id=id;
25
}
26
public Integer getId(){
28
return this.id;
29
}
30
public void setName(String name){
32
this.name=name;
33
}
34
public String getName(){
36
return this.name;
37
}
38
public void setEmail(String email){
40
this.email=email;
41
}
42
public String getEmail(){
44
return this.email;
45
}
46
public void setSalary(Double salary){
48
this.salary=salary;
49
}
50
public Double getSalary(){
52
return this.salary;
53
}
54
55
public String toString(){
56
StringBuffer buf=new StringBuffer();
57
buf.append(this.name).append(" ");
58
return buf.toString();
59
}
60
62
public boolean equals(Object obj) {
63
if (obj == null) {
64
return false;
65
}
66
return this.getId() == ((Employee) obj).getId();
67
}
68
}
Сервис SpringData.
Джава
xxxxxxxxxx
1
package com.app.repositories;
2
import java.util.List;
4
import org.springframework.data.jpa.repository.JpaRepository;
5
import org.springframework.stereotype.Service;
6
import com.app.models.Employee;
7
9
public interface EmployeeService extends JpaRepository<Employee, Integer> {
10
public List<Employee> findByName(String name);
11
public List<Employee> findByEmail(String email);
12
public List<Employee> findBySalary(String salary);
13
}
Зрелая весна RestController.
Джава
xxxxxxxxxx
1
package com.app.controllers;
2
import java.util.*;
4
import org.springframework.beans.factory.annotation.Autowired;
5
import org.springframework.http.*;
6
import org.springframework.web.bind.annotation.*;
7
import com.app.models.Employee;
9
import com.app.repositories.EmployeeService;
10
12
"/employee") (
13
public class EmployeeController {
14
16
EmployeeService employeeService;
17
(method = RequestMethod.OPTIONS)
19
ResponseEntity<?> options() {
20
// @formatter:off
21
return ResponseEntity.ok().allow(
22
HttpMethod.GET,
23
HttpMethod.POST,
24
HttpMethod.HEAD,
25
HttpMethod.OPTIONS,
26
HttpMethod.PUT,
27
HttpMethod.DELETE).
28
build();
29
// @formatter:on
30
}
31
33
public ResponseEntity<List<Employee>> getAll() {
34
return ResponseEntity.ok(this.employeeService.findAll());
35
}
36
38
public ResponseEntity<Employee> insert( Employee employee) {
39
Employee save = this.employeeService.save(employee);
40
return ResponseEntity.ok(save);
41
}
42
(value = "/{id}")
44
public ResponseEntity<Employee> find( ("id") int id) {
45
Optional<Employee> object = this.employeeService.findById(id);
46
if (object.isPresent()) {
47
return ResponseEntity.ok(object.get());
48
}
49
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
50
}
51
(value="/{id}")
53
public ResponseEntity<Employee> delete( int id){
54
Optional<Employee> object = this.employeeService.findById(id);
55
if(object.isPresent()) {
56
this.employeeService.deleteById(id);
57
return ResponseEntity.noContent().build();
58
}
59
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
60
}
61
(value="/{id}")
63
public ResponseEntity<Employee> save( int id, Employee employee){
64
Optional<Employee> object = this.employeeService.findById(id);
65
if(object.isPresent()) {
66
employee.setId(id);
67
this.employeeService.save(employee);
68
return ResponseEntity.noContent().build();
69
}
70
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
71
}
72
}
Как мы это делали в проекте iOS, скопируйте и вставьте сгенерированный код в нужные пакеты с правильными именами классов, или вы можете скачать его, нажав Download Generated Code .
Чтобы сделать проект простым и легким в обслуживании, разделите его на пакеты (контроллеры, модели, репозитории).
Убедитесь, что URL-адрес в классе службы iOS соответствует IP-адресу файлового сервера свойств Spring Boot.
Чтобы запустить проект, откройте класс IosBackendApplication.java, щелкните правой кнопкой мыши и запустите приложение Java от имени.
Вы можете проверить это с помощью любого инструмента, такого как Postman , или с помощью любого браузера, посетите: http://127.0.0.1/employee. Это должно вернуть пустой список [], так как у нас нет данных в базе данных.
Запуск приложения
После запуска Spring Boot API перезапустите проект iOS.
- Перейти на вкладку Сотрудник
- Нажмите на кнопку Добавить
- Заполните данные сотрудника
- Нажмите на сохранить
- Нажмите на строку, чтобы редактировать ее
- Проведите строку, чтобы удалить ее