先說下什麼是JPA吧,JPA實際上是EJB3.0的一個規範,相信老程序員都知道啦,它是基於O/R映射的標準規範,目前最新版本是JPA2.1。既然是規範即只定義了標準規則,不提供實現,軟件提供商按照標準進行實現,使用者只須要按照標準定義的方式進行使用便可(就像JDBC同樣)。java
今天的主角是Spring data JPA,它是spring data的一個分支,默認是使用Hibernate實現(固然還有EclipseLink、OpenJPA等均可以)。因此咱們做爲使用者只須要按照規範使用便可,若是須要深度的定製一些內容則研究一下源碼,也沒那麼難(後續若是有空給你們寫一遍自定義通用的Repository能夠實現一些jpa默認實現裏面不帶有的根據用戶傳入的實體自動進行查詢,相似mybaitis中的動態sql)。mysql
廢話很少說,先看步驟:程序員
一、引入必要的包(maven必備,別告訴我你不會用)web
二、配置JPA啓動相關參數ajax
三、編寫實體(添加註解)spring
四、編寫service和controller(業務簡單能夠直接省略service)sql
<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.pxk</groupId> <artifactId>SpringBootDemo_JPA</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>SpringBootDemo_JPA Maven Webapp</name> <url>http://maven.apache.org</url> <build> <finalName>SpringBootDemo_JPA</finalName> </build> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.6.RELEASE</version> <relativePath /> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <!-- web容器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>1.5.6.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.3.10.RELEASE</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.40</version> </dependency> <!--日誌 --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <!-- druid鏈接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.18</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> </project>
你們可能會有疑問了,爲何啓動類裏面看不到任何JPA的影子呢,由於只要咱們引入spring-boot-starter-data-jpa,Spring Boot就會啓動JPA的默認配置。數據庫
詳見org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfigurationapache
package com.pxk.springboot; import javax.sql.DataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import com.alibaba.druid.pool.DruidDataSource; @SpringBootApplication public class Application { private final static Logger log=LoggerFactory.getLogger(Application.class); @Bean @ConfigurationProperties(prefix = "spring.datasource") //覆蓋默認數據源 使用druid數據源 public DataSource dataSource() { return new DruidDataSource(); } public static void main(String[] args) { SpringApplication.run(Application.class, args); log.info("啓動成功"); } }
單寫上面一個啓動類仍是不夠的,還須要加入一些須要的配置參數到application.properties中
# 數據庫訪問配置 # 主數據源,默認的 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/springboot_demo_jpa?useUnicode=true&characterEncoding=UTF-8 spring.datasource.username=root spring.datasource.password=pxk server.port=8081 spring.http.encoding.force=true spring.http.encoding.charset=UTF-8 spring.http.encoding.enabled=true server.tomcat.uri-encoding=UTF-8 spring.jpa.show-sql= true ## 建表方式 spring.jpa.properties.hibernate.hbm2ddl.auto=update # 方言 spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
這裏須要注意下,JPA實體註解,在Hibernate升級到4.0之後有一些變化,使用了javax的默認註解替代了Hiernate本來的註解,這裏對使用老版本的朋友來講不注意就是一個小坑。至於註解的使用這裏主要是主鍵的生成策略,屬性若是不加註解name對應數據庫的name字段,userName對應數據庫的user_name。另外還有一些長度限制非空限定等均可以使用註解實現。(最好的一點能夠直接結合Hibernate validator進行後臺數據驗證,數據完整性的保證--前臺驗證是不保險的【搞過爬蟲的同窗確定知道,前端很脆弱的】)
package com.pxk.springboot.domain; import java.io.Serializable; import java.util.Date; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import com.fasterxml.jackson.annotation.JsonFormat; @Entity public class User implements Serializable{ /** * */ private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name; private Integer age; private String passWord; private String gender; // json日期格式化 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date regestDate; // 默認構造函數不能少 ,若是沒有會報ibatis.executor.ExecutorException: No constructor found public User() { super(); } public User(String name) { this.name = name; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getPassWord() { return passWord; } public void setPassWord(String passWord) { this.passWord = passWord; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public Date getRegestDate() { return regestDate; } public void setRegestDate(Date regestDate) { this.regestDate = regestDate; } }
UserServiceImpl.java
package com.pxk.springboot.serivce.imp; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import com.pxk.springboot.dao.UserDao; import com.pxk.springboot.domain.User; import com.pxk.springboot.serivce.UserService; @Service//注入成service public class UserServiceImpl implements UserService { @Autowired private UserDao userDao; @Override public User getUser(String name) { return new User(name); } @Override public Page<User> findUserByPage(Pageable pageInfo) { Page<User> list=userDao.findAll(new PageRequest(pageInfo.getPageNumber(), pageInfo.getPageSize())); return list; } @Override public User getUserById(Long id) { return userDao.findOne(id); } @Override public User updateUser(User user) { return userDao.saveAndFlush(user); } @Override public void deleteUser(User user) { userDao.delete(user); } @Override public User addUser(User user) { return userDao.saveAndFlush(user); } }
UserController.java
若是看了我前一篇springboot 入門教程(5) 基於ssm框架的crud操做(後臺部分-附源碼)的同窗確定會發現這個後臺沒法和上一篇的前端整合在一塊兒使用,爲何呢?就是由於咱們前端用了Bootstap table,它自動發送的ajax請求參數和咱們後臺接受的參數名不統一,若是要實現整合提供兩種思路
一、修改前端BootStrap table源碼,優勢是懂前端的修改起來簡單,很快就改完了。缺點是修改源碼意味着當BootStrap table升級後你不能很順利的升級。
二、那確定是修改後臺咯,修改後臺又有兩種方式,一種是想前一篇同樣,引入兩個輔助分頁的類,編寫一個父類,進行統一的參數接收和結果集的轉換。第二種就是硬編碼,在controller的每一個分頁方法裏面去手動實現一遍參數和結果集的轉換。(固然第一種更適合了,後續有時間給你們補充上這一部分)
package com.pxk.springboot.conntroller; import java.util.Date; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import com.pxk.springboot.domain.User; import com.pxk.springboot.serivce.UserService; @RestController @RequestMapping("/user") public class UserController { @Autowired // 依賴注入service UserService userService; @RequestMapping("/findUserByPage") @ResponseBody public Page<User> getStudents(Pageable pageInfo) { return userService.findUserByPage(pageInfo); } @RequestMapping("/getUserById") protected User getUserById(Long id) { return userService.getUserById(id); } @RequestMapping("/deleteUser") protected void deleteUser(Long id) { User user = new User(); user.setId(id); userService.deleteUser(user); } @RequestMapping(value="/addUser") protected User addUser(User user) { if(user.getId()!=null&&user.getId()!=0){ return userService.updateUser(user); }else{ user.setRegestDate(new Date()); return userService.addUser(user); } } }
代碼都很簡單沒什麼可介紹的了。
簡單總結下:
其實小項目,用戶併發量小的項目用JPA確定比mybaitis快,並且逆向工程對開發這種小項目能夠說是事半功倍。其實JPA還有不少高級特性,如:事務、自定義Repository,複雜的關聯查詢等等。後面有機會再介紹。
下集預告:Spring Boot 集成Jpa 和Shiro ,token方式實現 web和app鑑權