spring boot整合jpa day(1)
一、jpa
1.1 添加依赖
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.1.11.RELEASE</version>
</dependency>
//还有mysql连接的依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
1.2 创建实体类
@Entity
@Table(name = "User")
public class User {
String email;
String pass;
@Id@GeneratedValue(strategy = GenerationType.AUTO)
int id;
public User() {
}
public User(String email, String pass) {
this.email = email;
this.pass = pass;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
1.3 创建Dao层
public interface UserDao extends CrudRepository<User,Integer> {
public User findByEmailAndPass(@Param("email") String email, @Param("pass") String pass);
}
1.4 创建service层
@Service
public class UserService {
@Autowired
UserDao userDao;
public User findByEmailAndPass(String email,String pass){
return userDao.findByEmailAndPass(email,pass);
}
}
1.5 创建controller层
@RestController
public class UserController {
@Autowired
UserService userService;
@RequestMapping("/login")
public Result login(@RequestParam("email")String email, @RequestParam("pass")String pass){
User byEmailAndPass = userService.findByEmailAndPass(email, pass);
if(byEmailAndPass == null){
System.out.println("失败");
return new Result(Msg.EmailOrPassError);
}else {
System.out.println("成功");
return new Result(Msg.LoginSuccess);
}
}
}
二、结果类的分封装
2.1 Msg类
public class Msg {
int code;
String message;
public Msg(int code, String message) {
this.code = code;
this.message = message;
}
public static final Msg EmailOrPassError = new Msg(100001,"邮箱或者手机号错误");
public static final Msg LoginSuccess = new Msg(1000010,"登陆成功");
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public static Msg getEmailOrPassError() {
return EmailOrPassError;
}
public static Msg getLoginSuccess() {
return LoginSuccess;
}
}
2.2 Result类
package com.example.demo.Response;
public class Result<T> {
int code;
String message;
T data;
public Result(int code, String message, T data) {
this.code = code;
this.message = message;
this.data = data;
}
public Result(int code, String message) {
this.code = code;
this.message = message;
}
public Result(Msg msg){
this.code = msg.code;
this.message = msg.message;
}
public Result(Msg msg, T data){
this.code = msg.code;
this.message = msg.message;
this.data = data;
}
public static Result Success = new Result(1,"success");
public static Result Failed = new Result(0,"success");
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public static Result getSuccess() {
return Success;
}
public static void setSuccess(Result success) {
Success = success;
}
public static Result getFailed() {
return Failed;
}
public static void setFailed(Result failed) {
Failed = failed;
}
}
三、测试结果
1.1 登录成功
1.2 登录失败
四、遇到的错误
4.1 spring boot无法将结果转换为JSON格式
No converter found for return value of type: class com.example.demo.Response
返回的实体类中缺少get和set方法,缺少这两个方法会导致spring boot无法将结果转换为JSON格式,就会出错。
4.2 datasource为Null
- 配置远程maven为阿里源
<repository>
<id>aliyun</id>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
4.3 字段长度修改问题
- 已经生成表的实体类上的字段重新修改字段长度,在数据库中是不会被修改的,需要自己手动修改。varchar的默认长度是255
五、JPA相关的配置
5.1 数据库相关配置
spring.datasource.url=jdbc:mysql://192.168.16.103:3306/blockcoin?useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=******
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#spring.jpa.properties.hibernate.hbm2ddl.auto=update
#spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql= true
5.2 测试数据库链接
@SpringBootTest
class DemoApplicationTests {
@Autowired
DataSource dataSource;
@Test
public void testMysqlConn() throws SQLException {
System.out.println(dataSource.getConnection());
}
}
5.3 测试结果
5.4 jpa配置
- 不添加jpa配置就不会创建表
spring:
datasource:
username: root
url: jdbc:mysql://192.168.1.109:3306/student
driver-class-name: com.mysql.cj.jdbc.Driver
password: 510363
jpa:
hibernate:
ddl-auto: update
show-sql: true
5.5 提示datasource为null
- 注意:测试文件一定要在com.example.demo文件中
5.6 driver-class-name: com.mysql.cj.jdbc.Driver
- 是userName不是name
六、JPA中需要了解的注解
6.1 注解了解
6.2 findall排序
@RequestMapping("/getAllPort")
public boolean getAllPort(){
ArrayList<Sort.Order> list = new ArrayList<>();
Sort.Order order = new Sort.Order(Sort.Direction.ASC, "callMark");
Sort.Order order1 = new Sort.Order(Sort.Direction.ASC, "callNumber");
list.add(order);
list.add(order1);
//Sort.by(list)可以是一个order也可以是orderList
List<IpfsPort> all = ipfsPortDao.findAll(Sort.by(list));
for(IpfsPort ip : all){
System.out.println(ip.getHost() + "----" + ip.getPort()+ "----" + ip.getCallMark() + "----" + ip.getCallNumber());
}
return true;
}
七、插入数据测试
7.1 service层
- dao层不用写方法,直接调用父类的save方法即可。
- 测试
public User save(User user){
return userDao.save(user);
}
返回值是User对象
7.2 controller层
@RequestMapping("/regist")
public Result regist(@RequestParam("email")String email, @RequestParam("pass")String pass){
User byEmailAndPass = userService.findByEmailAndPass(email, pass);
if(byEmailAndPass != null){
System.out.println("重复注册");
return new Result(Msg.RepeatRegist);
}
User user = new User(email, pass);
User save = userService.save(user);
if(save == null){
return new Result(Msg.RegistFailed);
}else {
return new Result(Msg.RegistSucess);
}
}
}
7.3 结果展示
- 重复注册
* 注册成功
* 注册失败
八、jpa中的增删改查
8.1 修改语句
两种实现方式:
- save()方法,主键相同时是修改功能。
- @Query(value = " ")语句
- Dao层
public interface UserInfoDao extends JpaRepository<UserInfo,Integer>{
public UserInfo findByEmail(String emial);
@Modifying
@Query(value = "update user_info set sname = ?1,email = ?2,address = ?3,phone = ?4,info = ?5,height = ?6 where email = ?7",nativeQuery = true)
public int update(String sname,String email1,String address,String phone,String into,float height,String email);
}
- Service层
@Service
public class UserInfoService {
@Autowired
UserInfoDao userInfoDao;
@Transactional
//更新个人信息编辑,sid相同时是update
public UserInfo update(UserInfo userInfo){
UserInfo save = userInfoDao.save(userInfo);
return save;
}
//更新个人信息编辑,sid相同时是update
@Transactional
public int update1(UserInfo userInfo,String email2){
return userInfoDao.update(userInfo.sname,userInfo.email,userInfo.address,userInfo.phone,userInfo.info,userInfo.height, email2);
}
}
8.2 插入语句
- save方法
九、记录
9.1 出错一
Caused by: org.hibernate.MappingException: Could not determine type for: lom
- 原因
定义实体类时,对大小写敏感,建议改为小写。
9.2 注意
save方法是默认的,不能再dao中添加save()方法,不然会报错的。
十、案例
10.1 表一
- 表一和表二的关系是一对多
- mappedby是表一的名称
package com.example.demo.Ipfs.Entity;
import lombok.*;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Table
public class IpfsPort {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
int ipfsPortPid;
String host;
String port;
//该Ipfs节点存取数据的次数
String callNumber;
//对ipfs节点进行存取评估
String callMark;
@OneToMany(mappedBy = "ipfsPort")
public List<IpfsPortHistory> iplist = new ArrayList<IpfsPortHistory>();
public IpfsPort(String host, String port, String callNumber, String mark) {
this.host = host;
this.port = port;
this.callMark = mark;
this.callNumber = callNumber;
}
//对节点进行评估,这里只进行了ipfs节点运行成功和失败的简单的比较
public String ipfsNodeAssessment(){
int successRun = 0;
int errorRun = 0;
for(IpfsPortHistory node : this.iplist){
if(node.res == 0){
successRun ++;
}else {
errorRun ++;
}
}
int value = (int)(successRun / (successRun + errorRun)) * 100;
this.callMark = String.valueOf(value);
return String.valueOf(value);
}
}
10.2 表二
package com.example.demo.Ipfs.Entity;
import lombok.*;
import javax.persistence.*;
import java.text.SimpleDateFormat;
import java.util.Date;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Table
@Entity
//记录Ipfs以往的运行记录:比如出错的原因,时间,等等...
//节点成功运行或者错误运行的记录
public class IpfsPortHistory {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
int ipHisId;
//ipfs测估的时间
String recordDate;
//0代表success,1代表false
int res;
//节点出错的原因
String reason;
//节点此刻的评估分数
String callMark;
@ManyToOne
IpfsPort ipfsPort;
public IpfsPortHistory(int res, String reason, IpfsPort ipfsPort){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("YYYY-mm-DD:hh-MM-ss");
String format = simpleDateFormat.format(new Date());
this.callMark = ipfsPort.getCallMark();
this.recordDate = format;
}
public IpfsPortHistory(int res, String reason,String callMark){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("YYYY-mm-DD:hh-MM-ss");
String format = simpleDateFormat.format(new Date());
this.recordDate = format;
this.reason = reason;
this.callMark = callMark;
}
}
10.3 Dao层
package com.example.demo.Ipfs.Dao;
import com.example.demo.Ipfs.Entity.IpfsPort;
import com.example.demo.Ipfs.Entity.IpfsPortHistory;
import jdk.nashorn.internal.objects.annotations.Property;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.data.jpa.repository.JpaRepository;
//操作Ipfs节点记录的Dao
public interface IpfsHisDao extends JpaRepository<IpfsPortHistory,Integer> {
public void findByIpHisId(int id);
}
package com.example.demo.Ipfs.Dao;
import com.example.demo.Ipfs.Entity.IpfsPort;
import com.example.demo.Ipfs.Entity.IpfsPortHistory;
import org.springframework.data.jpa.repository.JpaRepository;
//操作ipfs节点的dao
public interface IpfsPortDao extends JpaRepository<IpfsPort, Integer> {
public void findByIpfsPortPid(int id);
}
10.4 controller层
package com.example.demo.Ipfs.Controller;
import com.example.demo.Ipfs.Dao.IpfsHisDao;
import com.example.demo.Ipfs.Dao.IpfsPortDao;
import com.example.demo.Ipfs.Entity.IpfsPort;
import com.example.demo.Ipfs.Entity.IpfsPortHistory;
import com.example.demo.Ipfs.Util.IpfsUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ipfsService {
@Autowired
IpfsPortDao ipfsPortDao;
@Autowired
IpfsHisDao ipfsHisDao;
@RequestMapping("/port")
public IpfsPort selectPort() {
for (int i = 0; i < 100; i++) {
IpfsPort ipfsPort = IpfsUtil.IpfsPortFactory();
IpfsPort save = ipfsPortDao.save(ipfsPort);
}
IpfsPort ipfsPort = IpfsUtil.IpfsPortFactory();
IpfsPort save = ipfsPortDao.save(ipfsPort);
return save;
}
@RequestMapping("/portHis")
public void selectPortHistory() {
for (int i = 0; i < 10; i++) {
int ipfsPortId = (int) (Math.random() * 90) + 50;
IpfsPort byIpfsPortPid = ipfsPortDao.findByIpfsPortPid(ipfsPortId);
while (byIpfsPortPid == null) {
ipfsPortId = (int) (Math.random() * 90) + 50;
byIpfsPortPid = ipfsPortDao.findByIpfsPortPid(ipfsPortId);
}
IpfsPortHistory ipfsPortHistory = IpfsUtil.IpfsPortHistoryPortFactory();
ipfsPortHistory.setIpfsPort(byIpfsPortPid);
IpfsPortHistory save = ipfsHisDao.save(ipfsPortHistory);
}
}
}
10.5 util工具
package com.example.demo.Ipfs.Util;
import com.example.demo.Ipfs.Entity.IpfsPort;
import com.example.demo.Ipfs.Entity.IpfsPortHistory;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.UUID;
public class IpfsUtil {
public static void main(String[] args) {
System.out.println(IpfsPortFactory().toString());
System.out.println(IpfsPortHistoryPortFactory().toString());
}
public static IpfsPort IpfsPortFactory(){
String host = "192.168.";
String port = String.valueOf((int) (Math.random() * 9000) + 1000);
int host1 = (int) (Math.random() * 900) + 99;
int host2 = (int) (Math.random() * 900) + 99;
host = host + host1 + "." + host2;
IpfsPort ipfsPort = new IpfsPort();
String callNumber = String.valueOf((int) (Math.random() * 10000));
String mark = String.valueOf((int) (Math.random() * 100));
IpfsPort ipfsPort1 = new IpfsPort(host,port,callNumber,mark);
return ipfsPort1;
}
public static IpfsPortHistory IpfsPortHistoryPortFactory(){
int res = (int) (Math.random() * 2);
String mark = String.valueOf((int) (Math.random() * 100));
String reason = UUID.randomUUID().toString().replaceAll("-","");
IpfsPortHistory ipfsPortHistory = new IpfsPortHistory(res,reason,mark);
return ipfsPortHistory;
}
}
十一、报错
11.1 java.lang.IllegalArgumentException: Not an managed type:
- 实体类没加@Entity注释,导致在容器中找不到实体类