spring-data-jpa操作jpa(hibernate實現)

1.在maven的pom文件中添加依賴

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>	<!-- druid start -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>1.1.9</version>
		</dependency>
		<!-- druid end -->
		<!-- mysql start -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>8.0.11</version><!--$NO-MVN-MAN-VER$ -->
		</dependency>
		<!-- mysql end -->


2.在springboot的配置文件yml文件中配置數據庫鏈接信息

spring:
#數據庫鏈接信息配置
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    url: jdbc:mysql://192.168.1.25:3306/test?useUnicode=true&characterEncoding=utf8
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
#JPA配置
  jpa:
    hibernate:
      ddl-auto: create-drop
    show-sql: true
    database-platform: org.hibernate.dialect.MySQL55Dialect
#請求編碼配置  
  http:
    encoding:
      charset: UTF-8
      force: true
      enabled: true
#日誌配置
logging:
  file: /logs/springBootTest.log
  pattern:
    level: debug

3.具體編碼

3.1第一步:構建實體類Customer

package com.example.myapplication.customer;


import java.io.Serializable;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import com.example.myapplication.order.Order;

@Table
@Entity
public class Customer implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 4340240628311870193L;
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(columnDefinition="int unsigned")
	private Long id;
	@Column(nullable=false)
	private String name;
	@Column(name="borthday",nullable=false)
	private Date borthDay;
	@Column(nullable=false)
	private String address;
	@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL)
	private List<Order> orders;
	
	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 Date getBorthDay() {
		return borthDay;
	}
	public void setBorthDay(Date borthDay) {
		this.borthDay = borthDay;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	
	public List<Order> getOrders() {
		return orders;
	}
	public void setOrders(List<Order> orders) {
		this.orders = orders;
	}
	@Override
	public String toString() {
		return "Customer [id=" + id + ", name=" + name + ", borthDay=" + borthDay + ", address=" + address + "]";
	}
	
}

構建實體類Order,order是mysql數據庫的關鍵字(order by),必須用``包括住,否則無法報錯,無法創建表

package com.example.myapplication.order;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import com.example.myapplication.customer.Customer;
import com.fasterxml.jackson.annotation.JsonBackReference;

@Entity
@Table(name="`order`")
public class Order implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = -5202655458725277540L;
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(columnDefinition="int unsigned")
	private Long id;
	@Column(nullable=false,length=50)
	private String name;
	@Column(nullable=false)
	private String sn;
	@Column(nullable=false)
	private Long price;
	@Column(nullable=false,columnDefinition="tinyint default 0 COMMENT '狀態:0 未支付;1 已支付;'")
	private Integer state;
	@JsonBackReference
	@ManyToOne(optional=true,fetch=FetchType.EAGER)
	private Customer customer;
	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 getSn() {
		return sn;
	}
	public void setSn(String sn) {
		this.sn = sn;
	}
	public Long getPrice() {
		return price;
	}
	public void setPrice(Long price) {
		this.price = price;
	}
	public Integer getState() {
		return state;
	}
	public void setState(Integer state) {
		this.state = state;
	}
	public Customer getCustomer() {
		return customer;
	}
	public void setCustomer(Customer customer) {
		this.customer = customer;
	}
}

實體類構建是使用hibernate最關鍵的一步

@Tabe:標記這是一個表<->實體類的關係映射關係,如果表名和實體類一致不用填寫name屬性,表名和實體類名對應關係是

實體類類名首字母大寫:表名首字母小寫;實體類類名中間有駝峯形式的大寫字母:表名在大寫字母前加"_",對應字母小寫;

例如:實體類OrderItem==>表名:order_item,字段名的命名規範也是一至的

@Entity:標記這個類是實體類,

實體類之間一般通過一對多,多對一來管理映射關係

@JsonBackReference



這個標籤可以在json序列化的時候忽略這個字段,避免由於雙向關聯引起的無限遞歸報錯,該字段仍然有值;

@JsonManagedReference則是在json反序列化的時候忽略字段,該字段仍然有值;

@JsonIgnore則是json序列化時候完全忽略該字段,並且該字段不會被賦值

3.2 第二步:構建Repository,也就是我們傳統上的dao,持久層的操作方法都在這裏

例如:

import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;

public interface OrderRepository extends JpaRepository<Order, Long>{

	@Override
	default <S extends Order> Optional<S> findOne(Example<S> example) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	default <S extends Order> Page<S> findAll(Example<S> example, Pageable pageable) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	default <S extends Order> long count(Example<S> example) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	default <S extends Order> boolean exists(Example<S> example) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	default Page<Order> findAll(Pageable pageable) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	default <S extends Order> S save(S entity) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	default Optional<Order> findById(Long id) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	default boolean existsById(Long id) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	default long count() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	default void deleteById(Long id) {
		// TODO Auto-generated method stub
		
	}

	@Override
	default void delete(Order entity) {
		// TODO Auto-generated method stub
		
	}

	@Override
	default void deleteAll(Iterable<? extends Order> entities) {
		// TODO Auto-generated method stub
		
	}

	@Override
	default void deleteAll() {
		// TODO Auto-generated method stub
		
	}

	@Override
	default List<Order> findAll() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	default List<Order> findAll(Sort sort) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	default List<Order> findAllById(Iterable<Long> ids) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	default <S extends Order> List<S> saveAll(Iterable<S> entities) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	default void flush() {
		// TODO Auto-generated method stub
		
	}

	@Override
	default <S extends Order> S saveAndFlush(S entity) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	default void deleteInBatch(Iterable<Order> entities) {
		// TODO Auto-generated method stub
		
	}

	@Override
	default void deleteAllInBatch() {
		// TODO Auto-generated method stub
		
	}

	@Override
	default Order getOne(Long id) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	default <S extends Order> List<S> findAll(Example<S> example) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	default <S extends Order> List<S> findAll(Example<S> example, Sort sort) {
		// TODO Auto-generated method stub
		return null;
	}
	
}

只要像下面這樣簡單的繼承JpaRepository<實體類類型,id類型>就可以得到上面的所有方法實現,無需程序員自己去編寫代碼,

jpa的多表操作通常都是通過第一步的構建實體類,配置關係映射和級聯關係這幾個步驟來實現的

package com.example.myapplication.order;

import org.springframework.data.jpa.repository.JpaRepository;

public interface OrderRepository extends JpaRepository<Order, Long>{
	
}

當然,如果你喜歡更加靈活一些的方法也可以的,這是通過jpql(一種和hql高度相似的面向對象的查詢語言)來實現的查詢,第一種方法是直接使用Jpql來查詢,第二種則是通過固定的前綴,例如findBy,再加上駝峯命名的字段條件作爲方法名(個人感覺雖然不用寫jpql,但是還是如果條件多的話文件名就會過長了,也不好維護)

@Repository("customerRepository")
public interface ICustomerRepository extends JpaRepository<Customer, Long>{

	@Query(value="SELECT customer FROM Customer customer where id = ?1")
	Customer getCustomer(Long id);
	//@Query(value="SELECT customer FROM Customer customer where name = ?1 and address = ?2")
	Customer findByNameAndAddress(String name,String address);
}


jpql的參數傳遞也可以這樣,更加方便容易維護:
	@Query(value="SELECT customer FROM Customer customer where id = :id and name = :name")
	Customer getCustomer(@Param("id")Long id,@Param("name")String name);

如果對jpql不熟悉的,也可以使用自然sql,不過映射的對象依然必須是該實體類類型或者是Object類型,不能是自定義的一個javaBean,這個也是hibernate/jpa這種完全ORM框架的不靈活的地方,相對複雜的查詢,結果集映射沒有mybatis那樣可以自由靈活地返回自定義的map<k,v>集合,list<Map<k,v>>集合

@Query(value="select * from `order` where id=:id and name=:name",nativeQuery=true)
	Order getOder(@Param("id")Long id,@Param("name")String name);
	@Query(value="select * from `order` where id=? and name=?",nativeQuery=true)
	Order getOder2(Long id,String name);

還有一種通過Example對象操作來進行查詢的方法:

ExampleMatcher matcher = ExampleMatcher.matching()
				  .withMatcher("id", match -> match.endsWith())
				  .withMatcher("name", match -> match.startsWith());
		Order probe = new Order();
		probe.setId(1l);
		Example<Order> ex = Example.of(probe , matcher);
		List<Order> lis = orderRepository.findAll(ex);



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章