Spring-Data-Jpa入門教程(一)

一、啥是JPA?

JPA,全英文名叫Java Persistence API,就是java持久化api,是SUN公司推出的一套基于ORM的規(guī)范。

持久化想必如雷貫耳,都0202年了,誰(shuí)還不用個(gè)持久化框架啊,舉起mybatis。

ORM呢?全英文名為Object-Relational Mapping:對(duì)象關(guān)系映射,簡(jiǎn)單來(lái)說(shuō)為了不用JDBC那一套原始方法來(lái)操作數(shù)據(jù)庫(kù),ORM框架橫空出世(mybatis、hibernate等等)。

然而ORM框架出的太多了,百花齊放,琳瑯滿目,你一套標(biāo)準(zhǔn)我一套標(biāo)準(zhǔn),要是想換一套框架實(shí)現(xiàn)項(xiàng)目,可能要從頭再寫。啊這?入土吧。

百度這樣介紹SUN的JPA規(guī)范:

Sun引入新的JPA ORM規(guī)范出于兩個(gè)原因:

其一,簡(jiǎn)化現(xiàn)有Java EE和Java SE應(yīng)用開(kāi)發(fā)工作;

其二,Sun希望整合ORM技術(shù),實(shí)現(xiàn)天下歸一。

有氣魄,我喜歡,學(xué)他丫的。

二、Spring-Data-Jpa簡(jiǎn)介

學(xué)jpa哪家強(qiáng)?哪家簡(jiǎn)單學(xué)哪家,spring-data-jpa最簡(jiǎn)單。介紹如下:

Spring Data JPA是Spring Data家族的一部分,可以輕松實(shí)現(xiàn)基于JPA的存儲(chǔ)庫(kù)。 此模塊處理對(duì)基于JPA的數(shù)據(jù)訪問(wèn)層的增強(qiáng)支持。 它使構(gòu)建使用數(shù)據(jù)訪問(wèn)技術(shù)的Spring驅(qū)動(dòng)應(yīng)用程序變得更加容易。

總的來(lái)說(shuō)JPA是ORM規(guī)范,Hibernate、TopLink等是JPA規(guī)范的具體實(shí)現(xiàn),這樣的好處是開(kāi)發(fā)者可以面向JPA規(guī)范進(jìn)行持久層的開(kāi)發(fā),而底層的實(shí)現(xiàn)則是可以切換的(敲黑板哦)。Spring Data Jpa則是在JPA之上添加另一層抽象(Repository層的實(shí)現(xiàn)),極大地簡(jiǎn)化持久層開(kāi)發(fā)及ORM框架切換的成本。

也就是如下圖所示:


JPA原理圖

三、環(huán)境配置

話不多說(shuō),使用Maven管理包,使用springboot框架,建個(gè)空maven項(xiàng)目就行

1、配置pom.xml

```

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.4.RELEASE</version><relativePath/><!--lookup parentfromrepository--></parent><groupId>com.jacky</groupId><artifactId>user-service</artifactId><version>0.0.1-SNAPSHOT</version><name>user-service</name><description>Demo projectforSpring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.6.3</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.20</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency></dependencies>

```

2、配置application.yml

server:port:8801spring:application:name:user-service? datasource:type:com.alibaba.druid.pool.DruidDataSource? ? driverClassName:com.mysql.jdbc.Driver? ? url:jdbc:mysql://10.16.58.21:3306/appt_test? ? username:root? ? password:123456# druid配置項(xiàng),默認(rèn)spring-boot不支持,故需要config類來(lái)解析? ? initialSize:5minIdle:5maxActive:20maxWait:60000timeBetweenEvictionRunsMillis:60000minEvictableIdleTimeMillis:300000validationQuery:SELECT1FROM DUAL? ? testWhileIdle:truetestOnBorrow:falsetestOnReturn:falsepoolPreparedStatements:truemaxPoolPreparedStatementPerConnectionSize:20filters:stat,wall,log4j? ? connectionProperties:druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000jpa:hibernate:ddl-auto:update? ? show-sql:true

3、配置Springboot啟動(dòng)類

@SpringBootApplication@EnableJpaAuditingpublicclassUserServiceApplication{publicstaticvoidmain(String[]args){SpringApplication.run(UserServiceApplication.class,args);}@PostConstructvoidsetDefaultTimeZone(){TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));}}

注意:

除了@SpringBootApplication啟動(dòng)注解外,

還有一個(gè)注解@EnableJpaAuditing,它是用來(lái)啟動(dòng)Jpa的審計(jì)功能,比如說(shuō)在使用建表中經(jīng)常會(huì)加入 版本號(hào)、創(chuàng)建時(shí)間、修改時(shí)間 、創(chuàng)建者、修改者 這五個(gè)字段。因此為了簡(jiǎn)化開(kāi)發(fā), 我們可以將其交給jpa來(lái)自動(dòng)填充。

4、創(chuàng)建阿里Druid配置類

importcom.alibaba.druid.pool.DruidDataSource;importcom.alibaba.druid.support.http.StatViewServlet;importcom.alibaba.druid.support.http.WebStatFilter;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.boot.web.servlet.FilterRegistrationBean;importorg.springframework.boot.web.servlet.ServletRegistrationBean;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.context.annotation.Primary;importjavax.sql.DataSource;importjava.sql.SQLException;/**

* 阿里Druid配置類

*

* @author zcc ON 2018/2/11

**/@ConfigurationpublicclassDruidConfig{privatestaticfinal Logger log=LoggerFactory.getLogger(DruidConfig.class);@Value("${spring.datasource.url}")privateString dbUrl;@Value("${spring.datasource.username}")privateString username;@Value("${spring.datasource.password}")privateString password;@Value("${spring.datasource.driverClassName}")privateString driverClassName;@Value("${spring.datasource.initialSize}")privateint initialSize;@Value("${spring.datasource.minIdle}")privateint minIdle;@Value("${spring.datasource.maxActive}")privateint maxActive;@Value("${spring.datasource.maxWait}")privateint maxWait;@Value("${spring.datasource.timeBetweenEvictionRunsMillis}")privateint timeBetweenEvictionRunsMillis;@Value("${spring.datasource.minEvictableIdleTimeMillis}")privateint minEvictableIdleTimeMillis;@Value("${spring.datasource.validationQuery}")privateString validationQuery;@Value("${spring.datasource.testWhileIdle}")privateboolean testWhileIdle;@Value("${spring.datasource.testOnBorrow}")privateboolean testOnBorrow;@Value("${spring.datasource.testOnReturn}")privateboolean testOnReturn;@Value("${spring.datasource.poolPreparedStatements}")privateboolean poolPreparedStatements;@Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")privateint maxPoolPreparedStatementPerConnectionSize;@Value("${spring.datasource.filters}")privateString filters;@Value("{spring.datasource.connectionProperties}")privateString connectionProperties;@Bean? ? @PrimarypublicDataSourcedataSource(){DruidDataSource datasource=newDruidDataSource();log.info("----------- druid datasource ----------");datasource.setUrl(this.dbUrl);datasource.setUsername(username);datasource.setPassword(password);datasource.setDriverClassName(driverClassName);datasource.setInitialSize(initialSize);datasource.setMinIdle(minIdle);datasource.setMaxActive(maxActive);datasource.setMaxWait(maxWait);datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);datasource.setValidationQuery(validationQuery);datasource.setTestWhileIdle(testWhileIdle);datasource.setTestOnBorrow(testOnBorrow);datasource.setTestOnReturn(testOnReturn);datasource.setPoolPreparedStatements(poolPreparedStatements);datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);try{datasource.setFilters(filters);}catch(SQLExceptione){e.printStackTrace();}datasource.setConnectionProperties(connectionProperties);returndatasource;}@BeanpublicServletRegistrationBeanregistrationBean(){ServletRegistrationBean servletRegistrationBean=newServletRegistrationBean(newStatViewServlet());// 添加初始化參數(shù):initParamsservletRegistrationBean.addUrlMappings("/druid/*");// 白名單servletRegistrationBean.addInitParameter("allow","127.0.0.1");//黑名單? ? ? ? servletRegistrationBean.addInitParameter("deny","192.168.0.101");//登錄查看信息的賬號(hào)密碼.servletRegistrationBean.addInitParameter("loginUsername","admin");servletRegistrationBean.addInitParameter("loginPassword","123456");//可重置數(shù)據(jù).servletRegistrationBean.addInitParameter("resetEnable","false");returnservletRegistrationBean;}@BeanpublicFilterRegistrationBeanfilterRegistrationBean(){FilterRegistrationBean filterRegistrationBean=newFilterRegistrationBean(newWebStatFilter());//添加過(guò)濾規(guī)則.filterRegistrationBean.addUrlPatterns("/*");// 添加不需要忽略的格式信息.filterRegistrationBean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");returnfilterRegistrationBean;}}

5、創(chuàng)建repository數(shù)據(jù)訪問(wèn)層接口,

通過(guò)repository接口可以很方便的調(diào)用JPA,完成數(shù)據(jù)庫(kù)的所有操作,當(dāng)然包括數(shù)據(jù)庫(kù)CRUD

importcom.jacky.userservice.pojo.entity.dvUser;importorg.springframework.data.jpa.repository.JpaRepository;publicinterfacedvUserRepositoryextendsJpaRepository<dvUser,Long>{}

可以看到,這個(gè)接口繼承了JpaRepository<實(shí)體,ID>,spring-data-jpa只需要這個(gè)信息,就可以幫你完成常用的操作:增刪查改。

6、創(chuàng)建entity實(shí)體類

@Data@Entity@Table(name="dv_user")@EntityListeners(AuditingEntityListener.class)publicclassdvUser{@Id? ? @Column(name="id")@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="JPA_USER_S2")@SequenceGenerator(sequenceName="JPA_USER_S1",name="JPA_USER_S2",allocationSize=1)privateLong id;@Column(name="name")privateString name;@Column(name="object_version")@VersionprivateLong objectVersion;@Column(name="created_by")@CreatedByprivateString createdBy;@Column(name="created_date")@CreatedDate? ? @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")privateDate createdDate;@Column(name="last_updated_by")@LastModifiedByprivateString lastUpdatedBy;@Column(name="last_updated_date")@LastModifiedDate? ? @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")privateDate lastUpdatedDate;}

7、創(chuàng)建service接口

importcom.jacky.userservice.pojo.entity.dvUser;importjava.util.List;publicinterfacedvUserService{/**

? ? * 新增用戶

? ? * @param user 用戶對(duì)象

? ? */dvUserinsertUser(dvUser user);/**

? ? * 刪除用戶

? ? * @param id 刪除id

? ? */voiddeleteUser(Long id);/**

? ? * 修改用戶

? ? * @param user 用戶信息

? ? */dvUserupdateUser(dvUser user);/**

? ? * 查詢所有用戶

? ? */List<dvUser>findAllUser();/**

? ? * 通過(guò)id查詢用戶

? ? * @param id 用戶id

? ? */dvUserfindUserById(Long id);}

8、創(chuàng)建service接口實(shí)現(xiàn)類

importcom.jacky.userservice.pojo.entity.dvUser;importcom.jacky.userservice.repository.dvUserRepository;importcom.jacky.userservice.service.dvUserService;importorg.springframework.stereotype.Service;importjavax.annotation.Resource;importjava.util.List;@ServicepublicclassdvUserServiceImplimplementsdvUserService{@ResourceprivatedvUserRepository dvUserRepository;@OverridepublicdvUserinsertUser(dvUser user){returndvUserRepository.save(user);}@OverridepublicvoiddeleteUser(Long id){dvUserRepository.deleteById(id);}@OverridepublicdvUserupdateUser(dvUser user){returndvUserRepository.save(user);}@OverridepublicList<dvUser>findAllUser(){returndvUserRepository.findAll();}@OverridepublicdvUserfindUserById(Long id){returndvUserRepository.findById(id).orElse(null);}}

9、創(chuàng)建controller訪問(wèn)層

importcom.jacky.userservice.pojo.entity.dvUser;importcom.jacky.userservice.service.dvUserService;importorg.springframework.web.bind.annotation.*;importjavax.annotation.Resource;importjava.util.List;@RestController@RequestMapping("/user")publicclassJpaUserController{@ResourceprivatedvUserService dvUserService;/**

? ? * 新增用戶

? ? */@PostMapping("")publicdvUseraddUser(@RequestBody dvUser user){returndvUserService.insertUser(user);}/**

? ? * 刪除用戶

? ? */@DeleteMapping("/{id}")publicvoiddeleteUser(@PathVariable("id")Long id){dvUserService.deleteUser(id);}/**

? ? * 修改用戶

? ? */@PutMapping("")publicdvUserupdateUser(@RequestBody dvUser user){returndvUserService.updateUser(user);}/**

? ? * 全查用戶

? ? */@GetMapping("")publicList<dvUser>findAll(){returndvUserService.findAllUser();}/**

? ? * id查用戶

? ? */@GetMapping("/{id}")publicdvUserfindbyId(@PathVariable("id")Long id){returndvUserService.findUserById(id);}}

四、是實(shí)時(shí)展示真正的技術(shù)了

1、費(fèi)了老大的勁才把代碼敲完,現(xiàn)在是開(kāi)始見(jiàn)證成果的時(shí)候了,讓我們使用Post模擬請(qǐng)求

先添加一個(gè)用戶

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容