springcloud初学者--Spring Data Jpa

最近mybatis用的多了,都对hibernate这些东西有点生疏了,正好趁着这篇博客补习一下jpa,正好也看看springboot的jpa和hibernate继承的jpa有什么区别。
随着这几年mybaits的流行,人们好像忘了,就在前几年,hibernate还是数据访问的绝对霸主,使用O/R映射技术实现数据库访问。
使用Spring Data Jpa访问数据库十分简单,只是需要简单的继承JpaRespository就可以。

public interface PersonRespository extend JpaRespository<Person,Long>

就可以执行如下操作

public interface JpaRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
    //查询全部
    List<T> findAll();
    //排序查询
    List<T> findAll(Sort var1);
    //根据id集合查询
    List<T> findAll(Iterable<ID> var1);
    //保存集合
    <S extends T> List<S> save(Iterable<S> var1);
    //....
    void flush();

    <S extends T> S saveAndFlush(S var1);

    void deleteInBatch(Iterable<T> var1);

    void deleteAllInBatch();

    T getOne(ID var1);

    <S extends T> List<S> findAll(Example<S> var1);

    <S extends T> List<S> findAll(Example<S> var1, Sort var2);
}

都是一些基本的操作,当然这些都是JapRespository的源码的东西,我们就不再一一描述了。
我们创建一个实体来映射数据库的表字段。

添加jar包

<?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>org.springframework</groupId>
    <artifactId>gs-accessing-data-jpa</artifactId>
    <version>0.1.0</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.5.RELEASE</version>
    </parent>

    <properties>
        <java.version>1.8</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-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.14</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-releases</id>
            <name>Spring Releases</name>
            <url>https://repo.spring.io/libs-release</url>
        </repository>
        <repository>
            <id>org.jboss.repository.releases</id>
            <name>JBoss Maven Release Repository</name>
            <url>https://repository.jboss.org/nexus/content/repositories/releases</url>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>spring-releases</id>
            <name>Spring Releases</name>
            <url>https://repo.spring.io/libs-release</url>
        </pluginRepository>
    </pluginRepositories>
</project>

Person类

package com.mhb.domain;

import lombok.Data;
import org.hibernate.annotations.NamedQuery;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

/**
 * Created by menghaibin on 2017/7/31.
 */
@Data
@Entity
@NamedQuery(name = "Person.withNameAndAddressNamedQuery",
        query="select p from Person p where p.name = ?1 and p.address = ?2")
public class Person {

    @Id
    @GeneratedValue
    private Long id;

    private String name;

    private Integer age;

    private String address;

    public Person(){
        super();
    }

    public Person(Long id,String name, Integer age, String address ){
        super();
        this.id = id;
        this.name = name;
        this.age = age;
        this.address = address;
    }
}

@Data只是为了方便不写get,set方法,需要的可以添加相应的jar,@Entity指明了这是和数据表映射的实体类。当然我们也可以制定表名字@Entity(name=”person”),NamedQuery我们之后会介绍,@Id标明他是个主键, @GeneratedValue设置主键自增。
大家可能发现这个实体类和以前的实体类配置的不太一样,在hibernate我们大概需要这么配置

  //主键,此注解必须要有
    @Id  
    //数据库表中主键列名为id,如果实体类属性名和列名相同,此注解可以省略
    @Column(name="id")  
    //主键的维护策略
    @GenericGenerator(name="inc50",strategy="increment")   
    @GeneratedValue(generator="inc50")
    private Integer userID;

但是我们在上边的例子里边也没有发现@Column和@Table这些东西。不注解的时候hibernate回自动根据属性名映射表的字段名字,例如name会映射到NAME,textName会映射到TEXT_NAME,

定义查询方法

创建表和插入数据

我们创建一张简单的表叫做person:

-- auto-generated definition
create table person
(
    id int auto_increment
        primary key,
    name varchar(50) null,
    age int null,
    address varchar(50) null
);

INSERT INTO person (id, name, age, address) VALUES (1,'mhb','23','zjk');
INSERT INTO person (id, name, age, address) VALUES (2,'bb','23','bj');
INSERT INTO person (id, name, age, address) VALUES (3,'wgl','22','bj');
INSERT INTO person (id, name, age, address) VALUES (4,'lxy','23','bj');
INSERT INTO person (id, name, age, address) VALUES (5,'bb','60','zjk');
INSERT INTO person (id, name, age, address) VALUES (6,'mm','23','zjk');

创建数据库连接

spring.datasource.url=jdbc:mysql://localhost:3306/user_center
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

定义查询方法


/**
 * Created by menghaibin on 2017/7/31.
 */
public interface PersonRepository extends JpaRepository<Person, Long> {

    List<Person> findByAddress(String name);

    Person findByNameAndAddress(String name, String address);

    @Query("select p from Person p where p.name = :name and p.address = :address")
    Person withNameAndAddressQuery(@Param("name") String name, @Param("address")String address);

    Person withNameAndAddressNamedQuery(String name, String address);
}

springboot的jap主要是根据属性名来定义方法,例如findByName,findNameAndAddress,findNameOrAddress,大概就几个关键字,但是我们也可以重新定义一些方法,例如我们根据名字查询的时候,还需要定义年龄是大于23岁的,那么我们就需要用NamedQuery来重新定义这个方法。

 //Spring Data JPA 支持@NameQuery来定义查询方法,即一个名称映射一个查询语句(要在实体类上写,不是接口里写),示例如下:

@Entity
@NamedQuery(name="Person.findByName",
query="select p from Person p where p.name=?1 and p.age > 23")
public class Person{

}

当然我们也可以定义多个,

//如果要将多个方法都进行重新定义,可以使用@NameQueries标签,示例如下:
@Entity
@NamedQueries({
@NamedQuery(name="Person.findByName",
query="select p from Person p where p.name=?1"),
@NamedQuery(name = "Person.withNameAndAddressNamedQuery",
query = "select p from Person p where p.name=?1 and address=?2")
})
public class Person{

}

查询方法补充

关键字 示例 同功能的查询
And findByTitleAndContent where x.title = ?1 and x.content = ?2
Or findByTitleOrContent where x.title = ?1 or x.content = ?2
Is, Equals findByTitle,findByTitleIs,FindByTItleEquals where x.title = ?1
Between findByCreateTimeBetween where x.createTime between 1? and ?2
LessThanEqual findByAgeLessThanEqual where x.age <= ?1
LessThan findByAgeLessThan where x.age < ?1
GreaterThan findByAgeGreaterThan where x.age > ?1
GreaterThanEqual findByAgeGreaterThanEqual where x.age >= ?1
After findByCreateTimeAfter where x.create > ?1
Before findByCreateTimeBefore where x.createTime < ?1
IsNull findByAgeIsNull where x.age is null
IsNotNull NotNull findByAgeIsNotNull, findByAgeNotNull where x.age is not null
Like findByTitleLike where x.title like ?1
NotLike findByTitleNotLike where x.title not like ?1
StartingWith findByTitleStartingWith where x.title like ?1(title前加%)
EndingWith findByTitleEndingWith where x.title like ?1(title后加%)
Containing findByTitleContaining where x.title like ?1(前后都加)
OrderBy findByTitleOrderByIdDesc where x.title order by id desc
Not findByTitleNot where title <> ?1
In findByAgeIn(Collection ages) where x.age in ?1
NotIn findByAgeNotIn(Collection ages) where x.age not in ?1
True findByActiveTrue where x.active = true
False findByActiveFalse where x.active = false
ignoreCase findByTitleIgnoreCase where UPPER(x.title) = UPPER(?1)

创建controller

// Copyright (C), rzsj All Rights Reserved.
package com.mhb.domain;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * Created by menghaibin on 2017/7/31.
 */
@RestController
public class DateController {

    @Autowired
    PersonRepository personRepository;

    @RequestMapping("/save")
    public Person save(String name,String address, Integer age){
        Person p = personRepository.save(new Person(null, name,age,address));
        return p;
    }

    @RequestMapping("/q1")
    public List<Person> q1(String address){
        List<Person> p = personRepository.findByAddress(address);
        return p;

    }

    @RequestMapping("/q2")
    public Person q2(String name, String address){
        Person p = personRepository.findByNameAndAddress(name, address);
        return p;

    }

    @RequestMapping("/q3")
    public Person q3(String name, String address){
        Person p = personRepository.withNameAndAddressQuery(name, address);
        return p;

    }

    @RequestMapping("/q4")
    public Person q4(String name, String address){
        Person p = personRepository.withNameAndAddressNamedQuery(name, address);
        return p;

    }


    @RequestMapping("/sort")
    public List<Person> sort(){
        List<Person> p = personRepository.findAll(new Sort(Sort.Direction.ASC,"age"));
        return p;
    }

    @RequestMapping("/page")
    public Page<Person> page(){
        Page<Person> page = personRepository.findAll(new PageRequest(1,2));
        return page;
    }
}

启动项目

我们还是用springboot自带的tomcat启动,创建Application类启动

// Copyright (C), rzsj All Rights Reserved.
package com.mhb.domain;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * Created by menghaibin on 2017/7/31.
 */
@SpringBootApplication
public class Application {
    public static void main(String[] args) {


        SpringApplication.run(Application.class, args);
    }
}

结果

分页查询

http://localhost:8080/page

{
    "content": [
        {
            "id": 3,
            "name": "wgl",
            "age": 22,
            "address": "bj"
        },
        {
            "id": 4,
            "name": "lxy",
            "age": 23,
            "address": "bj"
        }
    ],
    "totalElements": 6,
    "totalPages": 3,
    "last": false,
    "size": 2,
    "number": 1,
    "first": false,
    "numberOfElements": 2,
    "sort": null
}

添加实体

http://localhost:8080/save?name=susan&age=32&address=NewYork

扫描二维码关注公众号,回复: 8641542 查看本文章
{
    "id": 8,
    "name": "susan",
    "age": 32,
    "address": "NewYork"
}

查询方法q2

http://localhost:8080/q2?address=bj&name=wgl

{
    "id": 3,
    "name": "wgl",
    "age": 22,
    "address": "bj"
}

小结

这些都是一些jpa的基本功能,至于其他的功能,我们在下一篇博客继续讨论,例如一对一,一对多这些关系映射,还有模糊查询这些应该是我们更加常用到的技术。
要想使用springboot的jpa基本和hibernate差不多,但是要注意添加相应的pom文件,定义方法的时候一定要记住关键字和属性名称一定要对。顺便附上一些常用的方法使用

 //And --- 等价于 SQL 中的 and 关键字,比如 findByHeightAndSex(int height,char sex);  
 public List<User> findByHeightAndSex(int height,char sex);  

// Or --- 等价于 SQL 中的 or 关键字,比如 findByHeightOrSex(int height,char sex);  
 public List<User> findByHeightOrSex(int height,char sex);  

 //Between --- 等价于 SQL 中的 between 关键字,比如 findByHeightBetween(int min, int max);  
 public List<User> findByHeightBetween(int min,int max);  

 //LessThan --- 等价于 SQL 中的 "<",比如 findByHeightLessThan(int max);  
 public List<User> findByHeightLessThan(int max);  

 //GreaterThan --- 等价于 SQL 中的">",比如 findByHeightGreaterThan(int min);  
 public List<User> findByHeightGreaterThan(int min);  

 //IsNull --- 等价于 SQL 中的 "is null",比如 findByNameIsNull();  
 public List<User> findByNameIsNull();  

 //IsNotNull --- 等价于 SQL 中的 "is not null",比如 findByNameIsNotNull();  
 public List<User> findByNameIsNotNull();  

 //NotNull --- 与 IsNotNull 等价;  
 public List<User> findByNameNotNull();  

 //Like --- 等价于 SQL 中的 "like",比如 findByNameLike(String name);  
 public List<User> findByNameLike(String name);  

 //NotLike --- 等价于 SQL 中的 "not like",比如 findByNameNotLike(String name);  
 public List<User> findByNameNotLike(String name);  

 //OrderBy --- 等价于 SQL 中的 "order by",比如 findByNameNotNullOrderByHeightAsc();  
 public List<User>findByNameNotNullOrderByHeightAsc();  

 //Not --- 等价于 SQL 中的 "! =",比如 findByNameNot(String name);  
 public List<User> findByNameNot(String name);  

 //In --- 等价于 SQL 中的 "in",比如 findByNameIN(String name);  
 public List<User> findByNameIn(String name);  

 //NotIn --- 等价于 SQL 中的 "not in",比如 findByNameNotIN(String name);  
 public List<User> findByNameNotIn(String name); 

如果项目不是很复杂,不需要很复杂的sql来计算的话,完全可以用springboot jpa来解决战斗。

发布了176 篇原创文章 · 获赞 84 · 访问量 44万+

猜你喜欢

转载自blog.csdn.net/lovemenghaibin/article/details/76484639