very happy main
package com.example.springbucksdemo;
import com.example.springbucksdemo.model.Coffee;
import com.example.springbucksdemo.model.CoffeeOrder;
import com.example.springbucksdemo.model.OrderState;
import com.example.springbucksdemo.repository.CoffeeOrderRepository;
import com.example.springbucksdemo.repository.CoffeeRepository;
import org.joda.money.CurrencyUnit;
import org.joda.money.Money;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Transactional;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* lesson 18
* Repository
* @EnableJpaRepositories (帮我自动发现CurdRepository等这样的接口的扩展)
*
* 定义查询
* 根据方法名定义查询
* find...By... / read...By... / query...By / get...By...
* count...By...
* ...OrderBy... [Asc / Desc]
* And / Or / IgnoreCase
* Top / First / Distinct
*
* 分页查询
* PagingAndSortingRepository<T,ID>
* Pageable/Sort
* Slice<T>/Page<T>
*
*
*/
@SpringBootApplication
@EnableJpaRepositories
@EnableTransactionManagement
public class SpringBucksDemoApplication implements ApplicationRunner {
@Autowired
private CoffeeRepository coffeeRepository;
@Autowired
private CoffeeOrderRepository orderRepository;
public static void main(String[] args) {
SpringApplication.run(SpringBucksDemoApplication.class, args);
}
@Override
@Transactional
public void run(ApplicationArguments args) throws Exception {
initOrders();
findOrders();
}
private void initOrders(){
Coffee latte = Coffee.builder().name("latte")
.price(Money.of(CurrencyUnit.of("CNY"), 30.0)).build();
Coffee save = coffeeRepository.save(latte);
if(save!=null){
System.out.println("Coffee:"+latte);
}else{
System.out.println("Coffee not saved");
}
Coffee espresso = Coffee.builder()
.name("espresso")
.price(Money.of(CurrencyUnit.of("CNY"), 20.0))
.build();
Coffee save1 = coffeeRepository.save(espresso);
if(save1!=null){
System.out.println("Coffee:"+espresso);
}else{
System.out.println("Coffee not saved");
}
CoffeeOrder order = CoffeeOrder.builder()
.customer("ZhangQi")
.items(Collections.singletonList(espresso))
.state(OrderState.INIT)
.build();
CoffeeOrder orderSave = orderRepository.save(order);
System.out.println("Order:"+order);
order = CoffeeOrder.builder()
.customer("JunJun")
.items(Arrays.asList(espresso, latte))
.state(OrderState.INIT)
.build();
orderRepository.save(order);
System.out.println("Order1:"+order);
}
private void findOrders(){
coffeeRepository
.findAll(Sort.by(Sort.Direction.DESC, "id"))
.forEach(c-> System.out.println("Loading"+c));
List<CoffeeOrder> list = orderRepository.findTop3ByOrderByUpdateTimeDescIdAsc();
System.out.println("findTop3ByOrder..."+getJoinedOrderId(list));
list = orderRepository.findByCustomerOrderById("ZhangQi");
System.out.println("findByCustomerOrder.ZQ.."+getJoinedOrderId(list));
list = orderRepository.findByCustomerOrderById("JunJun");
System.out.println("findByCustomerOrder.JunJun.."+getJoinedOrderId(list));
list.forEach(o->{
System.out.println("Order:"+o.getId());
o.getItems().forEach(i-> System.out.println("Item:"+i));
});
list = orderRepository.findByItems_Name("latte");
System.out.println("findByItems.Name:"+getJoinedOrderId(list));
}
/**
* 转换list获取id加入join形成1,2,3
* @param list
* @return
*/
private String getJoinedOrderId(List<CoffeeOrder> list){
return list.stream().map(o->o.getId().toString())
.collect(Collectors.joining(","));
}
}
model
BaseEntity
package com.example.springbucksdemo.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
/**
* 被继承的共有属性字段
*/
@MappedSuperclass
@Data
@NoArgsConstructor
@AllArgsConstructor
public class BaseEntity implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
//@GeneratedValue注解存在的意义主要就是为一个实体生成一个唯一标识的主键、@GeneratedValue提供了主键的生成策略。
// @GeneratedValue注解有两个属性,分别是strategy和generator
//AUTO主键由程序控制,是默认选项 ,不设置就是这个
//IDENTITY 主键由数据库生成, 采用数据库自增长, Oracle不支持这种方式
//SEQUENCE 通过数据库的序列产生主键, MYSQL 不支持
//Table 提供特定的数据库产生主键, 该方式更有利于数据库的移植
//generator
//generator属性的值是一个字符串,默认为"",其声明了主键生成器的名称
//(对应于同名的主键生成器@SequenceGenerator和@TableGenerator)
private Long id;
@Column(updatable = false)
@CreationTimestamp
private Date createTime;
@UpdateTimestamp
private Date updateTime;
}
Coffee
package com.example.springbucksdemo.model;
import lombok.*;
import org.hibernate.annotations.Type;
import org.joda.money.Money;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.io.Serializable;
import java.util.Date;
/**
* 不使用Lombok了,破坏封装性,如果有的不需要get,set的情况下
*/
@Entity
@Data
@Builder
@ToString(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@Table(name="T_MENU")
public class Coffee extends BaseEntity implements Serializable {
private String name;
/**
* 做映射,指定CNY人民币
* PersistentMoneyAmount是bigdecimal(19,2)
* PersistentMoneyMinorAmount是bigint Long
*/
// @Type(type = "org.jadira.usertype.moneyandcurrency.joda.PersistentMoneyAmount",
@Type(type = "org.jadira.usertype.moneyandcurrency.joda.PersistentMoneyMinorAmount",
parameters = {@org.hibernate.annotations.Parameter(name="currencyCode",value = "CNY")})
private Money price;
}
CoffeeOrder
package com.example.springbucksdemo.model;
import lombok.*;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* @Entity标注用于实体类声明语句之前,指出该Java 类为实体类,将映射到指定的数据库表。
* 如声明一个实体类 CoffeeOrder,它将映射到数据库中的 @Table指定的名称表上 T_ORDER
*/
@Entity
@Data
@Builder
@ToString(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@Table(name="T_ORDER")
public class CoffeeOrder extends BaseEntity implements Serializable {
private String customer;
/**
* 咖啡跟订单的关系 多对多
*/
@ManyToMany
@JoinTable(name="T_ORDER_COFFEE")
private List<Coffee> items;
//不能为空值
@Column(nullable = false)
private OrderState state;
}
OrderState
package com.example.springbucksdemo.model;
public enum OrderState {
INIT,PAID,BREWING,BREWED,TAKEN,CANCELLED
}
repository
BaseRepository
package com.example.springbucksdemo.repository;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
import java.util.List;
/**
* extends 分页and排序
* @param <T>
* @param <Long>
*
* 分页查询
* PagingAndSortingRepository<T,ID>
* Pageable / Sort
* Slice<T> / Page<T>
*
* @NoRepositoryBean 表示不需要为BaseRepository创建一个bean
*/
@NoRepositoryBean
public interface BaseRepository<T,Long> extends PagingAndSortingRepository<T,Long> {
List<T> findTop3ByOrderByUpdateTimeDescIdAsc();
}
package com.example.springbucksdemo.repository;
import com.example.springbucksdemo.model.CoffeeOrder;
import java.util.List;
public interface CoffeeOrderRepository extends BaseRepository<CoffeeOrder, Long> {
List<CoffeeOrder> findByCustomerOrderById(String customer);
List<CoffeeOrder> findByItems_Name(String name);
}
package com.example.springbucksdemo.repository;
import com.example.springbucksdemo.model.Coffee;
public interface CoffeeRepository extends BaseRepository<Coffee,Long> {
}
yml
spring:
jpa:
hibernate:
ddl-auto: create-drop #create and drop schema
properties:
hibernate:
format_sql: true
show_sql: true
<!--金额处理-->
<dependency>
<groupId>org.joda</groupId>
<artifactId>joda-money</artifactId>
<version>1.0.1</version>
</dependency>
<!--映射相关定制信息,帮助joda-money类的映射-->
<dependency>
<groupId>org.jadira.usertype</groupId>
<artifactId>usertype.core</artifactId>
<version>6.0.1.GA</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>