[读书笔记] 四、SpringBoot中使用JPA 进行快速CRUD操作
通过Spring提供的JPA Hibernate实现,进行快速CRUD操作的一个栗子~。
视图用到了SpringBoot推荐的thymeleaf来解析,数据库使用的Mysql,代码详细我会贴在下面文章中,请大家参考借鉴。
一、数据库表结构
CREATE TABLE `spring_jpa_test_table` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `message` TEXT NULL, INDEX `id` (`id`) ) ENGINE=InnoDB ;
二、POM.xml
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<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.springboot</groupId> <artifactId>springboot_test1_1</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springboot_test1_1</name> <url>http://maven.apache.org</url> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.2.RELEASE</version> <relativePath /> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> </dependencies> <build> <finalName>my-spring-boot</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>springloaded</artifactId> <version>1.2.6.RELEASE</version> </dependency> </dependencies> </plugin> </plugins> </build> </project>
三、VO/PO
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package core.vo; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name = "spring_jpa_test_table") public class JpaTestTablePO { private int id; private String message; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) public int getId() { return id; } public void setId(int id) { this.id = id; } @Column(name = "message") public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
四、DAO
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package core.dao; import java.io.Serializable; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import core.vo.JpaTestTablePO; public interface JpaTestTableDao extends JpaRepository<JpaTestTablePO, Serializable> { public List<JpaTestTablePO> findByMessageContaining(String message); }
五、Service
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package core.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import core.dao.JpaTestTableDao; import core.vo.JpaTestTablePO; @Service public class TestService { @Autowired JpaTestTableDao jpaTestTableDao; // SpringBoot JPA 默认CRUD实现 public void save(JpaTestTablePO po) { jpaTestTableDao.save(po); } public List<JpaTestTablePO> list() { return jpaTestTableDao.findAll(); } public void delete(int id) { jpaTestTableDao.delete(id); } // SpringBoot JPA 简单查询 public List<JpaTestTablePO> findByMessageContaining(String message) { return jpaTestTableDao.findByMessageContaining(message); } }
六、Controller
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package core; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.servlet.ModelAndView; import core.service.TestService; import core.vo.JpaTestTablePO; @Controller public class HomePageController { @Autowired TestService service; @RequestMapping(value = "/home", method = RequestMethod.GET) public String toIndex(Map<String, Object> model) { model.put("pos", service.list()); return "index"; } @RequestMapping(value = "/home", method = RequestMethod.POST) public String toIndex2(JpaTestTablePO po, Map<String, Object> model) { model.put("pos", service.findByMessageContaining(po.getMessage())); return "index"; } @RequestMapping(value = "/save", method = RequestMethod.POST) public ModelAndView save(JpaTestTablePO po) { service.save(po); return new ModelAndView("redirect:/home"); } @RequestMapping(value = "/delete/{id}", method = RequestMethod.GET) public ModelAndView delete(@PathVariable("id") String id) { service.delete(Integer.parseInt(id)); return new ModelAndView("redirect:/home"); } }
七、application.properties
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
spring.datasource.url = jdbc:mysql://localhost:3306/test spring.datasource.username = root spring.datasource.password = root spring.datasource.driverClassName = com.mysql.jdbc.Driver # Specify the DBMS spring.jpa.database = MYSQL # Show or not log for each sql query spring.jpa.show-sql = true # Hibernate ddl auto (create, create-drop, update) spring.jpa.hibernate.ddl-auto = update # Naming strategy spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy # stripped before adding them to the entity manager) spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect #spring.thymeleaf.prefix=classpath:/templates/ #spring.thymeleaf.suffix=.html #spring.thymeleaf.mode=HTML5 #spring.thymeleaf.encoding=UTF-8 # ;charset=<encoding> is added #spring.thymeleaf.content-type=text/html # set to false for hot refresh spring.thymeleaf.cache=false
八、index.html
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"> <head> <script src="http://cdn.static.runoob.com/libs/angular.js/1.4.6/angular.min.js"></script> <script type="text/javascript"> var app = angular.module('myApp', []); app.controller('myCtrl', function($scope) { $scope.txtChange = function() { } }); </script> </head> <body> <p th:text="${hello}"></p> <!-- SEARCH TABLE --> <form action="http://localhost:8080/home" method="post"> <p> Search Condition: <input type="text" name="message"/> <input type="submit" value="Search" /> </p> </form> <br /> <table border="1" width="400"> <tr> <th colspan="3" align="center">Messages</th> </tr> <tr> <td>Id</td> <td>Message</td> <td>Opt</td> </tr> <tr th:each="m,index: ${pos}"> <td th:text="${index.index}+1"></td> <td th:text="${m.message}"></td> <td><a th:href="'/delete/' + ${m.id }">delete</a></td> </tr> </table> <br /> <div ng-app="myApp"> <div ng-controller="myCtrl"> <form action="http://localhost:8080/save" method="post"> <p> Message: <input type="text" name="message" ng-model="message" ng-blur="txtChange();" /> <input type="submit" value="Save" /> </p> </form> </div> </div> </body> </html>
项目目录结构: