W tym przykładzie dowiesz się, jak używać Spring Boot Data JPA do implementacji operacji wstawiania, aktualizowania, usuwania i wybierania tabeli bazy danych na tabeli bazy danych MySQL. W przypadku Spring Boot Data JPA polecenie obsługi tabeli bazy danych zostało powiązane z metodą, wystarczy utworzyć interfejs Java, który rozszerza podstawowy interfejs Spring Boot Data JPA Repository (na przykład CrudRepository ), wystarczy zdefiniować metodę obsługi tabeli bazy danych (np. findBy
1. Utwórz tabelę bazy danych MySQL.
- Utwórz bazę danych MySQL o nazwie dev2qa_example . domyślne sortowanie bazy danych powinno być utf8 – utf8_bin .
CREATE SCHEMA `dev2qa_example` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin ;
- Utwórz tabelę konto_użytkownika w powyższym dev2qa_example bazy danych z poniższą instrukcją SQL. Identyfikator kolumna powinna mieć wartość AI (automatyczne przyrosty), w przeciwnym razie zostanie zgłoszony błąd Spring Boot JPA Table 'dbname.hibernate_sequence' Don't Exist.
CREATE TABLE `dev2qa_example`.`user_account` ( `id` INT NOT NULL AUTO_INCREMENT, `user_name` VARCHAR(100) NULL, `password` VARCHAR(100) NULL, `email` VARCHAR(100) NULL, PRIMARY KEY (`id`)) ENGINE = InnoDB DEFAULT CHARACTER SET = utf8 COLLATE = utf8_bin;
2. Utwórz projekt Spring Boot.
- Uruchom pakiet narzędzi Spring, kliknij Plik —> Nowy —> Projekt Spring Starter element menu do otwarcia poniżej Nowy projekt Spring Starter czarodziej. Wprowadź informacje dotyczące projektu, jak poniżej. I kliknij przycisk Dalej.
- Dodaj JPA , MySQL, i Sieć biblioteki w kreatorze zależności. I kliknij Zakończ przycisk, aby zakończyć inicjalizację projektu.
3. Przykładowe pliki projektu Spring Boot JPA CRUD.
Poniżej znajdują się pliki źródłowe w tym projekcie. Przedstawimy je jeden po drugim.
C:\WORKSPACE\WORK\DEV2QA.COM-EXAMPLE-CODE\SPRINGBOOT\SPRINGBOOTCRUDMYSQL │ pom.xml └───src ├───main │ ├───java │ │ └───com │ │ └───dev2qa │ │ └───example │ │ │ SpringBootCrudMySqlApplication.java │ │ │ │ │ ├───controller │ │ │ UserAccountController.java │ │ │ │ │ ├───entity │ │ │ UserAccount.java │ │ │ │ │ └───repository │ │ UserAccountRepository.java │ │ │ └───resources │ application.properties │ └───test └───java └───com └───dev2qa SpringBootCrudMySqlApplicationTests.java
3.1 SpringBootCrudMySqlApplication.java
To jest przykład wiosennego rozruchu uruchamiającego klasę java. Zostanie załadowany i uruchomiony jako pierwszy w aplikacji Spring Boot.
package com.dev2qa.example; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; //@SpringBootApplication @Configuration @ComponentScan(basePackages = { "com.dev2qa.example" }) @EnableAutoConfiguration public class SpringBootCrudMySqlApplication { public static void main(String[] args) { SpringApplication.run(SpringBootCrudMySqlApplication.class, args); } }
3.2 UserAccountController.java
Jest to klasa java kontrolera spring MVC, która mapuje adres URL żądania użytkownika na metodę przetwarzania.
package com.dev2qa.example.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import com.dev2qa.example.entity.UserAccount; import com.dev2qa.example.repository.UserAccountRepository; @Controller @RequestMapping(path = "/userAccount") public class UserAccountController { @Autowired UserAccountRepository userAccountRepository; /* * Mapping url exmaple: * http://localhost:8080/userAccount/add?userName=Jerry&password=888888&email= * [email protected] * http://localhost:8080/userAccount/add?userName=Richard&password=888888&email= * [email protected] */ @GetMapping(path = "/add") @ResponseBody public String addUser(@RequestParam String userName, @RequestParam String password, @RequestParam String email) { UserAccount userAccount = new UserAccount(); userAccount.setUsername(userName); userAccount.setPassword(password); userAccount.setEmail(email); userAccountRepository.save(userAccount); String ret = "User account has been added, user name = " + userName + ", password = " + password + ", email = " + email; return ret; } /* * Mapping url exmaple: http://localhost:8080/userAccount/findAll */ @GetMapping(path = "/findAll") @ResponseBody public String findAllUser() { StringBuffer retBuf = new StringBuffer(); List<UserAccount> userAccountList = (List<UserAccount>) userAccountRepository.findAll(); if (userAccountList != null) { for (UserAccount userAccount : userAccountList) { retBuf.append("user name = "); retBuf.append(userAccount.getUsername()); retBuf.append(", password = "); retBuf.append(userAccount.getPassword()); retBuf.append(", email = "); retBuf.append(userAccount.getEmail()); retBuf.append("\r\n"); } } if (retBuf.length() == 0) { retBuf.append("No record find."); } else { retBuf.insert(0, "<pre>"); retBuf.append("</pre>"); } return retBuf.toString(); } /* * Mapping url exmaple: * http://localhost:8080/userAccount/findByName?userName=Jerry */ @GetMapping(path = "/findByName") @ResponseBody public String findByName(@RequestParam String userName) { StringBuffer retBuf = new StringBuffer(); List<UserAccount> userAccountList = (List<UserAccount>) userAccountRepository.findByUsername(userName); if (userAccountList != null) { for (UserAccount userAccount : userAccountList) { retBuf.append("user name = "); retBuf.append(userAccount.getUsername()); retBuf.append(", password = "); retBuf.append(userAccount.getPassword()); retBuf.append(", email = "); retBuf.append(userAccount.getEmail()); retBuf.append("\r\n"); } } if (retBuf.length() == 0) { retBuf.append("No record find."); } return retBuf.toString(); } /* * Mapping url exmaple: * http://localhost:8080/userAccount/findByNameAndPassword?userName=Jerry& * password=888888 */ @GetMapping(path = "/findByNameAndPassword") @ResponseBody public String findByNameAndPassword(@RequestParam String userName, @RequestParam String password) { StringBuffer retBuf = new StringBuffer(); List<UserAccount> userAccountList = (List<UserAccount>) userAccountRepository .findByUsernameAndPassword(userName, password); if (userAccountList != null) { for (UserAccount userAccount : userAccountList) { retBuf.append("user name = "); retBuf.append(userAccount.getUsername()); retBuf.append(", password = "); retBuf.append(userAccount.getPassword()); retBuf.append(", email = "); retBuf.append(userAccount.getEmail()); retBuf.append("<br/>"); } } if (retBuf.length() == 0) { retBuf.append("No record find."); } return retBuf.toString(); } /* * Mapping url exmaple: * http://localhost:8080/userAccount/updateUser?userName=Jerry&password=hello& * [email protected] */ @GetMapping(path = "/updateUser") @ResponseBody public String updateUser(@RequestParam String userName, @RequestParam String password, @RequestParam String email) { StringBuffer retBuf = new StringBuffer(); List<UserAccount> userAccountList = userAccountRepository.findByUsername(userName); if (userAccountList != null) { for (UserAccount userAccount : userAccountList) { userAccount.setUsername(userName); userAccount.setPassword(password); userAccount.setEmail(email); userAccountRepository.save(userAccount); } } retBuf.append("User data update successfully."); return retBuf.toString(); } /* * Mapping url exmaple: * http://localhost:8080/userAccount/deleteByUserName?userName=Richard */ @GetMapping(path = "/deleteByUserName") @ResponseBody public String deleteByUserName(@RequestParam String userName) { StringBuffer retBuf = new StringBuffer(); userAccountRepository.deleteByUsername(userName); retBuf.append("User data has been deleted successfully."); return retBuf.toString(); } /* * Mapping url exmaple: * http://localhost:8080/userAccount/deleteByUserNameAndPassword?userName= * Richard&password=888888 */ @GetMapping(path = "/deleteByUserNameAndPassword") @ResponseBody public String deleteByUserNameAndPassword(@RequestParam String userName, @RequestParam String password) { StringBuffer retBuf = new StringBuffer(); userAccountRepository.deleteByUsernameAndPassword(userName, password); retBuf.append("User data has been deleted successfully."); return retBuf.toString(); } }"); } return retBuf.toString(); } /* * Przykładowy adres URL mapowania:* http://localhost:8080/userAccount/findByName?userName=Jerry */ @GetMapping(path ="/findByName") @ResponseBody public String findByName(@RequestParam String userName) { StringBuffer retBuf =nowy StringBuffer(); Lista
"); } } if (retBuf.length() ==0) { retBuf.append("Nie znaleziono rekordu."); } return retBuf.toString(); } /* * Przykład mapowania adresu URL:* http://localhost:8080/userAccount/updateUser?userName=Jerry&password=hello&* [email protected] */ @GetMapping(path ="/updateUser") @ResponseBody public String updateUser( @RequestParam String userName, @RequestParam String hasło, @RequestParam String email) { StringBuffer retBuf =new StringBuffer(); List
3.3 Konto użytkownika.java
To jest klasa java encji, która zostanie zmapowana do tabeli MySQL user_account . Zwróć uwagę na identyfikator generowana strategia musi mieć wartość GenerationType.IDENTITY , jeśli używasz Generation.AUTO a kolumna identyfikatora tabeli MySQL jest ustawiona na automatyczne zwiększanie, wtedy zostanie zgłoszony błąd.
package com.dev2qa.example.entity; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; /* Map this entity class to user_account table. */ @Entity(name = "user_account") public class UserAccount { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @javax.persistence.Column(name = "user_name") private String username; private String password; private String email; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }
3.4 UserAccountRepository.java
To jest niestandardowy interfejs repozytorium JPA danych rozruchu wiosennego, który rozszerza CrudRepository . Wystarczy zdefiniować powiązane metody, a framework spring automatycznie uruchomi powiązane polecenie SQL, aby zaimplementować metodę. Dzięki temu kodowanie jest szybsze.
package com.dev2qa.example.repository; import java.util.List; import org.springframework.data.repository.CrudRepository; import org.springframework.transaction.annotation.Transactional; import com.dev2qa.example.entity.UserAccount; public interface UserAccountRepository extends CrudRepository<UserAccount, Long> { /* * Get user list by user name. Please note the format should be * findBy<column_name>. */ List<UserAccount> findByUsername(String username); /* * Get user list by user name and password. Please note the format should be * findBy<column_name_1>And<column_name_2>. */ List<UserAccount> findByUsernameAndPassword(String username, String password); @Transactional void deleteByUsernameAndPassword(String username, String password); @Transactional void deleteByUsername(String username); }
3.5 aplikacja.właściwości
To jest plik zasobów, który zawiera dane połączenia ze źródłem danych MySQL JDBC używane w przykładzie.
# MySQL jdbc connection url. spring.datasource.url=jdbc:mysql://localhost:3306/dev2qa_example # MySQL jdbc driver class name. spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver # MySQL database username and password spring.datasource.username=root spring.datasource.password=root
3,6 pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>SpringBootCRUDMySQL</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>SpringBootCRUDMySQL</name> <description>Spring boot access mysql with crud operation.</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.0.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
3.7 Uruchom przykład.
- Kliknij prawym przyciskiem myszy nazwę projektu.
- Kliknij Uruchom jako —> Aplikacja Spring Boot element menu z listy menu podręcznego.
- Po uruchomieniu aplikacji wprowadź adres URL mapowania dla powiązanego UserAccountController metoda klasy java w przeglądarce internetowej, aby zobaczyć wynik.
4. Pytania i odpowiedzi.
4.1 Metody Spring Boot findAll, findById, deleteById wszystkie zwracają puste wyniki.
- Chcę użyć Spring boot + MySQL do zaimplementowania aplikacji REST, która będzie wykonywać akcje CRUD w celu manipulowania tabelą MySQL. Ale znajduję, kiedy wykonuję findAll() metoda, zwraca pustą listę, nie tego się spodziewam. Kiedy wykonuję findById() metody, zwraca komunikat o błędzie java.util.NoSuchElementException:Brak wartości . A kiedy wykonuję akcję usuwania za pomocą metody wiosennego rozruchu deleteById() , mówi mi również, że Nie istnieje encja klasy org.dev2qa.entity.Article o identyfikatorze 10 ! Wygląda na to, że moja tabela bazy danych jest pusta, ale tak nie jest. W jakim przypadku mogą wystąpić te błędy?
- Moja niestandardowa klasa repozytorium rozszerza JpaRepository klasę i jej findAll() metoda zwraca również pustą listę. Moja baza danych to również baza danych MySql. Kiedy dodaję jeden rekord w bazie danych MySQL, findAll() powrót metody [{}] , a kiedy dodam dwa rekordy w bazie danych MySQL, findAll() metoda zwraca [{},{}] . Numer elementu listy jest poprawny, ale dane elementu są puste, to nie jest poprawne. Czy ktoś może mi pomóc? Wielkie dzięki.
- Jeśli właściwości klasy encji nie są publiczne, może wystąpić ten błąd. Najpierw należy zadeklarować właściwości klasy jednostki za pomocą @Column adnotacja i deklaracja właściwości mogą być prywatne, a następnie dodaj metodę pobierającą i ustawiającą do tych właściwości i upublicznij metodę pobierającą i ustawiającą. Następnie JpaRepository może utworzyć obiekt encji i wypełnić właściwości obiektu danymi odczytanymi z bazy danych MySQL. A twoja findAll() metoda w ogóle nie zwróci pustej listy.
Odniesienie
- Jak zainstalować MySQL na Ubuntu
- Rozwiąż tabelę Spring Boot JPA „dbname.hibernate_sequence” nie istnieje błąd