框架个人总结
框架
一套规范。
实际是他人实现的一系列接口和类的集合。通入导入对应框架的jar文件(maven项目导入对应的依赖),进行适当的配置,就能使用其中的所有内容。
开发者可以省去很多模板代码,如dao中的CRUD,MVC模式下层与层之间的关联。只需要集中精力实现项目中的业务逻辑部分。
Java主流框架
Spring、SpringMVC、MyBatis、MyBatisPlus、Hibernate、JPA等。
Spring
概念
一个轻量级开源的Java框架。是一个管理项目中对象的容器,同时也是其他框架的粘合器,目的就是对项目进行解耦。
轻量级:对原有代码的侵入很小。
Spring的核心是IOC控制反转和AOP面向切面编程
组成
IOC
Inversion Of Control 控制反转
DI
Dependency Injection 依赖注入
spring核心容器
jdk8用5.x版本
<!-- spring-context表示spring核心容器 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.23</version>
</dependency>
属性自动注入autowire
以上所有案例中,如果要在A对象中注入一个引用类型的对象B,都是手动将对象B注入到对象A中。
如在Person中注入Car对象,在Cinema中注入Movie等。
这种情况下,如果当某个被注入的bean的id更改后,所有引用了该bean的地方都要进行修改。
所以将手动注入更改为自动注入(自动装配),就无需添加相应的<property>
标签,甚至可以无需定义bean的id。
autowire属性的值
-
byType
- 类中要有被注入的属性的setter()方法
- 被自动注入的对象可以没有id
- Spring容器中,某个对象的类型要与该setter()方法的参数类型一致,且容器中只有一个该类型的对象。
- 如setCar(Car c),Spring就会自动在容器中寻找类型为Car的对象自动装配
-
byName
- 类中要有被注入的属性的setter()方法
- 被自动注入的对象必须要有id
- 实际是根据setXXX()方法set后的单词XXX关联
- 如setCar(Car c),Spring就会自动在容器中寻找id为car的对象自动装配
在Web项目中,可以利用自动装配,在控制层中自动装配业务逻辑层的对象,在业务逻辑层中自动装配数据访问层的对象。
Spring核心注解
在Spring配置文件中加入
<!--设置要扫描的包,扫描这个包下所有使用了注解的类-->
<context:component-scan base-package="com.hqyj.spring02.bookSystem"></context:component-scan>
类上加的注解
- @Component
- 当一个类不好归纳时,定义为普通组件
- @Controller
- 定义一个类为控制层组件
- @Service
- 定义一个类为业务层组件
- @Repository
- 定义一个类为持久层(数组访问层)组件
- @Lazy/@Lazy(value=true)
- 设置该类为懒加载。
- @Scope(value=“singleton/prototype”)
- 设置为单例/原型模式。
说明
以上注解公共特点
- 都是将对应类的对象注入到Spring容器中,用于替换配置文件中的bean标签
- 都默认是单例模式非懒加载
- 默认注入的对象id为当前类的类名首字母小写形式
- 如在BookDao类上添加,id默认为bookDao
- 可以通过注解的value属性自定义注入的对象的id名,如@Component(value=“key”)表示注入的对象id为key
属性上加的注解
-
@Autowired
-
优先使用byType方式从Spring容器中获取对应类型的对象自动装配。先检索Spring容器中对应类型对象的数量,如果数量为0直接报错;数量为1直接装配
数量大于1,会再尝试使用byName方式获取对应id的对象,但要配合@Qualifier(value=“某个对象的id”)一起使用,指定id进行装配
-
-
@Qualifier(value=“某个对象的id”)
- 配合@Autowired注解,使用byName方式获取某个对象id的bean进行装配
-
@Resource(name=“某个对象的id”)
-
该注解相当于@Autowired+@Qualifier(value=“某个对象的id”)
-
优先使用byName方式,从Spring容器中检索name为指定名的对象进行装配,如果没有则尝试使用byType方式,要求对象有且只有一个,否则也会报错。
-
说明
-
如果要在某个类中使用Spring容器中的某个对象时,只需定义成员变量,无需创建对象,通过@Autowired或@Resource注解进行自动装配
-
实际开发中,绝大部分情况下,需要自动装配对象有且只有一个,并且命名规范,所以@Autowired或@Resource区别不是很大。@Autowired优先使用byType方式,@Resource优先使用byName方式
-
如果@Resource不能使用,是因为缺少javax.annotation包,需要引入对应依赖
<dependency> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> <version>1.3.2</version> </dependency>
AOP
概念
Process Oriented Programming 面向过程编程POP
Object Oriented Programming 面向对象编程OOP
Aspect Oriented Programming 面向切面编程AOP
以上都是编程思想,但AOP不是OOP和POP的替代,而是增强、拓展和延伸。主流编程思想依然是OOP。
作用
在传统的OOP思想中,我们将程序分解为不同层次的对象,通过封装、继承、多态等特性,
将对象组织成一个整体来完成功能。但在某些场景下,OOP会暴露出一些问题。
如在处理业务中,除了核心的业务代码外,通常还会添加一些如果参数验证、异常处理、事务、记录日志等操作。
这些内容会分散在各个业务逻辑中,依旧会出现大量重复操作。如果将这些重复的代码提取出来,在程序编译运行时,
再将提出来的内容应用到需要执行的地方,就可以减少很多代码量。方便统一管理,更专注于核心业务。
简单来说,就是将不同位置中重复出现的一些事情拦截到一处进行统一处理。
在SpringMVC中,让某个控制层中的方法返回JSON格式的数据
-
添加依赖
<!--jackson:将数据转换为JSON格式--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.14.2</version> </dependency>
-
@ResponseBody注解
该注解可以加在类或方法上
- 如果加在方法上,表示该方法的返回值类型为JSON格式
- 如果加在类上,表示该类中的所有方法的返回值类型为JSON格式
package com.hqyj.ssm02.controller; import com.hqyj.ssm02.entity.BookType; import com.hqyj.ssm02.service.BookTypeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import java.util.List; @Controller @RequestMapping("/bookType") public class BookTypeController { @Autowired private BookTypeService bookTypeService; //如果controller的某个方法返回一个JSON字符串,需要使用@ResponseBody @RequestMapping("/queryAllToJson") @ResponseBody//表示该方法无论返回值是什么,都返回JSON格式字符串 public List<BookType> queryAllToJson(){ List<BookType> list = bookTypeService.queryAll(); return list; } }
SSM项目中使用Ajax
ajax依赖于jquery,所以先保证页面中存在jquery.js。
$.ajax({
url:"访问地址",
data:{
"提交的参数名":"实际值",
"提交的参数名":"实际值"
},
type:"get/post",
success:function(res){
//成功后的回调函数,res为访问后的结果,必须是json格式
}
});
在前端页面中使用ajax访问controller时,controller的返回值必须是一个JSON格式的字符串。
所以controller中的方法上要加入@ResponseBody注解
拦截器
每次请求controller时,都要经过的一个类。
当一个项目中有过滤器、拦截器和controller时的执行流程
实现过程
1.导入servlet依赖
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
2.自定义一个类,实现拦截器HandlerInterceptor接口
其中有三个default方法可以重写
- preHandle
- 在发送请求后,DispatcherServlet解析控制器中某个RequestMapping之前执行的方法
- 该方法返回true时,请求才能继续
- postHandle
- 在preHandle方法返回值为true后执行
- 在DispatcherServlet解析控制器中某个RequestMapping之后执行
- afterCompletion
- 在preHandle方法返回true后执行
- 在解析视图后执行的方法
这里只需重写preHandle方法即可
package com.hqyj.ssm02.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*
* 自定义拦截器,用户拦截未登录时的请求
* */
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String requestURI = request.getRequestURI();
//登录成功后,会在session中保存一个名为sysAdmin的对象
Object sysAdmin = request.getSession().getAttribute("sysAdmin");
//如果有对象,说明登录成功,可以放行return true
if(sysAdmin!=null){
return true;
}else{
response.sendRedirect(request.getContextPath()+"/login");
}
System.out.println(requestURI+"试图访问,拦截成功");
return false;
}
}
3.在springmvc.xml中配置拦截器
<!--配置拦截器们-->
<mvc:interceptors>
<!--配置某个拦截器-->
<mvc:interceptor>
<!--设置要拦截的请求,这里的/**表示拦截一切请求-->
<mvc:mapping path="/**"/>
<!--设置不拦截的请求-->
<!--放行登录和注册页-->
<mvc:exclude-mapping path="/login"/>
<mvc:exclude-mapping path="/register"/>
<!--放行静态资源-->
<mvc:exclude-mapping path="/static/**"/>
<!--放行用户模块-->
<mvc:exclude-mapping path="/sysAdmin/**"/>
<!--注入指定的拦截器-->
<bean class="com.hqyj.ssm02.interceptor.MyInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
单元测试
1.导入依赖
如果只在普通的Maven项目中使用,只需导入该依赖
<!--单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
如果要在Spring环境下使用,还需
<!--spring集成JUnit-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.23</version>
<scope>test</scope>
</dependency>
2.创建单元测试类所在目录
在项目的src目录下新建test目录,会自动在其中创建java目录
3.使用
- 在test/java目录下,新建一个类
- 在类上加入
- @ContextConfiguration(“classpath:application.xml”)
- @RunWith(SpringJUnit4ClassRunner.class)
- 在类中创建公开的无返回值的无参数方法,加入@Test注解
- 在该方法上右键运行,运行的是当前方法,在类中空白处右键运行,运行的是当前类中的所有方法。
import com.hqyj.ssm02.dao.BookInfoDao;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
//解析Spring配置文件
@ContextConfiguration("classpath:application.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class Test {
/*
* 单元测试的方法必须是无参数无返回值的公共方法
* */
@org.junit.Test
public void fun(){
System.out.println("单元测试");
}
@Autowired
private BookInfoDao bookInfoDao;
@org.junit.Test
public void test1(){
System.out.println(bookInfoDao.queryAll());
}
}
SpringBoot+MyBatis实现单表查询
1.创建好SpringBoot项目
最好在创建的时候选择以下依赖
- spring-web(必选)
- lombok
- spring-devtools
- springboot集成mybatis
- mysql驱动
都可以后续添加
<!--web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>2.7.8</version>
</dependency>
<!--Lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
2.在pom.xml中添加mybatis集成SpringBoot依赖和数据库驱动
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.31</version>
</dependency>
<!--springboot集成MyBatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.3.0</version>
</dependency>
3.在springboot配置文件application.properties中
#注释
#.properties文件称为属性文件,数据以键值对"键=值"的形式保存
#设置项目启动端口号
#server.port=9090
#设置项目上下文路径
#server.servlet.context-path=/springbootday1
#mybatis相关配置
#开启驼峰命名映射
mybatis.configuration.map-underscore-to-camel-case=true
#打印sql语句
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#扫描mybatis的sql映射文件(将mapper.xml文件保存在resources目录下的mapper目录下)
mybatis.mapper-locations=classpath:mapper/*.xml
#数据库信息
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/gamedb?serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root
mybatis的sql映射文件模板
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--设置该文件对应的dao层接口全限定名-->
<mapper namespace="">
</mapper>
4.根据数据表创建实体类、dao层接口、service、controller
Hero
@Data
public class Hero{
private Integer id;
private String name;
private String position;
private String sex;
private Double price;
private String shelfDate;
}
dao
@Repository
public interface HeroDao{
List<Hero> queryAll();
}
mapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--设置该文件对应的dao层接口全限定名-->
<mapper namespace="com.xxx.dao.HeroDao">
<select id="queryAll" resultType="com.xxx.entity.Hero">
select * from hero
</select>
</mapper>
service
@Service
public class HeroService{
@Autowired
private HeroDao heroDao;
public List<Hero> queryAll(){
return heroDao.queryAll();
}
}
controller
@Controller
@RequestMapping("/hero")
public class HeroController{
@Autowired
private HeroService heroService;
@RequestMapping("/queryAll")
@ResponseBody
public List<Hero> queryAll(){
return heroDao.queryAll();
}
}
5.在SpringBoot的启动类上,加入@MapperScan注解,扫描dao层所在根包
@SpringBootApplication
//扫描dao层所在的根包
@MapperScan("com.hqyj.first.dao")
public class FirstApplication {
public static void main(String[] args) {
SpringApplication.run(FirstApplication.class, args);
}
}
启动项目,按自定的项目上下文路径和端口号访问某个controller中的方法
MyBatisPlus
官网简介 | MyBatis-Plus (baomidou.com)
MyBatis-Plus (简称 MP)是一个MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
只需简单的配置,就能实现对单表的CURD。
其核心有两个接口:BaseMapper和IService
BaseMapper中封装了大量数据访问层的方法
IServcie中封装了大量业务流程层的方法
SpringBoot+MyBatisPlus
1.创建SpringBoot项目
创建时勾选依赖
- devtools
- lombok
- spring-web
- mysql-driver
2.导入SpringBoot集成MyBatisPlus依赖
<!-- SpringBoot集成MyBatisPlus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
3.配置application.properties文件
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/gamedb?serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root
# 开启sql日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# 无需加入开启驼峰命名映射,MyBatisPlus默认使用驼峰命名进行属性-字段映射
#mybatis-plus.configuration.map-underscore-to-camel-case=true
4.根据数据表创建实体类
实体类的属性名命名方式:
- MyBatisPlus默认使用驼峰命名对字段和属性进行映射。如将字段stu_name对应的属性写为stuName
- 如果字段名和属性名不一致,在属性名上加入**@TableField(value = “字段名”)**
- 主键字段对应的属性,需要加入@TableId注解,其type属性表示主键生成策略
- @TableId(type = IdType.AUTO)表示主键自增,在数据库也要将主键设置为自增
- @TableId(type = IdType.ASSIGN_ID)//IdType.ASSIGN_ID表示使用"雪花算法"(根据时间和机器特征码)生成一个id
- @TableId(type = IdType.ASSIGN_UUID)//IdType.ASSIGN_UUID表示使用UUID生成一个随机字符串id
@Data
public class Hero {
//type表示主键生成策略,
@TableId(type = IdType.AUTO)// IdType.AUTO表示主键自增,在数据库也要将主键设置为自增
//@TableId(type = IdType.ASSIGN_ID)//IdType.ASSIGN_ID表示使用"雪花算法"(根据时间和机器特征码)生成一个id
//@TableId(type = IdType.ASSIGN_UUID)//IdType.ASSIGN_UUID表示使用UUID生成一个随机字符串id
private Integer id;
//如果属性名和字段名不一致
@TableField(value = "name")
private String heroName;
private String position;
private String sex;
private Integer price;
private String shelfDate;
}
5.编写数据访问层接口
可以不用写@Repository,继承BaseMapper接口,设置泛型
/*
* 数据访问层可以称为dao或mapper层
* 可以不用加@Repository注解
* */
public interface HeroMapper extends BaseMapper<Hero> {
}
6.在SpringBoot的启动类中,扫描数据访问层所在包
@SpringBootApplication
@MapperScan("com.hqyj.sbmp01.mapper")
public class Sbmp01Application {
public static void main(String[] args) {
SpringApplication.run(Sbmp01Application.class, args);
}
}
测试
在SpringBoot自带的单元测试类中,注入HeroMapper对象,调用BaseMapper中定义的方法即可实现CURD。
Thymeleaf
SpringBoot官方建议使用的页面模板引擎,代替之前的JSP。
它是以HTML为基础,可以展示静态数据,方便前端人员开发静态页面,
也可以通过Thymeleaf的语法,配合EL输出由控制器跳转而来的动态数据。
Thymeleaf从入门到精通 - 知乎 (zhihu.com)
用法
1.添加依赖
<!--thymeleaf页面模板引擎-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.7.3</version>
</dependency>
2.在temlates目录下创建一个HTML页面
在页面的HTML标签中,加入xmlns:th="http://www.thymeleaf.org"
属性。
可以通过修改IDEA中的HTML页面模板,之后每次创建HTML页面都会有该属性
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wmyL6tnf-1676452011143)(day14-SpringBoot+MyBatisPlus2.assets/image-20230209143658152.png)]
3.thymeleaf具体使用
-
双标签中的输出变量: th:text
<h1 th:text="${作用域中某个对象名}"></h1> <h1 th:text="${username}"></h1>
-
单标签中设置value的值:th:value
<input type="text" th:value="${作用域中某个对象名}"> <input type="text" th:value="${变量.属性名}">
-
遍历:th:each
<table> <tr th:each="变量:${作用域中的集合名}"> <td th:text="${变量.属性名}"></td> </tr> </table> <table> <tr th:each="hero:${heroList}"> <td th:text="${hero.id}"></td> <td th:text="${hero.name}"></td> <td th:text="${hero.sex}"></td> </tr> </table>
-
超链接获取全局路径:th:href=“@{/}”
-
不带参数
<link th:href="@{/bootstrap-3.4.1-dist/css/bootstrap.css}" rel="stylesheet">
-
带参数
<a th:href="@{'/hero/delete?id='+${hero.id}">删除</a> <a th:href="@{/question/findById(id=${question.quesCode})}">编辑</a>
-
-
表单提交路径:th:action=“@{/}”
<form methos="post" th:action="@{/hero/insert}"> </form>
-
判断:th:if
<h1 th:if="判断逻辑">用户信息</h1> <h1 th:if="${userinfo.username==null}">请登录</h1>
-
选中单选按钮或复选框:th:checked
<input type="radio" value="男" name="sex" th:checked="逻辑判断"> <input type="radio" value="男" name="sex" th:checked="${user.sex=='男'}">男 <input type="radio" value="女" name="sex" th:checked="${user.sex eq '女'}">女
-
选中下拉菜单:th:selected
<select> <option th:selected="逻辑判断"></option> </select> <select> <option th:selected="${book.typeId==bookType.typeId}" th:each="bookType:${list}" th:value="${bookType.typeId}" th:text="${bookType.typeName}"></option> </select>
-
src属性:th:src
<script th:src="@{/bootstrap-3.4.1-dist/js/jquery-3.6.2.min.js}"></script>
-
内联表达式
Thymeleaf页面中使用[[]]可以在script标签中使用EL表达式,这两对中括号拼接的内容称为内联表达式。
在给script标签加入**th:inline=“javascript”**后使用
<script th:inline="javascript"> $(function () { //遍历页码 $(".pno").each(function (){ //如果页码和当前页一致,高亮显示 if($(this).text()==[[${pageInfo.current}]]){ $(this).addClass("active"); } }); }); </script> <script th:inline="javascript"> $(function () { //使用ajax读取所有的题目类型对象,遍历成option $.ajax({ url:[[@{/qc/queryAll}]], success:function (res){ for(var i=0;i<res.length;i++){ let qcId = res[i].qcId; let qcName = res[i].qcName; $("<option></option>").text(qcName).val(qcId).appendTo($("select[name=qcId]")); } } }); }); </script>
Spring Data JPA
2001年推出了Hibernate,是一个全自动ORM框架。可以不用编写SQL语句,就能实现对数据库的持久化操作。
SUN公司在Hibernate的基础上,制定了JPA,全称 Java Persisitence API,中文名Java持久化API,
是一套Java访问数据库的规范,由一系列接口和抽象类构成。
后来Spring团队在SUN公司制定的JPA这套规范下,推出了Spring Data JPA,是JPA的具体实现。
如今常说的JPA,通常指Spring Data JPA。
SpringBoot集成Spring Data JPA
1.创建SpringBoot项目,选择依赖
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lmXLgjjF-1676452095246)(day16-SpringBoot+JPA.assets/image-20230213141450488.png)]
2.编辑配置文件,设置要连接的数据库信息
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/bookdb?serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root
# 设置数据库类型
spring.jpa.database=mysql
# 打印SQL语句
spring.jpa.show-sql=true
3.创建实体类
-
类上加**@Entity**注解
-
主键属性上加
-
@Id注解标明主键
-
**@GeneratedValue(strategy = GenerationType.IDENTITY)**设置MySQL数据库主键生成策略,数据库设置为自增
-
-
其他属性名与字段名一致或驼峰命名法
- 如果字段名多个单词之间用_,使用驼峰命名法
- 如果不相同,使用**@Column(name=“字段名”)**注解指定该属性对应的字段名
@Data
@Entity
/*
* 实体类的属性名建议使用驼峰命名法
* */
public class BookInfo {
@Id//主键字段
//主键生成策略,GenerationType.IDENTITY表示MySQL自增
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer bookId;
private Integer typeId;
private String bookName;
private String bookAuthor;
//如果字段名和属性名不一致,使用@Column指定字段名
@Column(name = "book_price")
private Integer price;
private Integer bookNum;
private String publisher_date;
}
4.数据访问层接口
- 类上加@Repository注解
- 继承JpaRepository<实体类型,主键类型>接口
@Repository
public interface BookInfoDao extends JpaRepository<BookInfo,Integer> {
}
5.测试常用方法
方法名 | 返回值 | 作用 |
---|---|---|
findAll() | List | 查询所有数据。 |
save(T entity) | T entity | 添加或修改。如果不存在主键属性或主键值不存在,执行添加;如果存在主键属性且有该主键值,执行修改。 |
delete(T entity) | void | 根据对象删除。如果该对象中有主键属性且有该主键值,根据该主键值删除。 |
findById(主键) | Optional | 根据主键值查询。返回的对象调用isPresent()结果为true,表示查询到了数据,继续调用get()得到查询到的对象。 |
@SpringBootTest
class Day16SpringBootJpaApplicationTests {
@Autowired
private BookInfoDao bookInfoDao;
@Test
void contextLoads() {
List<BookInfo> all = bookInfoDao.findAll();
all.forEach(System.out::println);
}
@Test
void insert() {
BookInfo bookInfo = new BookInfo();
bookInfo.setBookName("测试");
bookInfo.setBookAuthor("测试");
bookInfo.setBookNum(156);
bookInfo.setPrice(20);
bookInfo.setTypeId(1);
//save()方法调用时,如果对象中没有主键或主键值不存在,作为添加使用
BookInfo save = bookInfoDao.save(bookInfo);
//添加成功后,会自动获取主键自增的值
System.out.println(save);
}
@Test
void update() {
BookInfo bookInfo = new BookInfo();
bookInfo.setBookName("xxxxxxxxxxx");
bookInfo.setBookAuthor("测试");
bookInfo.setBookNum(356);
bookInfo.setPrice(23);
bookInfo.setTypeId(1);
//save()方法调用时,如果对象中有主键且存在,作为修改使用
BookInfo save = bookInfoDao.save(bookInfo);
//修改成功后,返回修改后的对象
System.out.println(save);
}
@Test
void delete() {
//根据主键值删除,如果值不存在,会报错
//bookInfoDao.deleteById(36);
//根据对象删除,如果对象中包含主键值则删除,如果没有值或不存在,不会报错
BookInfo bookInfo = new BookInfo();
//bookInfo.setBookId(330);
bookInfoDao.delete(bookInfo);
}
@Test
void findOne() {
//根据主键查询,返回值Optional类型
Optional<BookInfo> byId = bookInfoDao.findById(60);
//isPresent()如果为true表示查询到了数据
if (byId.isPresent()) {
//get()将查询到的数据转换为对应的实体类
BookInfo bookInfo=byId.get();
System.out.println(bookInfo);
}else{
System.out.println("未查询到数据");
}
}
}