一.快速入门
1.首先就是导入依赖咯,没啥好说的,还有常见的一些依赖没导。web环境之类的,不过你既然都来到这了,我也就不用说了。
<!--jpa-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.3.12.RELEASE</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
<!--lombok用来简化实体类:需要安装lombok插件-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
2.配置jpa和数据库的配置文件
# 端口号
server.port=8001
# 开发环境
spring.profiles.active=dev
# mysql的配置
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/copy_used?serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=root
#json
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
#jpa的配置文件
#开启逆向工程
spring.jpa.generate-ddl=true
#如果设定的实体类发生了改变,那么数据表就会更新
spring.jpa.hibernate.ddl-auto=update
#操纵实体对象的时候货生成sql语句
spring.jpa.show-sql=true
#指定数据库的类型
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
3.实体类
import io.swagger.annotations.ApiModel;
import lombok.Data;
import javax.persistence.*;
import java.util.Date;
@Data
@ApiModel(value="Traveller对象", description="")
@Table(name="traveler")
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Traveler{
@Id//这个是主键
@GeneratedValue(strategy = GenerationType.IDENTITY)//设置增长方式是自增
private int id;
@Column
private String travelerName;//旅行者姓名
@Column
private String element;//旅行者的元素力
@Column
private Integer isDeleted;//是否被删除
@Column
private Date gmtCreate;//创建时间
@Column
private Date gmtModified;//最后一次修改时间
}
4.vo层,用来对得到的对象进行封装
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TravelerVo{
private int id;
private String travelerName;//旅行者姓名
private String element;//旅行者的元素力
private Integer isDeleted;//是否被删除
private Date gmtCreate;//创建时间
private Date gmtModified;//最后一次修改时间
}
5.Dao层的代码
import com.guguo.Entity.Traveler;
import org.springframework.data.jpa.repository.JpaRepository;
public interface TravelerDao extends JpaRepository<Traveler,Integer> {
}
5.直接在controller里面直接写业务逻辑了哈,不写Service了,不要在意这些细节。进行测试
import com.guguo.Entity.Traveler;
import com.guguo.Entity.vo.TravelerVo;
import com.guguo.dao.TravelerDao;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
@RestController
public class TravelController{
@Autowired
private TravelerDao travelerDao;
@GetMapping("/findAllTravelers")
public ArrayList<TravelerVo> findAllTravelers(){
List<Traveler> travelers = travelerDao.findAll();//调用框架的方法,查询所有的旅行者对象
ArrayList<TravelerVo> travelerVos = new ArrayList<>();//vo封装类
for (Traveler traveler:travelers) {//把查询到的数据封装到vo的list集合中
TravelerVo travelerVo = new TravelerVo();
BeanUtils.copyProperties(traveler,travelerVo);
travelerVos.add(travelerVo);
}
return travelerVos;//返回封装好的数据
}
}
6.结果,这个结果的展示是用了Swagger,如果没学过Swagger的话呢,也可以直接打印到控制台,问题不大其实。
二.一对多映射
1.实体类,VO类
1.实体类,一个旅行者有很多武器,每个武器都只归属于一个旅行者
import io.swagger.annotations.ApiModel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.util.Date;
import java.util.List;
//一的一方
@Data
@ApiModel(value="Traveler对象", description="")
@Table(name="traveler")
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Traveler{
@Id//这个是主键
@GeneratedValue(strategy = GenerationType.IDENTITY)//设置增长方式是自增
private int id;
//@Version
@Version
private int version;//这个就是注入的字段
@Column
private String travelerName;//旅行者姓名
@Column
private String element;//旅行者的元素力
@Column
private Integer isDeleted;//是否被删除
@Column
private Date gmtCreate;//创建时间
@Column
private Date gmtModified;//最后一次修改时间
@OneToMany(mappedBy = "traveler",fetch = FetchType.EAGER)//mappedBy创建一对多的映射关系,值是对方类中关于己方的属性名称,那个fetch表示是不是懒加载,这里设置的不是
private List<Arms> armsList;
}
import io.swagger.annotations.ApiModel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.util.Date;
@Data
@ApiModel(value="Arms对象", description="")
@Table(name="arms")
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Arms{
@Id//这个是主键
@GeneratedValue(strategy = GenerationType.IDENTITY)//设置增长方式是自增
private int id;
@Column
private String armsName;//武器名称
@Column
private String skillName;//武器自带技能的名称
@Column
private Integer isDeleted;//是否被删除
@Column
private Date gmtCreate;//创建时间
@Column
private Date gmtModified;//最后一次修改时间
@ManyToOne//多个武器对应一个角色
@JoinColumn(name="tid")//指定外键列
private Traveler traveler;
}
2.实体映射vo类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TravelerVo{
private int id;
private String travelerName;//旅行者姓名
private String element;//旅行者的元素力
private Integer isDeleted;//是否被删除
private Date gmtCreate;//创建时间
private Date gmtModified;//最后一次修改时间
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ArmsVo{
private int id;
private String armsName;//武器名称
private String skillName;//武器自带技能的名称
private Integer isDeleted;//是否被删除
private Date gmtCreate;//创建时间
private Date gmtModified;//最后一次修改时间
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TravlerAndArms {
private int id;
private String travelerName;//旅行者姓名
private String element;//旅行者的元素力
private Integer isDeleted;//是否被删除
private Date gmtCreate;//创建时间
private Date gmtModified;//最后一次修改时间
private List<ArmsVo> armsVos=new ArrayList<>();
}
2.查询方法
查询事例:
@GetMapping("/findAllTravelers")
public List<TravlerAndArms> findAllTravelers(){
List<Traveler> travelers = travelerDao.findAll();//调用框架的方法,查询所有的旅行者对象
ArrayList<TravlerAndArms> travlerAndArmsList = new ArrayList<>();//vo封装类
for (Traveler traveler:travelers) {
TravlerAndArms travlerAndArms = new TravlerAndArms();//先封装TravelerVo的属性
BeanUtils.copyProperties(traveler,travlerAndArms);
List<Arms> list = traveler.getList();//再封装ArmsVo集合
for (Arms arms:list) {
ArmsVo armsVo = new ArmsVo();
BeanUtils.copyProperties(arms,armsVo);
travlerAndArms.getArmsVos().add(armsVo);
}
travlerAndArmsList.add(travlerAndArms);
}
return travlerAndArmsList;//返回封装好的数据
}
jpql语句查询:
语句书写:
package com.guguo.dao;//旅行者Dao
import com.guguo.Entity.Traveler;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
//多的一放默认是立即加载,一的一方默认是懒加载
public interface TravelerDao extends JpaRepository<Traveler,Integer> {
//普通查询
@Query("from Traveler where travelerName =:travelerName")
Traveler selectTraveler(String travelerName);
//左外连接
@Query("select t from Traveler t left join fetch t.armsList where t.travelerName =:travelerName")
Traveler selectTravelerAndArms(String travelerName);
//内连接
@Query("select t from Traveler t inner join fetch t.armsList where t.travelerName =:travelerName")
Traveler selectArmsAndTraveler(String travelerName);
}
package com.guguo.dao;//武器Dao
import com.guguo.Entity.Arms;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
//多的一放默认是立即加载,一的一方默认是懒加载
public interface ArmsDao extends JpaRepository<Arms,Integer> {
//普通查询
@Query("from Arms where armsName =:armsName")
Arms selectArms(String armsName);
//左外连接
@Query("select a from Arms a left join fetch a.traveler where a.armsName =:armsName")
Arms selectTravelerAndArms(String armsName);
//内连接
@Query("select a from Arms a inner join fetch a.traveler where a.armsName =:armsName")
Arms selectArmsAndTraveler(String armsName);
}
测试://测试的代码都差不多,我就写一个方便以后粘代码就好
package com.guguo.test;
import com.guguo.Application;
import com.guguo.Entity.Arms;
import com.guguo.Entity.Traveler;
import com.guguo.dao.TravelerDao;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
@SpringBootTest(classes=Application.class)
@RunWith(SpringRunner.class)
public class TraveleAndArmsTest {
@Autowired
private TravelerDao travelerDao;
@Test//Traveler左外连接
public void test1(){
Traveler traveler = travelerDao.selectTravelerAndArms("胡桃");
System.out.println("Traveler{" +
"id=" + traveler.getId() +
", version=" + traveler.getVersion() +
", travelerName='" + traveler.getTravelerName() + '\'' +
", element='" + traveler.getElement() + '\'' +
", isDeleted=" + traveler.getIsDeleted() +
", gmtCreate=" + traveler.getGmtCreate() +
", gmtModified=" + traveler.getGmtModified() +
'}');
List<Arms> armsList = traveler.getArmsList();
System.out.println(armsList.get(0).getArmsName()+" "+armsList.get(0).getSkillName());
System.out.println(armsList.get(1).getArmsName()+" "+armsList.get(1).getSkillName());
}
@Test//Arms左外连接
public void test5(){
Arms arms = armsDao.selectTravelerAndArms("焚天火焰刀");
System.out.println(
"Arms{" +
"id=" + arms.getId() +
", armsName='" + arms.getArmsName() + '\'' +
", skillName='" + arms.getSkillName() + '\'' +
", isDeleted=" + arms.getIsDeleted() +
", gmtCreate=" + arms.getGmtCreate() +
", gmtModified=" + arms.getGmtModified() +
", traveler=" + arms.getTraveler().getTravelerName() +
'}');
}
}
三.多对多映射
1.实体类,VO类
实体类:
package com.guguo.Entity;
import io.swagger.annotations.ApiModel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Data
@ApiModel(value="Emp对象", description="这个是员工的实体类")
@Table(name="Emp")
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Emp {
@Id//这个是主键
@GeneratedValue(strategy = GenerationType.IDENTITY)//设置增长方式是自增
private int id;
@Column
private String empName;//员工姓名
@Column
private Integer isDeleted;//是否被删除
@Column
private Date gmtCreate;//创建时间
@Column
private Date gmtModified;//最后一次修改时间
@ManyToMany(mappedBy = "emps")
private List<Project> projects=new ArrayList<>();
}
项目类:
package com.guguo.Entity;
import io.swagger.annotations.ApiModel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Data
@ApiModel(value="Project对象", description="这个是项目类")
@Table(name="project")
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Project {
@Id//这个是主键
@GeneratedValue(strategy = GenerationType.IDENTITY)//设置增长方式是自增
private int id;
@Column
private String projectName;//项目名
@Column
private Integer isDeleted;//是否被删除
@Column
private Date gmtCreate;//创建时间
@Column
private Date gmtModified;//最后一次修改时间
@ManyToMany
@JoinTable(name="emps_pros",uniqueConstraints = @UniqueConstraint(columnNames = {"e_id","p_id"}),
joinColumns = {@JoinColumn(name="p_id",referencedColumnName = "id")},//以本类的id生成的字段
inverseJoinColumns = {@JoinColumn(name="e_id",referencedColumnName = "id")}//参考另一个类的id字段生成的字段
)
private List<Emp> emps=new ArrayList<>();
}
Vo类:
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ProjectVo {
private int id;
private String projectName;//项目名
private Integer isDeleted;//是否被删除
private Date gmtCreate;//创建时间
private Date gmtModified;//最后一次修改时间
}
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class EmpVo {
private int id;
private String empName;//员工姓名
private Integer isDeleted;//是否被删除
private Date gmtCreate;//创建时间
private Date gmtModified;//最后一次修改时间
}
2.查询操作
四.自关联一对多映射
1.实体类
package com.guguo.Entity;
import io.swagger.annotations.ApiModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Data
@ApiModel(value="Node对象", description="哎")
@Table(name="node")
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Builder
public class Node {
@Id//这个是主键
// @GeneratedValue(strategy = GenerationType.IDENTITY)//设置增长方式是自增
private int id;
//@Builder.Default
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name="pid")
private Node parent;
@OneToMany(mappedBy = "parent",fetch = FetchType.EAGER)
private List<Node> chileren=new ArrayList<>();
public Node(int i) {
this.setId(i);
}
}
2.查询和保存方法
package com.guguo.controller;
import com.guguo.Entity.Node;
import com.guguo.Entity.vo.TravelerVo;
import com.guguo.dao.NodeDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Optional;
@RestController
public class NodeController {
@Autowired
private NodeDao nodeDao;
@GetMapping("/nodeSave")
public void nodeSave(){
Node node1 = new Node();node1.setId(1);
Node node2 = new Node();node2.setId(2);node2.setParent(node1);
Node node3 = new Node();node3.setId(3);node3.setParent(node1);
Node node4 = new Node();node4.setId(4);node4.setParent(node1);
nodeDao.save(node1);
nodeDao.save(node2);
nodeDao.save(node3);
nodeDao.save(node4);
node1.getChileren().add(node2);
node1.getChileren().add(node3);
node1.getChileren().add(node4);
nodeDao.save(node1);
// List<Node> all = nodeDao.findAll();
// all.stream().forEach(node->{
// System.out.println(node.getId());
//
// });
//查某个结点下的子结点
Optional<Node> byId = nodeDao.findById(1);
Node node = byId.get();
System.out.println(node.getId());
List<Node> chileren = node.getChileren();
System.out.println(chileren.size());
chileren.stream().forEach(de->{
System.out.println(de.getId());
});
return ;
}
}