华清远见-重庆中心-框架阶段个人总结

框架

一套规范。

实际是他人实现的一系列接口和类的集合。通入导入对应框架的jar文件(maven项目导入对应的依赖),进行适当的配置,就能使用其中的所有内容。

开发者可以省去很多模板代码,如dao中的CRUD,MVC模式下层与层之间的关联。只需要集中精力实现项目中的业务逻辑部分。

Java主流框架

Spring、SpringMVC、MyBatis、MyBatisPlus、Hibernate、JPA等。

Spring

概念

一个轻量级开源的Java框架。是一个管理项目中对象的容器,同时也是其他框架的粘合器,目的就是对项目进行解耦。

轻量级:对原有代码的侵入很小。

img

Spring的核心是IOC控制反转和AOP面向切面编程

组成

img

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("未查询到数据");
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值