是Sun官方在JDK5.0后提出的Java持久化规范, hibernate实现了这个规范,比mybais有优势
测试持久层目的:就是为了验证数据表创建,查询等,所以不用在mysql等数据库验证
坚持使用h2 三种模式之一的内存mem模式,也获得了url
url:jdbc:h2:mem:musicbird;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MODE=MYSQL
h2 mem比较特别,连接了数据库即创建出来
最后也没有在这个界面上看到创建出来的表,而是通过使用repository中的
User2 getByUsername(String username)获得查询返回
否则会报错:Syntax error in SQL statement,也许有其他方法解决
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "create table [*]User (Id varchar(255) not null, created_time timestamp, updated_time timestamp, avatar varchar(255), email varchar(255), enabled boolean, gender varchar(255), last_login_ip varchar(255), last_login_time timestamp, locked boolean, mobile varchar(255), nickname varchar(255), password varchar(255), true_name varchar(255), username varchar(255), primary key (Id))"; expected "identifier"; SQL statement:
create table User (Id varchar(255) not null, created_time timestamp, updated_time timestamp, avatar varchar(255), email varchar(255), enabled boolean, gender varchar(255), last_login_ip varchar(255), last_login_t
里面的create语句不是我写的
Hibernate: drop table if exists user_all
Hibernate: create table user_all (id varchar(255) not null, created_time datetime, updated_time datetime, avatar varchar(255), email varchar(255), enabled bit, gender varchar(255), last_login_ip varchar(255), last_login_time datetime, locked bit, mobile varchar(255), nickname varchar(255), password varchar(255), true_name varchar(255), user
1)编写entity-->编写repository-->
在比如UserRepository中Generate 测试文件
2)测试文件会在test目录下
注意修改其application.properties以完成实现把h2数据库配置到其中
#---------服务器配置-----------
server.port=8080
#---------数据源配置-----------
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:musicbird;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MODE=MYSQL
spring.datasource.username=root
spring.datasource.password=123456
spring.sql.init.platform=h2
#SQL脚本编码
spring.sql.init.encoding=UTF-8
spring.sql.init.platorm=h2
#初始化模式
spring.sql.init.mode=always
#如果在初始化数据库时发生错误,是否停止
spring.sql.init.continue-on-error=false
#----------flyway配置--------------
spring.flyway.enabled=false
#---------JPA配置-------------
#要操作的目标数据库
spring.jpa.database=h2
#控制台显示SQL语句
spring.jpa.show-sql=true
#更新或者创建数据表结构
spring.jpa.hibernate.ddl-auto=update
#物理命名策略的完全限定名称
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
#是否在启动时初始化架构
spring.jpa.generate-ddl=true
logging.level.org.hibernate=DEBUG
#----------H2配置--------------
spring.h2.console.path=/h2-console
#启用控制台
spring.h2.console.enabled=true
里面的@Entity特别重要,每个entity都要有id,统一写在其父类里面了
package com.i7i8i9.musicbird1.entity;
import com.i7i8i9.musicbird1.enums.Gender;
import lombok.Data;
import javax.persistence.*;
import java.util.Date;
@Entity
@Data
public class User2 extends AbstractEntity{ //entity会自动映射到数据库
private String username;
private String password;
@Enumerated(EnumType.STRING)
private Gender gender; //因为已经定义在了enums里面,默认存储0,1,2,上面@内容表示取其内容,以便于存储在数据库
private String email;
private String avatar;
private String mobile;
private String nickname;
private String true_name;
private Boolean locked;
private Boolean enabled;
private String last_login_ip;
private Date last_login_time;
}
package com.i7i8i9.musicbird1.entity;
import lombok.Data;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.UpdateTimestamp;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import java.util.Date;
@MappedSuperclass //这个是让其他类能够继承id,好像可以不加,有的不加子类报错
@Data
public abstract class AbstractEntity {
@javax.persistence.Id //这个是自动生成的,或许可以直接用@Id
@GeneratedValue(generator = "ksuid")
@GenericGenerator(name="ksuid",strategy = "com.i7i8i9.musicbird1.utils.KsuidIdentifierGenerator")
private String Id;//Id新建时候会自东调用上面的类,把值塞进去
@CreationTimestamp //hibernate 表示创建时候更新
private Date created_time;
@UpdateTimestamp
private Date updated_time;
}
package com.i7i8i9.musicbird1.repository;
import com.i7i8i9.musicbird1.entity.User2;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository {//User指的是entity中的user string 指的是id
// default List findByUsername(String username) {
// return findByUsername(username);
// }
User2 getByUsername(String username);
}
可以在repository文件上右键generate生成
里面的 三个必须,其余未研究
@DataJpaTest 说明这是在测试数据库操作 @Autowired @Test
package com.i7i8i9.musicbird1.repository;
import com.i7i8i9.musicbird1.entity.User2;
import com.i7i8i9.musicbird1.enums.Gender;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.annotation.Commit;
import org.springframework.test.context.ActiveProfiles;
import java.util.Date;
// @ActiveProfiles("dev") 指定是不是使用application-dev.properties
@DataJpaTest //持久层测试必须写这个
//@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) //还是没有用指定数据库
class UserRepositoryTest {
@Autowired //用于生成对象,有多少个对象就要在其上面写多少次
UserRepository repository;
@Test //测试文件自动生成的
@Commit //主要是不回滚,实际测试估计不用设置本项
void findByUsername() {
User2 user=new User2();
user.setUsername("libai");
user.setNickname("小白");
user.setPassword("123456");
user.setGender(Gender.MALE);
user.setEnabled(true);
user.setLocked(false);
user.setEmail("[email protected]");
user.setLast_login_ip("127.0.0.1");
user.setLast_login_time(new Date());
//存储到数据库,会返回user
User2 saveUser=repository.save(user);
System.out.println(saveUser.toString());
System.out.println("测试结束");
User2 result=repository.getByUsername("libai");
System.out.println("hello"+result.toString());
}
}
Process finished with exit code 0代表成功
点击左边下面的方法,可以过滤看到创建和查询结果
pom中引入了jpa
org.springframework.boot
spring-boot-starter-data-jpa
@DataJpaTest 会配置 Hibernate 为我们自动创建数据库模式。对此负责的属性是 spring.jpa.hibernate.ddl-auto,Spring Boot 默认将其设置为 create-drop,这意味着模式在运行测试之前创建并在测试执行后删除。
Spring Data Jpa的使用_^LiuYttt的博客-CSDN博客_springdatajpa的使用
hibernate在springboot中简单使用_薄荷味脑花的博客-CSDN博客_springboot hibernate
->需要在任何为空的前面加 @Autowired,
->如果有两行就要加两个
class UserRepositoryTest {
@Autowired //将类引入变量
UserRepository repository;//引入UserRepository,为了测试
@Test
void findByUsername() {
因为我们要测的是数据库,所以使用
为了测试 Spring Data JPA 存储库或任何其他与 JPA 相关的组件,Spring Boot 提供了 @DataJpaTest 注解。我们可以将它添加到单元测试中,它将设置一个 Spring 应用程序上下文:
@DataJpaTest
class UserRepositoryTest {
@Autowired
UserRepository repository;
@Test
void findByUsername() {
SpringBoot——单元测试之JUnit5_宋子浩的博客-CSDN博客_junit5测试springboot
Java测试框架-junit5详解_小测.的博客-CSDN博客_junit5
@SpringBootTest注解:添加在需要依赖springboot框架的测试类上,
不然不能使用Springboot的相关开发功能
@Test注解:添加在测试方法上
1)如果未设置属性,则Spring Boot将使用主DataSource或(如果存在)注释为@FlywayDataSource的DataSource配置Flyway。属性spring.flyway.url的存在是为了用一个具体的连接字符串覆盖这个选择过程。相关代码可以在类FlywayAutoConfiguration中找到。
在H2的特定情况下,重写连接字符串会导致这样一个问题,即H2数据库在事务之后不会保持打开状态,除非连接字符串包含指示它这样做的标志。这解释了问题中的观察结果,即Flyway运行的数据库随后关闭,然后Hibernate连接到一个干净的新H2实例。
在H2的特定情况下,重写连接字符串会导致这样一个问题,即H2数据库在事务之后不会保持打开状态,除非连接字符串包含指示它这样做的标志。这解释了问题中的观察结果,即Flyway运行的数据库随后关闭,然后Hibernate连接到一个干净的新H2实例。
这遵循了Spring Boot的通常模式及其auto-configuration的哲学。Auto-configuration旨在hands-off工作,并且仅由类路径上的事物触发。因此,对于其许多功能,无需属性或代码即可启用它们。
同时,Spring Boot只能对auto-configuration在何种情况下应配置的内容使用合理的默认值或启发式。因此,Spring Boot带有扩展点和标志,如果auto-configuration做得不对,可以轻松地退出。属性spring.flyway.url
是这些标志之一。
这个也很重要,在yml中的配置:
如果不配成create
jpa: hibernate: ddl-auto: create
ddl-auto:update----每次运行程序,没有表格会新建表格,表内有数据不会清空,只会更新
ddl-auto:validate----运行程序会校验数据与数据库的字段类型是否相同,不同会报错
ddl-auto:create----每次运行该程序,没有表格会新建表格,表内有数据会清空
ddl-auto:create-drop----每次程序结束的时候会清空表