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);
}


@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);