当前位置:Gxlcms > 数据库问题 > Spring Data JPA例子[基于Spring Boot、Mysql]

Spring Data JPA例子[基于Spring Boot、Mysql]

时间:2021-07-01 10:21:17 帮助过:11人阅读

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接口主要定义了一些查询方法;

比如这里的findByNameAndAddressfindByName方法,我们是不需要额外定义其它查询语句就可以直接执行的,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]

标签:lan   https   输入   snap   st3   nat   社区   1.0   string   

人气教程排行