Spring Data JPA例子[基于Spring Boot、Mysql]
关于Spring Data
Spring社区的一个顶级工程,主要用于简化数据(关系型&非关系型)访问,如果我们使用Spring Data来开发程序的话,那么可以省去很多低级别的数据访问操作,如编写数据查询语句、DAO类等,我们仅需要编写一些抽象接口并定义相关操作即可,Spring会在运行期间的时候创建代理实例来实现我们接口中定义的操作。
关于Spring Data子项目
Spring Data拥有很多子项目,除了Spring Data Jpa外,还有如下子项目。
Spring Data Commons
Spring Data MongoDB
Spring Data Redis
Spring Data Solr
Spring Data Gemfire
Spring Data REST
Spring Data Neo4j
关于Spring Data Jpa
Spring Data Jpa是Spring Data的一个子项目,主要用于简化数据访问层的实现,使用Spring Data Jpa可以轻松实现增删改查、分页、排序等。
例子,Spring Boot + Spring Data Jpa
1、添加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>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <name>spring-data-jpa-example</name>
<description>Demo project for Spring Boot</description> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.4.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.7</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>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency> <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
</dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> </project>
其中,spring-boot-starter-parent会加载Spring Boot应用所需的所有默认配置;
spring-boot-starter-data-jpa会下载所有Spring Data Jpa所需的依赖;
添加spring-boot-starter-web是因为我们的工程是一个Web应用;
另外我们的数据库是mysql,所以还需要mysql-connector-java依赖;
由于使用了缓存,所以再添加一个spring-boot-starter-cache依赖;
2、编写实体类User
package com.example.domain; import java.io.Serializable; import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQuery; @Entity
@NamedQuery(name = "User.findByName", query = "select name,address from User u where u.name=?1")
public class User implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
long id;
@Column(name = "name")
String name;
@Column(name = "address")
String address; 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 String getAddress()
{
return address;
} public void setAddress(String address)
{
this.address = address;
} }
其它没啥好说的,注意下这里的@NamedQuery注解,大致意思就是让我们在Repository接口中定义的findByName方法不使用默认的查询实现,取而代之的是使用这条自定义的查询语句去查询,如果这里没有标注的话,会使用默认实现的。
3、编写Repository接口
这里将编写两个Repository接口,仅仅用于示例,实际中可以合并成一个:
UserJpaRepository
package com.example.repository; import org.springframework.data.jpa.repository.JpaRepository; import com.example.domain.User; public interface UserJpaRepository extends JpaRepository<User,Long> { }
这里的UserJpaRepository接口实现了JpaRepository接口;
实际上JpaRepository实现了PagingAndSortingRepository接口,PagingAndSortingRepository接口实现了CrudRepository接口,CrudRepository接口实现了Repository接口;
简单说明下:
Repository接口是一个标识接口,里面是空的;
CrudRepository接口定义了增删改查方法;
PagingAndSortingRepository接口用于分页和排序;
由于JpaRepository接口继承了以上所有接口,所以拥有它们声明的所有方法;
另外注意下,以findAll方法为例,JpaRepository接口返回的是List, PagingAndSortingRepository和CrudRepository返回的是迭代器;
UserRepository
package com.example.repository; import java.util.List; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.query.Param; import com.example.domain.User; public interface UserRepository extends Repository<User, Long>
{ List<User> findByNameAndAddress(String name, String address); @Query(value = "from User u where u.name=:name")
List<User> findByName1(@Param("name") String name); @Query(value = "select * from #{#entityName} u where u.name=?1", nativeQuery = true)
List<User> findByName2(String name); List<User> findByName(String name);
}
这里的UserRepository接口主要定义了一些查询方法;
比如这里的findByNameAndAddress和findByName方法,我们是不需要额外定义其它查询语句就可以直接执行的,Spring Data Jpa会根据实体类的属性名字以及方法名自动实现该方法;PS:由于我们在实体类中声明了@NamedQuery注解,实际上findByName方法会使用@NamedQuery注解标注的查询语句去查询;
另外这里的findByName1方法使用了HQL语句查询;
findByName2方法使用了原始的sql语句查询;
4、编写Service
service接口:
package com.example.service; import java.util.List; import com.example.domain.User; public interface IUserService
{
public List<User> findAll(); public void saveUser(User book); public User findOne(long id); public void delete(long id); public List<User> findByName(String name); }
接口实现类:
package com.example.service.impl; import java.util.List; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import com.example.domain.User;
import com.example.repository.UserRepository;
import com.example.repository.UserJpaRepository;
import com.example.service.IUserService; @Service
@Transactional
public class UserServiceImpl implements IUserService
{
@Autowired
private UserJpaRepository userJpaRepository;
@Autowired
private UserRepository userRepository; public List<User> findAll()
{
return userJpaRepository.findAll();
} public List<User> findByName(String name)
{
List<User> userList1 = userRepository.findByName1(name);
List<User> userList2 = userRepository.findByName2(name);
List<User> userList3 = userRepository.findByNameAndAddress(name, "3");
System.out.println("userList1:" + userList1);
System.out.println("userList2:" + userList2);
System.out.println("userList3:" + userList3);
return userRepository.findByName(name);
} public void saveUser(User book)
{
userJpaRepository.save(book);
} @Cacheable("users")
public User findOne(long id)
{
System.out.println("Cached Pages");
return userJpaRepository.findOne(id);
} public void delete(long id)
{
userJpaRepository.delete(id);
}
}
这个没啥好说的,调用Repository接口接口的方法即可。
5、编写Controller
Controller也没啥好说的,调用Service即可,注意下这里的Controller使用@RestController注解来标注,另外URL路径命名按照RESTful风格来命名;
package com.example.web; import java.util.List; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import com.example.domain.User;
import com.example.service.IUserService; @RestController
@RequestMapping(value = "/users")
public class UserController
{
@Autowired
private IUserService userService; @RequestMapping(value = "/add/{id}/{name}/{address}")
public User addUser(@PathVariable int id, @PathVariable String name,
@PathVariable String address)
{
User user = new User();
user.setId(id);
user.setName(name);
user.setAddress(address);
userService.saveUser(user);
return user;
} @RequestMapping(value = "/delete/{id}")
public void deleteBook(@PathVariable int id)
{
userService.delete(id);
} @RequestMapping(value = "/")
public List<User> getBooks()
{
return userService.findAll();
} @RequestMapping(value = "/{id}")
public User getUser(@PathVariable int id)
{
User user = userService.findOne(id);
return user;
} @RequestMapping(value = "/search/name/{name}")
public List<User> getBookByName(@PathVariable String name)
{
List<User> users = userService.findByName(name);
return users;
} }
6、配置datasource
在application.properties文件中添加如下配置:
spring.jpa.show-sql = true
logging.level.org.springframework.data=DEBUG
spring.jpa.hibernate.ddl-auto= spring.datasource.url=jdbc:mysql://localhost:3306/demo
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
如果你使用STS IDE的话,这些属性配置都会自动提示的,省的去查找。
想查看spring.datasource的配置,可以参考这个类:DataSourceProperties.java
7、编写启动类
比较简单,注意下该类所属的包级别要大于或等于其它类,以保证其它类的注解可以被扫描到。
package com.example; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching; @SpringBootApplication
@EnableCaching
public class SpringDataJpaExampleApplication { public static void main(String[] args) {
SpringApplication.run(SpringDataJpaExampleApplication.class, args);
}
}
运行、测试程序
启动main方法,或打成jar包运行;
浏览器输入以下URL,测试即可:
http://localhost:8080/users/
http://localhost:8080/users/add/100/110/111
http://localhost:8080/users/delete/100
http://localhost:8080/users/2
http://localhost:8080/users/search/name/2
程序源码
https://github.com/peterchenhdu/spring-data-jpa-example
参考资料
http://docs.spring.io/spring-data/jpa/docs/1.11.0.RELEASE/reference/html/
http://javabeat.net/spring-data-jpa/
https://spring.io/guides/gs/caching/
Spring Data JPA例子[基于Spring Boot、Mysql]的更多相关文章
- Spring Data JPA系列4——Spring声明式数事务处理与多数据源支持
大家好,又见面了. 到这里呢,已经是本SpringData JPA系列文档的第四篇了,先来回顾下前面三篇: 在第1篇<Spring Data JPA系列1:JDBC.ORM.JPA.Spring ...
- Spring Data Jpa 实现分页(Spring MVC+easyui)
spring data jpa很好的对dao层进行了封装,这篇文章主要来写的是实现easyui datagird数据分页,由于各个UI参数不大一样,所以如果使用的是其他UI,得稍作修改.需要说明的是我 ...
- 【spring data jpa】使用spring data jpa 的删除操作,需要加注解@Modifying @Transactional 否则报错如下: No EntityManager with actual transaction available for current thread - cannot reliably process 'remove' call
使用spring data jpa 的删除操作,需要加注解@Modifying @Transactional 否则报错如下: No EntityManager with actual tran ...
- 【spring data jpa】使用spring data jpa时,关于service层一个方法中进行【删除】和【插入】两种操作在同一个事务内处理
场景: 现在有这么一个情况,就是在service中提供的一个方法是先将符合条件的数据全部删除,然后再将新的条件全部插入数据库中 这个场景需要保证service中执行两步 1.删除 2.插入 这两步自然 ...
- spring boot(五):spring data jpa的使用
在上篇文章springboot(二):web综合开发中简单介绍了一下spring data jpa的基础性使用,这篇文章将更加全面的介绍spring data jpa 常见用法以及注意事项 使用spr ...
- spring boot(五)Spring data jpa介绍
在上篇文章springboot(二):web综合开发中简单介绍了一下spring data jpa的基础性使用,这篇文章将更加全面的介绍spring data jpa 常见用法以及注意事项 使用spr ...
- Spring Boot2 系列教程 (七) | 使用 Spring Data JPA 访问 Mysql
前言 如题,今天介绍 Spring Data JPA 的使用. 什么是 Spring Data JPA 在介绍 Spring Data JPA 之前,首先介绍 Hibernate . Hibernat ...
- Spring Boot + Spring Data JPA + PostgreSQL
最近在用Java重写之前实习生用.netcore写的微信后台应用. 规定用Spring Boot框架,PostgreSQL数据库.之前一直习惯于基于XML的Spring app,也没用过Postgre ...
- SpringBoot入门:Spring Data JPA 和 JPA(理论)
参考链接: Spring Data JPA - Reference Documentation Spring Data JPA--参考文档 中文版 纯洁的微笑:http://www.ityouknow ...
随机推荐
- Linq的执行效率及优化
描述:项目中使用了linq,发现写的顺序不一样最后的结果也不一样,效率也不一样. Linq的执行效率对比 List<int> source = new List<int>(); ...
- 微信小程序之 -----事件
事件分类 1. 冒泡事件: 当一个组件上的事件被触发后,该事件会向父节点传递. 2. 非冒泡事件: 当一个组件上的事件被触发后,该事件不会向父节点传递. 常见的冒泡 ...
- 二 分析easyswoole源码(启动服务)
前文连接,阅读的时候最好参照EasySwoole2.1.2的源码 $inst->run();//启动服务 这里实际调用的是Core的start方法ServerManager::getInstan ...
- Piwis Tester II V18.100 with CF30 Laptop for Porsche
Porsche Piwis Tester II is the latest professional tester for Porshe,the most poweful diagnose and o ...
- 代码之髓读后感——名字&作用域&类型
名字和作用域 为什么要取名 看着代码中遍地都是的变量,函数,或多或少的我们都应该想过,为什么会有这些名字呢? 我们知道,计算机将数据存储到对应的物理内存中去.我们的操作就是基于数据的.我们需要使用这些 ...
- python页面解析_beautifulsoup试玩
最近玩爬虫,先把python解析器 beautifulsoup 练练 这个 tainiu.html 是从百度网盘里拷贝一段html from bs4 importBeautifulSoup wit ...
- 设计模式学习心得<单利模式 Singleton>
概述 意图 保证一个类仅有一个实例,并提供一个访问它的全局访问点. 主要解决 一个全局使用的类频繁地创建与销毁. 何时使用 当您想控制实例数目,节省系统资源的时候. 如何解决 判断系统是否已经有这个单 ...
- mysql找到数据的存储位置
本来是想找mysql数据库文件中的sql脚本文件的,结果发现运行了sql脚本文件后,你删除了,就没有sql语句了,那么我们分析一下在数据库路径下面找到的文件又是什么呢? 1.先找mysql中data的 ...
- zeromq学习记录(五)vc下多线程
/************************************************************** 技术博客 http://www.cnblogs.com/itdef/ ...
- A - ACboy needs your help again!
ACboy was kidnapped!! he miss his mother very much and is very scare now.You can't image how dark th ...