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{

}
查询方法补充
关键字示例同功能的查询
AndfindByTitleAndContentwhere x.title = ?1 and x.content = ?2
OrfindByTitleOrContentwhere x.title = ?1 or x.content = ?2
Is, EqualsfindByTitle,findByTitleIs,FindByTItleEqualswhere x.title = ?1
BetweenfindByCreateTimeBetweenwhere x.createTime between 1? and ?2
LessThanEqualfindByAgeLessThanEqualwhere x.age <= ?1
LessThanfindByAgeLessThanwhere x.age < ?1
GreaterThanfindByAgeGreaterThanwhere x.age > ?1
GreaterThanEqualfindByAgeGreaterThanEqualwhere x.age >= ?1
AfterfindByCreateTimeAfterwhere x.create > ?1
BeforefindByCreateTimeBeforewhere x.createTime < ?1
IsNullfindByAgeIsNullwhere x.age is null
IsNotNull NotNullfindByAgeIsNotNull, findByAgeNotNullwhere x.age is not null
LikefindByTitleLikewhere x.title like ?1
NotLikefindByTitleNotLikewhere x.title not like ?1
StartingWithfindByTitleStartingWithwhere x.title like ?1(title前加%)
EndingWithfindByTitleEndingWithwhere x.title like ?1(title后加%)
ContainingfindByTitleContainingwhere x.title like ?1(前后都加)
OrderByfindByTitleOrderByIdDescwhere x.title order by id desc
NotfindByTitleNotwhere title <> ?1
InfindByAgeIn(Collection ages)where x.age in ?1
NotInfindByAgeNotIn(Collection ages)where x.age not in ?1
TruefindByActiveTruewhere x.active = true
FalsefindByActiveFalsewhere x.active = false
ignoreCasefindByTitleIgnoreCasewhere 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

{
    "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来解决战斗。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【2021年,将Spring全家桶系列课程进行Review,修复顺序等错误。进入2022年,将Spring的课程进行整理,整理为案例精讲的系列课程,并新增高级的Spring Security等内容,通过手把手一步步教你从零开始学会应用Spring,课件将逐步进行上传,敬请期待】 本课程是Spring案例精讲课程的第四部分Spring Cloud,Spring案例精讲课程以真实场景、项目实战为导向,循序渐进,深入浅出的讲解Java网络编程,助力您在技术工作中更进一步。 本课程聚焦Spring Cloud的核心知识点:注册中心、服务提供者与消费者、服务的调用OpenFeign、Hystrix监控、服务网关gateway、消息驱动的微服务Spring Cloud Stream、分布式集群、分布式配置中心的案例介绍, 快速掌握Spring Cloud的核心知识,快速上手,为学习及工作做好充足的准备。 由于本课程聚焦于案例,即直接上手操作,对于Spring的原理等不会做过多介绍,希望了解原理等内容的需要通过其他视频或者书籍去了解,建议按照该案例课程一步步做下来,之后再去进一步回顾原理,这样能够促进大家对原理有更好的理解。【通过Spring全家桶,我们保证你能收获到以下几点】 1、掌握Spring全家桶主要部分的开发、实现2、可以使用Spring MVC、Spring Boot、Spring Cloud及Spring Data进行大部分的Spring开发3、初步了解使用微服务、了解使用Spring进行微服务的设计实现4、奠定扎实的Spring技术,具备了一定的独立开发的能力  【实力讲师】 毕业于清华大学软件学院软件工程专业,曾在Accenture、IBM等知名外企任管理及架构职位,近15年的JavaEE经验,近8年的Spring经验,一直致力于架构、设计、开发及管理工作,在电商、零售、制造业等有丰富的项目实施经验  【本课程适用人群】如果你是一定不要错过!  适合于有JavaEE基础的,如:JSP、JSTL、Java基础等的学习者没有基础的学习者跟着课程可以学习,但是需要补充相关基础知识后,才能很好的参与到相关的工作中。 【Spring全家桶课程共包含如下几门】 

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值