springboot 入門教程(6)--- 整合Spring data JPA實現CRUD(附源碼)

Spring data JPA實現CRUD源碼連接    前端

先說下什麼是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

一、引入必要的包(maven必備,別告訴我你不會用)

<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啓動相關參數

    你們可能會有疑問了,爲何啓動類裏面看不到任何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&amp;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;
	}
}

四、編寫service和controller(業務簡單能夠直接省略service)

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鑑權

相關文章
相關標籤/搜索