1
0
mirror of https://gitee.com/coder-xiaomo/java-note synced 2025-01-10 19:48:15 +08:00
Code Issues Projects Releases Wiki Activity GitHub Gitee
java-note/张博凯的Java学习笔记.md
2022-01-23 17:23:09 +08:00

127 KiB
Raw Blame History

Java

Java技术体系

1. Java基础
   变量 选择结构(if) 循环结构(for) 数组
   ============================================================================
2. Java面向对象
   类  方法  属性  对象
   创建类的语法:
   访问修饰符(public/private) class 类名{
   		// 类名首字母大写
   }
   创建方法的语法:
   访问修饰符  返回值类型(void/基本数据类型/对象/集合) 方法名称(有参/无参){
   
   }
   类中包含的内容: a.属性  b.方法
   对象创建的语法: 类名 对象名=new 类名();
   字符串的常用方法 
   ============================================================================
3. Java高级部分
Java面向对象的三大特性 
a. 封装: (1).属性私有化  (2).生成get和set方法
b. 继承: Java支持单根继承   extends   好处: 父类有的,子类完全可以使用
c. 多态: 子类指向父类对象  
d. 接口: interface  接口用法: (1)接口中所有的方法都是抽象方法  (2) 方法没有方法体 3方法重写implements
e. IO流 InputStream   OutputStream
f. 线程: 
h. 集合: List集合 set集合 Map集合  size()
泛型集合: 存储有相同类型的数据
==============================Java控制台项目================================
4. Javaweb
a. JDBCjava连接数据库的技术
b. Servlet 后端与前端进行数据交互和页面传递   servlet中跳转页面方法转发 重定向)
c. JSP 动态网页html代码+java代码  ?  <%%>
d. HTML5静态网页
e. css: 页面样式 
f. javaScript: 
g. JavaQuery 封装js
h. layui 前端框架  vue.js  elementUI
i. 数据库Sqlserver  mysql  oracle 关系型数据库    非关系型数据库redis
===============================Javaweb项目(前端+后端)======================
5. 企业级框架SSM
MyBatis框架 数据访问(操作数据库)====JDBC角色
Spring框架 胶水框架(主要跟其他框架组合) Spring全家桶Springmvc springboot springcloud
SpringMVC框架 web框架 =============Servlet角色
Thymeleaf模板引擎
=============================Javaweb企业级项目(前端+后端)=====================
6.前后端分离
a.springboot  + vue  
7.微服务:
springcloud+ES+Redis  =====架构师

Java基础、高级控制台项目

新建类

image-20220116152649260

(可以和包一起建)

org.example.entity.Userorg.example.pojo.User

类名首字母大写;包名首字母小写

image-20220116153103336

创建main方法

main + <回车>

image-20220116153728996

image-20220116153844861

新建接口

image-20220116153417709

接口没有方法体不可以new对象

实现接口

UserDao

image-20220116154126155

image-20220116154238246

image-20220116154415712

image-20220116154448653

集合与数组

/*
 * 数组:存储相同数据类型的一组数据
 * 集合:可以存储不同数据类型的数据
 * 泛型集合:存储有相同类型的数据
 */

// 集合
List list = new List();
list.add("aa");
list.add(1);
list.add(new Person());
list.add(2.34);

// 泛型集合
List<String> a = new ArrayList<String>();

导入依赖

传统jar包
  1. 下载jar包

  2. 将下载的jar包拷贝到项目中

    web项目放在web中

  3. 选择jar文件右键 Add as Library

存在的问题

  1. 步骤多(相对)
  2. 在不同项目中如果需要使用同一jar包需要分别存储这个jar文件导致项目体积大
  3. 在不同的环境下可能因为jar版本不一致导致项目无法运行
Maven导入依赖

Maven是一个基于项目对象模型(pom)用于进行项目的依赖管理的工具软件

核心功能
  1. 依赖聚合

  2. 聚合工程

    javaweb三层架构Dao层、Service层 Servlet jsp (可以每一层放在一工程里面)

官网

Maven官网https://maven.apache.org/

image-20220117103539600

安装和配置

1. 安装及目录介绍

下载:https://maven.apache.org/download.cgi

tar.gz是linux下的zip是windows下的

注意Maven使用前JDK需要先安装配置好

  • 解压

  • 目录结构

    • bin目录存储指令文件Maven提供了一个mvn指令

    • boot目录包含了一个类加载框架的jar文件

    • conf目录

      • settings.xml核心配置文件

        • 配置本地存储库 <localRepository></localRepository>

          image-20220117114331099

        • 配置镜像

          <mirrors>
              <mirror>
                  <id>aliyunmaven</id>
                  <mirrorOf>*</mirrorOf>
                  <name>阿里云公共仓库</name>
                  <url>https://maven.aliyun.com/repository/public</url>
              </mirror>
          </mirrors>
          
    • lib目录存放了Maven运行所需的jar文件

2. 配置环境变量

环境变量 说明
MAVEN_HOME 压缩包解压出来的地址,例如:D:\Program\Java\apache-maven-3.6.3
PATH %MAVEN_HOME%\bin

3. 测试

mvn -versionmvn -version

image-20220117105823106

4. 依赖管理流程

Maven.drawio

本地仓库:就是本地计算机上的某个文件夹(可以自定义的任何文件夹)

远程仓库就是远程主机上的jar文件仓库

Java项目打包三种方式

  1. pomMaven项目
  2. jarJava普通项目
  3. warJavaweb项目

IntelliJ IDEA开发

配置

主题配置

Settings > Appearance & Behavior > Appearance

image-20220116150937119

编码设置

Settings > Editor > File Encodings

改成UTF-8

image-20220116150815030

设置IDEA启动时不自动打开上次打开的项目

Settings > Appearance & Behavior > System Settings

image-20220118002219620

查看JDK版本

java -version

image-20220116151812896

配置idea中的JDK

File > Project Structure

image-20220116161629613

image-20220116161555885

配置idea中的Maven

Settings > Build, Execution, Deployment > Build Tools > Maven

image-20220117142419973

IDEA创建自定义模板

点击文档内跳转

快捷键

有些快捷键在其他部分顺带提到了,这里仅写其他部分没有提到的快捷键

  • main+回车 创建main方法

        public static void main(String[] args) {
    
        }
    
  • xxxx.var+回车 生成赋值语句

    "apple".var
    // 👇
    String apple = "apple";
    
  • sout+回车 输出语句

    System.out.println();
    
  • Alt+Enter 添加try catch ...

  • Alt+Insert 生成构造器、Getter and Setter等

    image-20220118005611780

创建项目

创建简单Java项目控制台项目

image-20220116152139474

不使用模板直接Next

image-20220116152438232

设置项目名称和路径,点击完成

image-20220116152545188

创建Javaweb项目

2021.3与2019版本不同

2021.3版本idea

参考了:https://blog.csdn.net/znufe_newer/article/details/113115002

2021.3版本不是选左边的Java Enterprise而是选Java

image-20220116163216848

image-20220116163237365

image-20220116163251053image-20220116163341532

image-20220116163519894

2019版本idea

步骤如下

图中要勾上Create web.xml

image-20220116163623140

image-20220116163649763

创建普通Maven项目控制台项目

image-20220117142625153

image-20220117142728008

项目目录介绍

image-20220117145353469

src/main/java		# Java后端代码
src/main/resources	# 配置文件
src/test/java
pom.xml				# Maven依赖
Maven的pom.xml配置

**artifactId配置中不可以有中文**artifictid的正则表达式为[A-Za-z0-9_\-.]

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion><!-- 版本 -->

    <groupId>org.example</groupId><!-- 包名 -->
    <artifactId>maven_project</artifactId><!-- 项目名(不可以是中文) -->
    <version>1.0-SNAPSHOT</version><!-- 版本 -->

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
		<!-- 项目依赖 -->
    </dependencies>

</project>

<dependencies></dependencies> 标签中添加依赖(如果需要的话),依赖可以在 https://mvnrepository.com/ 这个网站上找到

image-20220117143830281

依赖添加后需要点击图中 Load Maven Changes 按钮

image-20220117144038244

如果没有的话可以右键 Maven > Reload Project

image-20220118110133670

创建Mavenweb项目

有两种方式

  1. 创建项目时选择Maven勾上Create from archtype

    不建议使用这种方式,因为会生成很多依赖和没有用的东西在项目中

    image-20220118002503343

  2. 手动操作(见下方步骤)

image-20220118002605490

image-20220118002804532

配置打包方式war包

pom.xml中添加 <packaging>war</packaging> ,如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>mavenweb项目</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

</project>

添加 web.xml 文件

image-20220118003605867

image-20220118003711365

WEB-INF 前添加 src\main\webapp\

image-20220118003805398

删除 Web Resource Directory 重新加载

image-20220118004012885

image-20220118004227647

即可

image-20220118004559833

创建SpringIOC Maven项目

创建项目

image-20220118002605490 image-20220119185937940

添加依赖
添加Spring依赖

core(核心依赖)、beans(组件)、aop(AOP处理)、context(context组件)

Spring Context

https://mvnrepository.com/artifact/org.springframework/spring-context/5.2.19.RELEASE

 <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
 <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-context</artifactId>
     <version>5.2.19.RELEASE</version>
 </dependency>

导入Spring Context依赖相当于同时导入了 pring-aop,spring-beans,spring-core,spring-expression 依赖,所以只需要导入Spring Context即可

image-20220119201948073

添加lombok依赖

传送门

创建Spring核心配置文件

Spring核心配置文件“告诉Spring容器创建什么对象”给对象属性赋什么值

在resources目录下创建applicationContext.xml文件备注名称可以自定义但是建议一般使用applicationContext.xml

image-20220119213008054

第一次需要新建模板,如图

image-20220119212825415

src/main/resources/applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    
</beans>

image-20220119215150497

image-20220119215211686

创建SpringMVC Maven web项目

image-20220118002605490

image-20220120143744218

Mavenweb配置

参照创建Mavenweb项目将项目配置为Mavenweb项目

idea与Tomcat集成

image-20220120152419754

image-20220120153146124

4自定义名称

5Tomcat本地路径

6选择浏览器

7默认访问的路径

8JDK

再次编辑 Run/Debug Configuration

image-20220120153712846

image-20220120153639117

选择第1个或者第2个都行

image-20220120153830065

/ 表示从根目录启动

项目结构

image-20220120154144701

  • java后端代码
  • resources配置文件
  • webapp静态资源html, css, 图片等)
启动

在 webapp 目录下创建 index.jsp ,然后运行就可以看到了。

Tomcat控制台输出乱码解决方案

image-20220120155801302

在这两个地方添加下方配置

-Dfile.encoding=UTF-8
  1. idea

    image-20220120160009256

image-20220120160041194

  1. tomcat

    image-20220120160127852

添加完后重启idea即可

接下来,配置SpringMVC

连接数据库

IDEA连接MySQL

image-20220116172510338

image-20220116172545108

注意:

image-20220116172803614

填写用户名&密码

image-20220116172859540

连接之后默认值会显示一个数据库

image-20220117100543999

选择其他数据库

image-20220117100636687

image-20220117100732206

Java、Javaweb

Lombok

Lombok是简化javabean实体类可以使用注解简化代码

导入依赖

https://mvnrepository.com/artifact/org.projectlombok/lombok

<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.22</version>
    <scope>provided</scope>
</dependency>

IDEA中使用

IDEA中使用必须安装lombok插件才可以生效

image-20220118005337949

常用注解

  1. @Data

    相当于实体类封装的get和set方法

  2. @Setter

    相当于实体类封装的set方法

  3. @Getter

    相当于实体类封装的get方法

  4. @NoArgsConstructor

    相当于无参构造函数

  5. @AllArgsConstructor

    相当于有参构造函数

JDBC以MySQL为例

Java连接数据库的技术

导入MySQL依赖包

从网上下载MySQL的jar包https://mvnrepository.com/artifact/mysql/mysql-connector-java

MySQL 5.x版本导入5.1.x版本jar包8.x版本导入8.0.x版本jar包

image-20220116164807251

下载后放入项目web/lib文件夹下

image-20220116164942847

添加jar包

image-20220116165411807

创建User.java并编写Java代码

全限定名com.mysql.jdbc.Driver是这样复制出来的

image-20220116165755225

image-20220116165818350

package org.exmple.entity;

import java.sql.*;

/**
 * JDBC链接数据库的操作
 */
public class UserJdbc {
    public static void main(String[] args) {
        // 1. 加载驱动全限定名com.mysql.jdbc.Driver是复制进来的也可以一个一个 . 出来)
        try { // 2. Alt + Enter 抛出异常
            Class.forName("com.mysql.jdbc.Driver");

            // 3. 创建连接对象Connection是java.sql下的
            Connection connection= DriverManager.getConnection("jdbc:mysql://localhost:3306/dormitory","root","111111");
            // 4. Alt + Enter 抛出异常

            // 5. 写SQL语句
            String sql = "select * from d_student";

            // 6. 创建对象 PreparedStatement
            PreparedStatement preparedStatement = connection.prepareStatement(sql);

            // 7. 执行命令
            ResultSet resultSet = preparedStatement.executeQuery();

            // 8. 循环遍历
            while (resultSet.next()){
                System.out.println(resultSet.getInt("s_id")+"\t"+resultSet.getString("s_name"));
            }

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

执行结果

image-20220117101802262

Maven

从网上下载MySQL的jar包https://mvnrepository.com/artifact/mysql/mysql-connector-java

MySQL 5.x版本选择5.1.x版本8.x版本选择.0.x版本

下面以MySQL 5.7版本为例:

image-20220117143510876

image-20220117143541787

<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.49</version>
</dependency>

Tomcat

配置Tomcat服务器

Tomcat官网https://tomcat.apache.org/

下载:https://tomcat.apache.org/download-90.cgi

image-20220120144746154

目录结构

bin启动或停止Tomcat服务器

conf核心配置文件可以修改端口号等信息

lib所需的jar文件

logs日志信息

temp

webapps项目部署

work

image-20220120144935976

启动
Windows Linux
启动服务 bin/startup.cmd bin/startup.sh
停止服务 bin/shutdown.cmd bin/shutdown.sh
Tomcat核心文件讲解

conf/server.xml 配置或修改端口号(建议添加 URIEncoding="utf-8"

    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" URIEncoding="utf-8" />

idea与Tomcat集成

idea与tomcat集成

Servlet

后端与前端进行数据交互和页面传递

跳转页面的方式

  • forward 转发
  • redirect 重定向

JSP

动态网页

JSP中Java代码需要用 <% %> 包起来

Thymeleaf

模板引擎

HTML5

静态网页

CSS

页面样式

JavaScript

JavaQueryjQuery

前端框架

Layui

Vue.js

elementUI

数据库

关系型数据库

SQL Server

MySQL

Oracle

非关系型数据库

redis

企业级框架SSM

框架:框架,就是软件的半成品,完成了软件开发过程中的通用操作,程序员只需很少或者不用进行加工就能实现特定的功能,从而简化开发人员在开发过程中的开发步骤,提高开发效率。

常用框架

  • MVC框架简化了Servlet的开发步骤
    • struts
    • struts2
    • SpringMVC
  • 持久层框架:完成数据库操作的框架
    • Apache DBUtils
    • Hibernate
    • MyBatis
  • 胶水框架Spring

SSMSpring SpringMVC MyBatis

SSHSpring Structs2 Hibernate

MyBatis框架

数据访问操作数据库JDBC角色

MyBatis是一个半自动的ORM框架

ORMObject Relational Mapping对象关系映射将Java中的一个对象与数据表中的一行记录一一对应。表映射为类类名一般是表名首字母大写类中的属性就是表中的字段名

ORM框架提供了实体类与数据表的映射关系通过映射文件的配置实现对象的持久化

MyBatis的前身是iBatis是Apache提供 的一个开源项目

对JDBC进行了封装几乎消除了所有的JDBC代码

支持xml和注解配置方式完成ORM操作

官网:https://mybatis.org/mybatis-3/

MyBatis框架部署及CRUD

MyBatis操作数据库进行增加、删除、修改、查询操作

首先创建Maven项目Maven普通或Mavenweb

添加mybatis依赖目前官网最新版是3.5.9

https://mvnrepository.com/artifact/org.mybatis/mybatis

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.9</version>
</dependency>

同时还需要添加

创建MyBatis配置文件

在resources目录下创建mybatis-config.xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
</configuration>
IDEA创建自定义模板

image-20220118103532515

Name: mybatis-config

Extension: xml

File Name: mybatis-config.xml

勾选 Enable Live Templates 激活当前模板

模板代码👇

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    
</configuration>

出现如图问题解决方案

image-20220118104342493

image-20220118104541497

在mybatis-config.xml中进行数据库连接信息配置

environments标签中可以定义多个environment每个environment标签可以定义一套连接配置default属性用来指定使用哪个environment标签

transactionManager标签用于配置数据库管理方式默认是JDBC

dataSource标签用于配置数据库的连接信息

配置模板idea中Maven配置好后输入 <en 回车即可自动补全)

<configuration>
    <environments default="">
        <environment id="">
            <transactionManager type=""></transactionManager>
            <dataSource type=""></dataSource>
        </environment>
    </environments>
</configuration>

配置信息

<configuration>
    <environments default="mysql">
        <environment id="mysql">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
                <property name="username" value="root"/>
                <property name="password" value="111111"/>
            </dataSource>
        </environment>
    </environments>
</configuration>

还可以将数据库密码写在配置文件中避免直接将数据库配置信息写在mybatis-config.xml文件中传送门

如果出现了中文乱码在jdbc:mysql://localhost:3306/mydb后面添加 characterEncoding=utf-8

MyBatis框架使用

案例:学生信息的数据库操作

创建数据库表

创建一个数据库创建student数据表并插入数据

CREATE DATABASE `mydb` CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_unicode_520_ci';

CREATE TABLE `student` (
  `stuId` int(11) NOT NULL AUTO_INCREMENT,
  `stuName` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  `stuGender` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  `stuAge` int(255) NOT NULL,
  PRIMARY KEY (`stuId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_520_ci;

INSERT INTO `mydb`.`student` (`stuName`, `stuGender`, `stuAge`) VALUES ('admin', '男', 18);
INSERT INTO `mydb`.`student` (`stuName`, `stuGender`, `stuAge`) VALUES ('tom', '男', 19);
创建实体类

ORM映射关系类名就是表名的首字母大写类中的属性就是表中的字段名

@Data类要进行封装 1. 属性私有化private 2. 生成get和set方法

src/main/java/org/example/entity/Student.java

package org.example;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 学生实体类
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {

    private int stuId;

    private String stuName;

    private String stuGender;

    private int stuAge;
}
创建Dao接口定义操作方法

src/main/java/org/example/dao/StudentDao.java

package org.example.dao;

import org.example.entity.Student;

/**
 * 接口
 */
public interface StudentDao {
    /**
     * 添加学生
     * @param student
     * @return
     */
    public int insertStu(Student student);

    /**
     * 删除学生
     * @param stuId
     * @return
     */
    public int deletetStu(int stuId);

    /**
     * 查询
     * @param stuName
     * @param stuGender
     * @return
     */
    public Student login(String stuName, String stuGender);

    /**
     * 查询所有学生信息
     * @return
     */
    public List<Student> showStudent();
}
创建Dao接口的映射文件

在resources目录下创建mapper文件

可以在IDEA中自定义一个模板mapper文件模板如下参考

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper>
    
</mapper>
  • 创建StudentMapper.xml文件

    src/main/resources/mappers/StudentMapper.xml

    使用上方的mapper文件模板创建

  • StudentDao.java与StudentMapper.xml保持一致将StudentDao.java接口改为StudentMapper.java

在映射文件中对DAO中的方法进行实现
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
    mapper文件相当于Dao接口的实现类
    namespace要制定实现类的全限定名从包名找到类
-->
<mapper namespace="org.example.dao.StudentMapper">
    <!--
        id对应接口中的方法名称
        parameterType传入的参数类型的全限定名
    -->
    <!-- 增加操作 -->
    <insert id="instertStu" parameterType="org.example.entity.Student">
        insert into student(stuName, stuGender, stuAge) VALUES (#{stuName}, #{stuGender}, #{stuAge});
    </insert>

    <!-- 删除操作 -->
    <delete id="deleteStu">
        delete from student where stuId=#{stuId};
    </delete>

    <!-- 查询操作 -->
    <!--
        resultType返回值的类型基本数据类型不用写只有对象或者集合使用
    -->
    <select id="login" resultType="org.example.entity.Student">
        select * from student where stuName=#{arg0} and stuGender=#{arg1}
    </select>
    <!--
        模糊查询:
		- stuName LIKE '%a'    # 以 a 结尾
		- stuName LIKE 'a%'    # 以 a 开头
		- stuName LIKE '%a%'   # 包含 a
		例如:
		select * from student where stuName LIKE concat('%', #{arg0}, '%')
    -->

    <!-- 查询所有 -->
    <select id="showStudent" resultType="org.example.entity.Student">
        select * from student
    </select>
</mapper>

[多参数使用]

当传入参数大于或等于2个时有三种方式实现上方代码使用的是第1种实现方式

  1. arg0, arg1, arg2, ... 实现

    如上方代码中的实现方式

    <select id="login" resultType="org.example.entity.Student">
        select * from student where stuName=#{arg0} and stuGender=#{arg1}
    </select>
    
  2. param1, param2, param3, ... 实现

    <select id="login" resultType="org.example.entity.Student">
        select * from student where stuName=#{param1} and stuGender=#{param2}
    </select>
    
  3. 使用注解配置(推荐)

    首先在Dao接口中添加注解如下

    /**
     * 查询
     * @param stuName
     * @param stuGender
     * @return
     */
    public Student login(@Param("name") String stuName, @Param("pwd") String stuGender);
    

    然后在xml文件中如下配置

    <select id="login" resultType="org.example.entity.Student">
        select * from student where stuName=#{name} and stuGender=#{pwd}
    </select>
    

目前为止,项目的结构应该如下

image-20220118161808106

将映射文件添加到主配置文件中

在mybatis-config.xml中配置

src/main/resources/mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- environments标签 -->

    <!-- 添加mapper映射文件 -->
    <mappers>
        <mapper resource="mappers/StudentMapper.xml"></mapper>
    </mappers>
</configuration>
单元测试

JUnit单元测试

添加单元测试的依赖

https://mvnrepository.com/artifact/junit/junit/4.12

<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>
创建测试

创建TestStudent.java文件

src/test/java/org/example/test/TestStudent.java

package org.example.test;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.example.dao.StudentMapper;
import org.example.entity.Student;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;

public class TestStudent {

    @Test
    public void add() {
        try {
            // 1. 加载mybatis的主配置文件
            // 选择 org.apache.ibatis 包下的
            InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");

            // 2. 创建会话工厂
            SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);

            // 3. 获取会话
            SqlSession sqlSession = factory.openSession();

            // 4. 通过会话获取dao对象
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

            // 5. 调用方法
            Student student = new Student();
            student.setStuName("bb");
            student.setStuGender("男");
            student.setStuAge(18);
            int i = mapper.insertStu(student);
            if (i > 0) {
                // 增删改会涉及到事务
                // 进行事务提交
                sqlSession.commit();
                System.out.println("成功");
            } else {
                System.out.println("失败");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void delete() {
		// 此处省略
    }

    @Test
    public void login() {
        try {
            // 1. ~ 4. 同 add()
            InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession sqlSession = factory.openSession();
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

            // 5. 调用方法
            Student student = mapper.login("admin","男");
            System.out.println(student);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void showStudent() {
        try {
            // 1. ~ 4. 同 add()
            InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession sqlSession = factory.openSession();
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

            // 5. 调用方法
            List<Student> students = mapper.showStudent();
            System.out.println(students);
            
            /**
             * 可以这样遍历输出每一个元素
             * for (Student stu:students) {
             *     System.out.println(stu);
             * }
             */
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

测试:

添加成功

image-20220118172524278

image-20220118172654675

查询成功

image-20220118182635014

查询所有成功

image-20220118190921546

[输出]

[Student(stuId=1, stuName=admin, stuGender=, stuAge=18), Student(stuId=2, stuName=tom, stuGender=, stuAge=19), Student(stuId=3, stuName=bb, stuGender=, stuAge=18)]

MyBatis文件

MyBatis核心配置文件

mybatis-config.xml是MyBatis框架的主配置文件只要用于配置MyBatis的数据源及属性信息

mybatis-config.xml中 <configuration> 中的标签配置顺序如下:

properties,settings,typeAliases,typeHandlers,objectFactory,objectWrapperFactory,plugins,environments,mappers

properties标签

用于设置键值对,或者加载属性文件

在resources目录下创建db.properties文件配置键值对

src/main/resources/db.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb
username=root
password=111111

在mybatis-config.xml的 <configuration></configuration> 标签中添加 <properties resource="db.properties"></properties> ,然后后面的数据库配置信息可以直接使用 ${配置项名称} 取得

[注意] <properties> 标签要写在 <environments> 之前

<configuration>
    <properties resource="db.properties"></properties>

    <environments default="mysql">
        <environment id="mysql">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
</configuration>
typeAliases标签

typeAliases用于给实体类取别名在映射文件中可以直接使用别名来替换实体类的全限定名

<configuration>
    <typeAliases>
        <typeAlias type="org.example.entity.Student" alias="student"></typeAlias>
    </typeAliases>
</configuration>

配置后,可以如下修改

<mapper namespace="...">
    <!-- 配置前 -->
    <insert id="..." parameterType="org.example.entity.Student">
        ...
    </insert>

    <!-- 配置后 -->
    <insert id="..." parameterType="student">
        ...
    </insert>
</mapper>
plugin插件

插件标签:向分页插件的使用

<configuration>
    <plugins>
        <plugin interceptor=""></plugin>
    </plugins>
</configuration>
mappers标签

加载映射文件配置

<configuration>
    <mappers>
        <mapper resource="mappers/StudentMapper.xml"></mapper>
    </mappers>
</configuration>
映射文件
mapper标签

mapper文件相当于Dao接口的实现类namespace属性指定实现Dao接口的全限定名

insert、update、delete、select标签

增加、修改、删除、查询

分页插件

Mybaits提供了一个PageHelper

PageHelper官网https://pagehelper.github.io/

GitHubhttps://github.com/pagehelper/Mybatis-PageHelper

中文使用方法:https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md

分页SQL语句

分页 关键字 limit

需要提供:当前页 一页显示的数据(页面容量)

查询表中共有多少条数据:select count(*) from student;

分页:select count(*) from student limit (pageNum-1)*pageSize, pageSize;

导入PageHelper依赖

https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper/5.3.0

<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.3.0</version>
</dependency>
配置PageHelper拦截器

在mybatis-config.xml中配置

<!-- 
    plugins在配置文件中的位置必须符合要求否则会报错顺序如下:
    properties?, settings?, 
    typeAliases?, typeHandlers?, 
    objectFactory?,objectWrapperFactory?, 
    plugins?, 
    environments?, databaseIdProvider?, mappers?
-->
<plugins>
    <!-- com.github.pagehelper为PageHelper类所在包名 -->
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
        <!-- 使用下面的方式配置参数,后面会有所有的参数介绍 -->
        <property name="param1" value="value1"/>
	</plugin>
</plugins>
插件使用
            // 分页前
            List<Student> students = mapper.showStudent();
            System.out.println(students);

            // 分页后
            PageHelper.startPage(1, 2);
            List<Student> students = mapper.showStudent();
            PageInfo<Student> pageInfo = new PageInfo<Student>(students);
            System.out.println(pageInfo);
            
            // 输出信息
            System.out.println("当前页:" + pageInfo.getPageNum());
            System.out.println("页面容量:" + pageInfo.getSize());
            System.out.println("总条数:" + pageInfo.getTotal());
            System.out.println("总页数:" + pageInfo.getPages());
            System.out.println("显示的数据:");
            for (Student student:pageInfo.getList()                 ) {
                System.out.println(
                	student.getStuId() + "\t" + 
                	student.getStuName() + "\t" + 
                	student.getStuGender() + "\t" + 
                	student.getStuAge()
                );
            }

查询结果

image-20220118232516699

log4j日志打印

查看日志信息

log4j依赖

https://mvnrepository.com/artifact/log4j/log4j/1.2.17

<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
导入log4j.propertites文件

log4j.properties

src/main/resources/log4j.properties

# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE            debug   info   warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE

# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE

# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=D:\axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

数据表关联映射

至少两张表,表与表之间有关系

映射关系:一对一,一对多,多对一,多对多

一对一关系

实例:用户表—用户详情表

查询用户的姓名、密码、年龄、地址、电话号码

# 两种方式:
select * from user u,details d where u.user_id=d.user_id;
select * from user u inner join details d on u.user_id=d.user_id;
数据库设计

用户信息表

CREATE TABLE `user` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  `user_pwd` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  `user_realname` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  `user_age` int(11) DEFAULT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;

用户详情表

CREATE TABLE `details` (
  `detail_id` int(11) NOT NULL AUTO_INCREMENT,
  `user_address` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  `user_desc` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  `user_phone` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  `user_id` int(11) NOT NULL,
  PRIMARY KEY (`detail_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
创建实体类

用户信息类

src/main/java/org/example/entity/User.java

package org.example.entity;

import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;

/**
 * 对应表 用户信息表
 * 类要封装: 1. 私有化 2.生成get和set方法
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private int userId;
    private String userName;
    private String userPwd;
    private String userRealname;
    private int userAge;
    private Details details; // 一对一关系
}

用户详细信息类

src/main/java/org/example/entity/Details.java

package org.example.entity;

import lombok.Data;
import lombok.NoArgsConstructor
import lombok.AllArgsConstructor;

/**
 * 用户详情表
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Details {
    private int detailId;
    private String userAddress;
    private String userDesc;
    private String userPhone;
    private int userId;
}
mapper接口

src/main/java/org/example/dao/UserMapper.java

package org.example.dao;

import org.example.entity.User;

import java.util.List;

/**
 * 接口
 */
public interface UserMapper {
    /**
     * 查询信息
     * @return
     */
    public List<User> showUser();
}
mapper.xml文件

src/main/resources/mappers/UserMapper.xml

<mapper namespace="org.example.dao.UserMapper">
    <resultMap id="u" type="user">
        <!--
            id标签主键id
            result标签: 属性
            property类中的属性名
            column对应表的字段名
        -->
        <id property="userId" column="user_id"></id>
        <result property="userName" column="user_name"></result>
        <result property="userPwd" column="user_pwd"></result>
        <result property="userRealname" column="user_realname"></result>
        <result property="userAge" column="user_age"></result>

        <!-- 一对一关系 -->
        <association property="details" javaType="org.example.entity.Details">
            <result property="detailId" column="detail_id"></result>
            <result property="userAddress" column="user_address"></result>
            <result property="userDesc" column="user_desc"></result>
            <result property="userPhone" column="user_phone"></result>
            <result property="userId" column="user_id"></result>
        </association>
    </resultMap>

    <select id="showUser" resultMap="u">
        select * from user u inner join details d on u.user_id=d.user_id
    </select>
</mapper>

记得在mybatis-config.xml中配置 <mappers>

<configuration>
     <mappers>
         <mapper resource="mappers/UserMapper.xml"></mapper>
     </mappers>
</configuration>
测试类

src/test/java/org/example/test/UserTest.java

...
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> users = mapper.showUser();
for(User user:users) {
	System.out.println(
		user.getUserName() + "\t" + 
		user.getUserPwd() + "\t" + 
		user.getUserAge() + "\t" + 
		user.getDetails().getUserAddress() + "\t" + 
		user.getDetails().getUserPhone()
	);
}
...
一对多关系

案例:班级(1)—学生(n)

通过班级id查询该班级的信息及班级下的所有学生的信息

select * from classes c inner join student s on c.cid=s.scid and c.cid=1;
select * from classes c,student s where c.cid=s.scid and c.cid=1;
创建数据库表

班级表

CREATE TABLE `classes` (
  `cid` int(11) NOT NULL AUTO_INCREMENT,
  `cname` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  `cdesc` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`cid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;

学生表

CREATE TABLE `student` (
  `sid` int(11) NOT NULL AUTO_INCREMENT,
  `sname` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  `sage` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  `scid` int(11) NOT NULL,
  PRIMARY KEY (`sid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
创建实体类

班级类

src/main/java/org/example/entity/Classes.java

 package org.example.entity;

import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;

import java.util.List;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Classes {
    private int cid;
    private String cname;
    private String cdesc;
    private List<Student> stu; // 一对多关系
}

学生类

src/main/java/org/example/entity/Student.java

package org.example.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private int sid;
    private String sname;
    private int sage;
    private int scid;
}
mapper接口

src/main/java/org/example/dao/ClassesMapper.java

package org.example.dao;

import org.example.entity.Classes;

import java.util.List;

/**
 * 接口
 */
public interface ClassesMapper {
    /**
     * 通过班级id查询信息
     * @return
     */
    public Classes showClasses(int cid);
}
mapper.xml文件

src/main/resources/mappers/ClassesMapper.xml

<mapper namespace="org.example.dao.ClassesMapper">
    <resultMap id="a" type="org.example.entity.Classes">
        <id property="cid" column="cid"></id>
        <result property="cname" column="cname"></result>
        <result property="cdesc" column="cdesc"></result>
        <!-- 一对多关系 -->
        <collection property="stu" ofType="org.example.entity.Student">
            <result property="sid" column="sid"></result>
            <result property="sname" column="sname"></result>
            <result property="sage" column="sage"></result>
            <result property="scid" column="scid"></result>
        </collection>
    </resultMap>

    <select id="showClasses" resultMap="a">
        select * from classes c inner join student s on c.cid=s.scid and c.cid=#{cid}
    </select>
</mapper>

记得在mybatis-config.xml中配置 <mappers>

<configuration>
        <mappers>
            <mapper resource="mappers/StudentMapper.xml"></mapper>
            <mapper resource="mappers/ClassesMapper.xml"></mapper>
        </mappers>
</configuration>
测试类

src/test/java/org/example/test/ClassesTest.java

...
ClassesMapper mapper = sqlSession.getMapper(ClassesMapper.class);
Classes classes = mapper.showClasses(1);
System.out.println(classes);
...

输出结果

image-20220119152029499

多对一关系

案例学生n: 班级(1)

通过学生id查询该学生所在班级的信息

select * from students s inner join classes c on s.scid=c.cid and s.sid=4;
select * from student s,classes c where s.scid=c.cid and s.scid=1;
创建数据库表

同上

创建实体类

学生类

src/main/java/org/example/entity/Student.java

package org.example.entity;

import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private int sid;
    private String sname;
    private int sage;
    private int scid;
    private Classes classes; // 学生所在的班级
}

班级类

src/main/java/org/example/entity/Classes.java

package org.example.entity;

import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

import java.util.List;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Classes {
    private int cid;
    private String cname;
    private String cdesc;
}
mapper接口

src/main/java/org/example/dao/ClassesMapper.java

package org.example.dao;

import org.example.entity.Student;

import java.util.List;

/**
 * 接口
 */
public interface StudentMapper {
    /**
     * 查询学生对应的班级
     * @return
     */
    public List<Student> showStu();
}
mapper.xml文件

src/main/resources/mappers/StudentMapper.xml

<mapper namespace="org.example.dao.StudentMapper">
    <resultMap id="b" type="org.example.entity.Student">
        <id property="sid" column="sid"></id>
        <result property="sname" column="sname"></result>
        <result property="sage" column="sage"></result>
        <result property="scid" column="scid"></result>

        <!-- 班级是一 -->
        <association property="classes" javaType="org.example.entity.Classes">
            <result property="cid" column="cid"></result>
            <result property="cname" column="cname"></result>
            <result property="cdesc" column="cdesc"></result>
        </association>
    </resultMap>

    <select id="showStu" resultMap="b">
        select * from student s inner join classes c on s.scidc.cid
    </select>
</mapper>

记得在mybatis-config.xml中配置 <mappers>

<configuration>
     <mappers>
         <mapper resource="mappers/StudentMapper.xml"></mapper>
         <mapper resource="mappers/ClassesMapper.xml"></mapper>
     </mappers>
</configuration>
测试类

src/test/java/org/example/test/StudentTest.java

...
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = mapper.showStu();
for(Student student:students) {
	System.out.println(student.getSName() + "\t" + "对应班级:" + student.getClasses());
}
...
多对多关系

案例:学生(m)----课程(n)

注意:一般对于多对多的关系都会有一个中间表,对另外两张表进行关系。

# 查询学生时,同时查询该学生选择的课程
# 三张表联合查询   inner join   on

select * from student s inner join grades g inner join course c on
s.sid=g.sid and g.course_id=c.course_id;

select * from student s,grades g,course c where s.sid=g.sid and g.course_id=c.course_id;
数据库表设计

课程表

CREATE TABLE `course` (
  `course_id` int(11) NOT NULL AUTO_INCREMENT,
  `course_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`course_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

学生表

CREATE TABLE `student` (
  `sid` int(11) NOT NULL AUTO_INCREMENT,
  `sname` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `sage` int(255) DEFAULT NULL,
  PRIMARY KEY (`sid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

中间表

CREATE TABLE `grades` (
  `gradeId` int(11) NOT NULL AUTO_INCREMENT,
  `sid` int(11) NOT NULL,
  `course_id` int(11) NOT NULL,
  PRIMARY KEY (`gradeId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
创建实体类

学生类

src/main/java/org/example/entity/Student.java

package org.example.entity;

import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private int sid;
    private String sname;
    private int sage;
    private List<Course> list; // 多个课程
}

课程类

src/main/java/org/example/entity/Course.java

package org.example.entity;

import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Course {
    private int courseId;
    private String courseName;
}
mapper接口

src/main/java/org/example/dao/ClassesMapper.java

package org.example.dao;

import org.example.entity.Student;

import java.util.List;

/**
 * 接口
 */
public interface StudentMapper {
    /**
     * 查询学生对应的班级
     * @return
     */
    public List<Student> showStu();
}
mapper.xml文件

src/main/resources/mappers/StudentMapper.xml

<mapper namespace="org.example.dao.StudentMapper">
    <resultMap id="b" type="org.example.entity.Student">
        <id property="sid" column="sid"></id>
        <result property="sname" column="sname"></result>
        <result property="sage" column="sage"></result>

        <!-- 多对多 -->
        <collection property="list" ofType="org.example.entity.Course">
          <result property="courseId" column="course_id"></result>
          <result property="courseName" column="course_name"></result>
        </collection>
    </resultMap>

    <select id="showStu" resultMap="b">
        select * from student s inner join grades g inner join course c on s.sid=g.sid and g.course_id=c.course_id
    </select>
</mapper>

记得在mybatis-config.xml中配置 <mappers>

<configuration>
    <mappers>
        <mapper resource="mappers/StudentMapper.xml"></mapper>
    </mappers>
</configuration>
测试类

src/test/java/org/example/test/StudentTest.java

...
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = mapper.showStu();
for(Student student:students) {
	System.out.println(student.getSName() + "\t" + "对应班级:" + student.getClasses());
}
...
总结
  1. 在多的一方添加集合,一的一方添加对象。

  2. 如果实体类中的属性与数据库的字段名不一致时mapper文件中选择resultmap映射

动态SQL

什么是动态SQL

根据查询条件动态完成SQL拼接

创建数据库表
CREATE TABLE `member` (
  `member_id` int(11) NOT NULL AUTO_INCREMENT,
  `member_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `member_age` int(255) DEFAULT NULL,
  `member_city` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`member_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
创建实体类

src/main/java/org/example/entity/Member.java

package org.example.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Member {
    private int memberId;
    private String memberName;
    private int memberAge;
    private String memberCity;
}
mapper接口

src/main/java/org/example/mapper/MemberMapper.java

package org.example.mapper;

import org.example.entity.Member;

import java.util.List;

public interface MemberMapper {
    /**
     * 通过指定条件进行查询
     * 1. 通过名称查新
     * 2. 通过年龄查询
     * 3. 通过城市查询
     * @param member
     * @return
     */
    public List<Member> showMember(Member member);

    /**
     * 修改
     * @param member
     * @return
     */
    public int updateMember(Member member);
}
mapper.xml文件

if, where, trim, set

src/main/resources/mappers/MemberMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.example.mapper.MemberMapper">
    <resultMap id="u" type="org.example.entity.Member">
        <id property="memberId" column="member_id"></id>
        <result property="memberName" column="member_name"></result>
        <result property="memberAge" column="member_age"></result>
        <result property="memberCity" column="member_city"></result>
    </resultMap>

    <!-- if、where、trim三种写法运行结果相同 -->
    <!-- if -->
    <select id="showMember" resultMap="u">
        select * from member where 1=1
        <if test="memberName != null"> <!--memberName就是参数对象的属性名称-->
            and member_name=#{memberName}
        </if>
        <if test="memberAge != 0"> <!-- memberAge为int类型要写成 != 0 -->
            and member_age=#{memberAge}
        </if>
        <if test="memberCity != null">
            and member_city=#{memberCity}
        </if>
    </select>

    <!-- where -->
    <select id="showMember" resultMap="u">
        select * from member
        <where>
            <if test="memberName != null"> <!--memberName就是参数对象的属性名称-->
                and member_name=#{memberName}
            </if>
            <if test="memberAge != 0">
                and member_age=#{memberAge}
            </if>
            <if test="memberCity != null">
                and member_city=#{memberCity}
            </if>
        </where>
    </select>

    <!-- trim -->
    <select id="showMember" resultMap="u">
        select * from member
        <!--
			prefix在前面加上前缀
			prefixOverrides可以自动把开头的and或者or去掉但不可以自动添加
		-->
        <trim prefix="where" prefixOverrides="and | or">
            <if test="memberName != null"> <!--memberName就是参数对象的属性名称-->
                and member_name=#{memberName}
            </if>
            <if test="memberAge != 0">
                and member_age=#{memberAge}
            </if>
            <if test="memberCity != null">
                and member_city=#{memberCity}
            </if>
        </trim>
    </select>

    <!-- set -->
    <update id="updateMember" parameterType="org.example.entity.Member">
        update member
        <set>
            <if test="memberName != null">
                member_name=#{memberName}
            </if>
            <if test="memberCity != null">
                member_city=#{memberCity}
            </if>
            <where>
                member_id=#{memberId}
            </where>
        </set>
    </update>
</mapper>

记得在mybatis-config.xml中配置 <mappers>

<configuration>
 <mappers>
     <mapper resource="mappers/MemberMapper.xml"></mapper>
 </mappers>
</configuration>
测试类

src/test/java/org/example/test/MemberTest.java

...
// 条件查询
MemberMapper mapper = sqlSession.getMapper(MemberMapper.class);
Member member = new Member();
member.setMemberName("admin");
List<Member> members = mapper.showMember(member);
for (Member member1 : members) {
    System.out.println(member1);
}
...
...
// 修改
MemberMapper mapper = sqlSession.getMapper(MemberMapper.class);
Member member = new Member();
member.setMemberName("tom");
member.setMemberId(1);
int i = mapper.updateMember(member);
sqlSession.commit();
System.out.println(i);
...

MyBatis逆向生成

MyBatis的快速生成实体类、mapper接口、mapper.xml文件

附件: generator.zip 放在D盘根目录下D:\generator

首先修改 generator.xml 配置文件

然后使用cmd命令

# 1. 切换所在路径
D:
cd generator

# 2. 
java -jar mybatis-generator-core-1.3.2.jar -configfile generator.xml -overwrite

[生成文件]

  1. 实体类 (pojo/User.java)

    生成的接口文件不含注解

  2. Mapper (mapper/UserMapper.java)

    deleteByPrimaryKey通过主键删除

    insert是添加insertSelective是选择性添加前者需要指定每一个字段的值

    selectByPrimaryKey通过主键查询

    updateByPrimaryKey是通过主键修改updateByPrimaryKeySelective是通过主键选择性修改前者是修改所有字段

  3. (mapper/UserMapper.xml)

<resultMap><resultMap><result><result> 的jdbcType属性可以删除

<sql></sql> 是公共SQL片段

#{xxx,jdbcType=xxx},jdbcType=xxx 可以省略

想要生成多个表generator.xml 配置文件中就多复制几个 <table> 标签

Integer是int类型Integer是int的包装类Integer效率比int高

抽象方法的语法:访问修饰符 abstract 返回值类型 方法名称();

public abstract int xxxx(Integer xxx); // public abstract 可省略

Spring框架

胶水框架(主要跟其他框架结合)

Spring全家桶SpringMVCSpringbootSpring Cloud

  • Spring Boot 简化SSM
  • Spring Framework Spring核心IOC AOP
  • Spring Cloud、Spring Cloud Data Flow 微服务架构
  • Spring Data 数据验证Spring提供的数据访问的客户端
  • Spring Security 权限验证安全框架类似框架shiro

官网:https://spring.io/

image-20220119185108127

Spring是一个轻量级的控制反转和面向切面编程框架,用来解决企业项目开发的复杂问题

特点:

  • 轻量级,体积小,对代码没有侵入性

  • 控制反转IOC把创建对象的工作交给Spring容器来完成

  • 依赖注入DISpring在创建对象的时候给对象的属性赋值

  • 面向切面编程AOP做事务管理可以在不改变原有业务逻辑的基础上实现对业务的增强

  • 容器:管理

Spring相关依赖https://mvnrepository.com/search?q=spring

  1. Spring Context

  2. Spring Core

  3. Spring Web

    做Web应用的

  4. Spring Beans

    Beans组件

  5. Spring Web MVC

  6. Spring TestContext Framework

  7. Spring AOP

    事务处理

  8. Spring Object/Relational Mapping

  9. Spring Framework

image-20220119190419786

Spring IOC和DI的使用

IOC控制反转可以完成对象的创建

DI对象属性赋值对象管理

Spring IOC基于XML
创建SpringIOC Maven项目

创建SpringIOC Maven项目

创建实体类

src/main/java/org/example/entity/User.java

package org.example.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private int id;
    private String name;
    private int age;
    private String address;
}

使用Spring之间

src/test/java/org/example/test/UserTest.java

package org.example.test;

import org.example.entity.User;

public class UserTest {
    public static void main(String[] args) {
        // 创建对象
        User user = new User();
        
        // 对象赋值
        user.setName("aa");
        user.setId(1);
    }
}

使用Spring后

src/main/resources/applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--
        IOC通过bean标签将实体类配置给Spring容器进行管理
        id对象的名称实体类的唯一标识
        class类的全限定名
	-->
    <bean id="user" class="org.example.entity.User">
        <property name="id" value="1"></property>
        <property name="name" value="aa"></property>
        <property name="age" value="18"></property>
        <property name="address" value="Wuhan"></property>
    </bean>

</beans>
初始化Spring对象工厂进行测试

src/test/java/org/example/test/UserTest.java

package org.example.test;

import org.example.entity.User;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserTest {
    public static void main(String[] args) {
        // 加载Spring的核心配置文件
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 通过Spring容器来获取对象
        User user = (User) context.getBean("user");
        System.out.println(user);
    }
}
DI依赖注入

DI给对象的属性赋值Spring容器加载配置文件之后通过反射创建累的对象,并给属性赋值。

Spring容器通过反射实现注入有三种方式

  • set方法注入用的较多
  • 构造器注入
  • 接口注入(不常用)
set注入

在bean标签中通过property标签给属性赋值实际上是通过set方式完成属性注入的

简单类型及字符串

src/main/resources/applicationContext.xml

<bean id="user" class="org.example.entity.User">
    <property name="id" value="1"></property>
    <property name="name" value="aa"></property>
    <property name="age" value="18"></property>
    <property name="address" value="Wuhan"></property>
</bean>

自定义对象类型

假设有两个实体类

src/main/java/org/example/entity/User.java

public class User {
    private int id;
    private String name;
    private int age;
    private String address;
    private Book book;
}

src/main/java/org/example/entity/Book.java

public class Book {
    private int bookId;
    private String bookName;
    private String author;
}

方式1在property标签中通过ref引用Spring容器中的另一个对象

src/main/resources/applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="user" class="org.example.entity.User">
        <property name="id" value="1"></property>
        <property name="name" value="aa"></property>
        <property name="age" value="18"></property>
        <property name="address" value="Wuhan"></property>
        <property name="book" ref="book"></property>
    </bean>
    <bean id="book" class="org.example.entity.Book">
        <property name="bookId" value="1"></property>
        <property name="bookName" value="Java编程"></property>
        <property name="author" value="aa"></property>
    </bean>
</beans>

方式2在property标签中添加字标签bean来指定对象内部bean

src/main/resources/applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="user" class="org.example.entity.User">
        <property name="id" value="1"></property>
        <property name="name" value="aa"></property>
        <property name="age" value="18"></property>
        <property name="address" value="Wuhan"></property>
        <property name="book">
            <bean id="book" class="org.example.entity.Book">
                <property name="bookId" value="1"></property>
                <property name="bookName" value="Java编程"></property>
                <property name="author" value="aa"></property>
            </bean>
        </property>
    </bean>
</beans>

集合类型

假设有实体类

src/main/java/org/example/entity/User.java

public class User {
    private int id;
    private String name;
    private int age;
    private String address;
    private List<String> list;
}

src/main/resources/applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="user" class="org.example.entity.User">
        <property name="id" value="1"></property>
        <property name="name" value="aa"></property>
        <property name="age" value="18"></property>
        <property name="address" value="Wuhan"></property>
        <property name="list">
            <list>
                <value>吃饭</value>
                <value>睡觉</value>
                <value>打豆豆</value>
            </list>
        </property>
    </bean>
</beans>

测试

src/test/java/org/example/test/UserTest.java

package org.example.test;

import org.example.entity.User;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserTest {
    public static void main(String[] args) {
        // 加载Spring的核心配置文件
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 通过Spring容器来获取对象
        User user = (User) context.getBean("user");
        System.out.println(user);
    }
}

image-20220119224034975

构造器注入

简单类型

假设有实体类

src/main/java/org/example/entity/User.java

public class User {
    private int id;
    private String name;
    private int age;
    private String address;
}

src/main/resources/applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--
        index通过下标下标从0开始
        name通过属性名称
        下面两种写法一样
    -->
    <bean id="user1" class="org.example.entity.User">
        <constructor-arg index="0" value="1"></constructor-arg>
        <constructor-arg index="1" value="aa"></constructor-arg>
        <constructor-arg index="2" value="12"></constructor-arg>
        <constructor-arg index="3" value="cc"></constructor-arg>
    </bean>
    <bean id="user" class="org.example.entity.User">
        <constructor-arg name="id" value="1"></constructor-arg>
        <constructor-arg name="name" value="aa"></constructor-arg>
        <constructor-arg name="age" value="12"></constructor-arg>
        <constructor-arg name="address" value="cc"></constructor-arg>
    </bean>
</beans>

自定义对象类型

假设有两个实体类

src/main/java/org/example/entity/User.java

public class User {
    private int id;
    private String name;
    private int age;
    private String address;
    private Book book;
}

src/main/java/org/example/entity/Book.java

public class Book {
    private int bookId;
    private String bookName;
    private String author;
}

src/main/resources/applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- index, name 两种写法均可 -->
    <bean id="user" class="org.example.entity.User">
        <constructor-arg index="0" value="1"></constructor-arg>
        <constructor-arg index="1" value="aa"></constructor-arg>
        <constructor-arg index="2" value="12"></constructor-arg>
        <constructor-arg index="3" value="cc"></constructor-arg>
        <constructor-arg index="4">
            <bean id="book" class="org.example.entity.Book">
                <constructor-arg name="bookId" value="1"></constructor-arg>
                <constructor-arg name="bookName" value="Java编程"></constructor-arg>
                <constructor-arg name="author" value="aa"></constructor-arg>
            </bean>
        </constructor-arg>
    </bean>
</beans>

集合类型

同理

Spring IOC基于注解

因为Spring容器初始化时只会加载applicationContext.xml文件那么我们在实体类中添加注解的话注解不会被Spring扫描所以需要在applicationContext.xml中配置扫描的范围以达到Spring初始化时扫描到对应有注解的实体类并完成初始化工作。

修改头部

添加xmlns:context属性

xmlns:context="http://www.springframework.org/schema/context"

并在xsi:schemaLocation属性中添加

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-beans.xsd

src/main/resources/applicationContext.xml

<!-- 修改前 -->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
<!-- 配置好后 -->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- 声明注解配置 -->
    <context:annotation-config></context:annotation-config>
    <!-- 扫描范围 -->
    <context:component-scan base-package="org.example.entity"></context:component-scan>
</beans>
IOC常用的注解

@Component

类注解声明此类被Spring容器进行管理相当于bean标签的作用

@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
public class Book {
    private int bookId;
    private String bookName;
    private String author;
}

@Component(value = "user")

value属性用于指定当前bean的id相当于bean标签的id属性value属性可以省略如果省略当前id的值默认为类名首字母小写

@Service

类注解声明业务层处理类配置给Spring容器管理service接口的实现类

@Controller

类注解声明将控制器类配置给Spring容器管理例如Servlet

@Autowired

属性注解,用于声明属性

@Resource

属性注解,用于声明属性

实体类

src/main/java/org/example/entity/User.java

@Data
@NoArgsConstructor
@AllArgsConstructor
@Component
public class User {
    @Value("1")
    private int id;
    @Value("aa")
    private String name;
    @Value("12")
    private int age;
    @Value("武汉")
    private String address;
    @Resource // 或 @Autowired
    private Book book;
}

src/main/java/org/example/entity/Book.java

@Data
@AllArgsConstructor
@NoArgsConstructor
@Service
public class Book {
    @Value("3")
    private int bookId;
    @Value("Java编程")
    private String bookName;
    @Value("dd")
    private String author;
}

测试

package org.example.test;

import org.example.entity.User;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserTest {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = (User) context.getBean("user");
        System.out.println(user);
    }
}

输出

D:\Program\Java\jdk1.8.0_201\bin\java.exe ...
User(id=1, name=aa, age=12, address=武汉, book=Book(bookId=3, bookName=Java编程, author=dd))

Process finished with exit code 0

Spring整合MyBatis

创建项目
创建普通Maven项目

image-20220119234814230

导入依赖

需要导入的依赖:MyBatisMySQLLombokJUnitSpring、MyBatis Spring、Druid

MyBatis Spring依赖

https://mvnrepository.com/artifact/org.mybatis/mybatis-spring/2.0.6

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>2.0.6</version>
</dependency>

Druid依赖(阿里巴巴数据源)

https://mvnrepository.com/artifact/com.alibaba/druid/1.2.8

<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.8</version>
</dependency>

Spring测试依赖

https://mvnrepository.com/artifact/org.springframework/spring-test/5.2.19.RELEASE

<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.2.19.RELEASE</version>
    <scope>test</scope>
</dependency>

Spring框架的依赖版本最好保持一致

Spring JDBC

<spanid="SpringJDBC依赖"></spanid=>

https://mvnrepository.com/artifact/org.springframework/spring-jdbc/5.2.19.RELEASE

<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.19.RELEASE</version>
</dependency>

综上

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>spring_and_mybatis</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.9</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.19.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.6</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.8</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.2.19.RELEASE</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.19.RELEASE</version>
        </dependency>
    </dependencies>
</project>
创建db.properties文件

在resources目录下创建db.properties文件配置键值对

src/main/resources/db.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb?characterEncoding=utf-8
username=root
password=111111
创建Spring核心配置文件

在resources目录下创建applicationContext.xml文件传送门

当Spring和MyBatis整合后MyBatis核心配置文件mybatis-config.xml可以不要

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 加载数据库配置文件 -->
    <context:property-placeholder location="classpath:db.properties" system-properties-mode="NEVER"></context:property-placeholder>

    <!-- 配置数据源 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${driver}"></property>
        <property name="url" value="${url}"></property>
        <property name="username" value="${username}"></property>
        <property name="password" value="${password}"></property>
    </bean>

    <!-- 配置 SqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 数据源 -->
        <property name="dataSource" ref="dataSource"></property>
        <!-- mapper文件的路径 -->
        <property name="mapperLocations" value="mappers/*Mapper.xml"></property>
        <!-- [可选] 取别名:类名首字母小写 -->
        <property name="typeAliasesPackage" value="org.example"></property>
        <!-- [可选] MyBatis配置文件 -->
        <!-- <property name="configLocation" value="classpath:mybatis-config.xml"></property> -->
    </bean>

    <!-- 配置mapper -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- sqlSessionFactory -->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
        <!-- mapper接口路径 -->
        <property name="basePackage" value="org.example.mapper"></property>
    </bean>
</beans>
数据库建表语句

用户表

CREATE TABLE `user` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  `user_pwd` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  `user_realname` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  `user_age` int(11) DEFAULT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
实体类

src/main/java/org/example/entity/User.java

package org.example.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Integer userId;
    private String userName;
    private String userPwd;
    private String userRealname;
    private Integer userAge;
}
mapper接口

src/main/java/org/example/mapper/UserMapper.java

package org.example.mapper;

import org.example.entity.User;

import java.util.List;

public interface UserMapper {
    /**
     * 查询所有用户信息
     * @return
     */
    public List<User> showUser();
}
mapper.xml文件

src/main/resources/mappers/UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper>
    <resultMap id="u" type="user">
        <id property="userId" column="user_id"></id>
        <result property="userName" column="user_name"></result>
        <result property="userPwd" column="user_pwd"></result>
        <result property="userRealname" column="user_realname"></result>
        <result property="userAge" column="user_age"></result>
    </resultMap>
    <select id="showUser" resultMap="u">
        select * from user
    </select>
</mapper>
测试类

当Spring和MyBatis整合后单表不需要使用 sqlSession.commit(); 事务提交,可以自动提交

src/test/java/org/example/test/SpringUserTest.java

package org.example.test;

import org.example.entity.User;
import org.example.mapper.UserMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;
import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringUserTest {
    // 需要调用接口中的方法进行测试
    @Resource
    private UserMapper userMapper;

    @Test
    public void show() {
        List<User> users = userMapper.showUser();
        for (User user : users) {
            System.out.println(user);
        }
    }
}

通过@RunWith声明当前测试类位于Spring容器管理

通过@ContextConfiguration声明加载配置文件

运行结果

image-20220120005858883

TKMapper快速开发

tk.mapper是mybatis第三方提供的一个插件。简化接口不需要映射文件

导入依赖

基于上一个项目Spring整合MyBatis

https://mvnrepository.com/artifact/tk.mybatis/mapper/4.1.5

<!-- https://mvnrepository.com/artifact/tk.mybatis/mapper -->
<dependency>
    <groupId>tk.mybatis</groupId>
    <artifactId>mapper</artifactId>
    <version>4.1.5</version>
</dependency>
修改Spring的核心配置文件

去掉以下部分

<!-- mapper文件的路径 -->
<property name="mapperLocations" value="mappers/*Mapper.xml"></property>
<!-- [可选] 取别名:类名首字母小写 -->
<property name="typeAliasesPackage" value="org.example"></property>
<!-- [可选] MyBatis配置文件 -->
<!-- <property name="configLocation" value="classpath:mybatis-config.xml"></property> -->

修改以下部分

<!-- 配置mapper -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">

改为

<!-- 配置mapper -->
<bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">

image-20220120111645093

删除映射文件

src/main/resources/mappers/

实体类添加注解

src/main/java/org/example/entity/User.java

package org.example.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import tk.mybatis.mapper.annotation.KeySql;

import javax.persistence.Id;
import javax.persistence.Table;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "user") // 对应数据库表名
public class User {
    /* ***** 如果表中字段名和实体类中属性名一致,就可以直接测试 ***** */
    @Id // 主键
    @KeySql(useGeneratedKeys = true) // 自增
    private Integer user_id;
    private String user_name;
    private String user_pwd;
    private String user_realname;
    private Integer user_age;

    /* 其实写成驼峰命名,经测试也可以 */
    @Id // 主键
    @KeySql(useGeneratedKeys = true) // 自增
    private Integer userId;
    private String userName;
    private String userPwd;
    private String userRealname;
    private Integer userAge;

    /* ***** 如果表中字段名和实体类中属性名不一致,需要谈价@Column注解 ***** */
    @Id // 主键
    @KeySql(useGeneratedKeys = true) // 自增
    @Column(name = "user_id")
    private Integer id;
    @Column(name = "user_name")
    private String name;
    @Column(name = "user_pwd")
    private String pwd;
    @Column(name = "user_realname")
    private String realname;
    @Column(name = "user_age")
    private Integer age;
}
mapper接口改为extends接口函数删掉

src/main/java/org/example/mapper/UserMapper.java

package org.example.mapper;

import org.example.entity.User;
import tk.mybatis.mapper.common.Mapper;

public interface UserMapper extends Mapper<User> {
    
}
测试类
package org.example.test;

import org.example.entity.User;
import org.example.mapper.UserMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;
import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringUserTest {
    // 需要调用接口中的方法进行测试
    @Resource
    private UserMapper userMapper;

    @Test
    public void show() {
        List<User> users = userMapper.selectAll();
        for (User user : users) {
            System.out.println(user);
        }
    }
}

运行结果

User(user_id=1, user_name=小明, user_pwd=13579, user_realname=张小明, user_age=20)
User(user_id=2, user_name=ad, user_pwd=asda, user_realname=dasd, user_age=48)

Process finished with exit code 0

Spring整合MyBatis整合log4j

基于上一个项目TKMapper快速开发

导入依赖

log4j、commons-logging、slf4j-log4j12

导入commons-logging依赖

https://mvnrepository.com/artifact/commons-logging/commons-logging/1.2

<!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
</dependency>

导入slf4j-log4j12依赖

https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12/1.7.25

<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.25</version>
    <scope>test</scope>
</dependency>
添加log4j配置文件

导入log4j.propertites文件

进行测试,日志成功输出

image-20220120115301780

Spring和MyBatis整合后pageHelper分页插件的使用

导入依赖

导入PageHelper依赖

在Spring核心配置文件中配置拦截器

https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md

src/main/resources/applicationContext.xml

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  ...
  <!-- pageHelper分页插件拦截器 -->
  <property name="plugins">
    <array>
      <bean class="com.github.pagehelper.PageInterceptor">
        <property name="properties">
          <!--使用下面的方式配置参数,一行配置一个 -->
          <value>
            params=value1
          </value>
        </property>
      </bean>
    </array>
  </property>
</bean>
测试类

src/test/java/org/example/test/SpringUserTest.java

package org.example.test;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.example.entity.User;
import org.example.mapper.UserMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;
import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringUserTest {
    // 需要调用接口中的方法进行测试
    @Resource
    private UserMapper userMapper;

    @Test
    public void show() {
        // 设置当前页,页面容量
        PageHelper.startPage(1,3);
        List<User> users = userMapper.selectAll();
        PageInfo<User> userPageInfo = new PageInfo<>(users);
        System.out.println(userPageInfo);
    }
}

运行结果

PageInfo{pageNum=1, pageSize=3, size=3, startRow=1, endRow=3, total=5, pages=2, list=Page{count=true, pageNum=1, pageSize=3, startRow=0, endRow=3, total=5, pages=2, reasonable=false, pageSizeZero=false}[User(id=1, name=小明, pwd=13579, realname=张小明, age=20), User(id=2, name=ad, pwd=asda, realname=dasd, age=48), User(id=3, name=vb, pwd=13579, realname=张小明, age=20)], prePage=0, nextPage=2, isFirstPage=true, isLastPage=false, hasPreviousPage=false, hasNextPage=true, navigatePages=8, navigateFirstPage=1, navigateLastPage=2, navigatepageNums=[1, 2]}

AOP注解事务的使用

导入依赖

spring-aspects

https://mvnrepository.com/artifact/org.springframework/spring-aspects/5.2.19.RELEASE

<!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.2.19.RELEASE</version>
</dependency>
修改Spring的核心配置文件

修改文件头,添加事务管理器配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    ...

    <!-- 事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!-- 声明使用注解配置 -->
    <context:annotation-config></context:annotation-config>

    <!-- 扫描范围 -->
    <context:component-scan base-package="org.example"></context:component-scan>

    <!-- 注解事务管理配置 -->
    <tx:annotation-driven></tx:annotation-driven>
</beans>
应用

创建UserService

src/main/java/org/example/service/UserService.java

package org.example.service;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserService {
    @Transactional(propagation = Propagation.REQUIRED)
    public void addUser() {
        System.out.println("增加");
    }
    @Transactional(propagation = Propagation.REQUIRED)
    public int updateUser() {
        return 1;
    }
    @Transactional(propagation = Propagation.SUPPORTS) // 查询不需要事务
    public int selectUser() {
        return 1;
    }
}

Spring中七种Propagation类的事务属性详解

REQUIRED支持当前事务如果当前没有事务就新建一个事务。这是最常见的选择。

SUPPORTS支持当前事务如果当前没有事务就以非事务方式执行。

MANDATORY支持当前事务如果当前没有事务就抛出异常。

REQUIRES_NEW新建事务如果当前存在事务把当前事务挂起。

NOT_SUPPORTED以非事务方式执行操作如果当前存在事务就把当前事务挂起。

NEVER以非事务方式执行如果当前存在事务则抛出异常。

NESTED支持当前事务如果当前事务存在则执行一个嵌套事务如果当前没有事务就新建一个事务。

REQUIRED和SUPPORTS用的较多。REQUIRED→增删改SUPPORTS→查

SpringMVC框架

Web框架Servlet角色

介绍

SpringMVC是由Spring官方提供的基于MVC设计的web框架

SpringMVC是基于Servlet封装的用于实现MVC控制的框架实现前端与服务端的交互

SpringMVC优势

严格遵守MVC分层思想

SpringMVC在数据绑定、视图解析等提供了多种处理方式可以灵活配置

SpringMVC对Restful风格提供了良好的支持

SpringMVC本质工作

接受并解析请求

处理请求

数据渲染、响应请求

SpringMVC框架部署

创建Maven web工程

之前创建的都是Maven普通工程

创建SpringMVC Maven web项目

配置SpringMVC
导入依赖

所需依赖导入spring-webmvc就可包含以下四个依赖

  • spring-context
  • spring-jdbc
  • spring-web
  • spring-webmvc

导入spring-webmvc依赖

https://mvnrepository.com/artifact/org.springframework/spring-webmvc/5.2.19.RELEASE

<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.19.RELEASE</version>
</dependency>
创建SpringMVC配置文件

在resources目录下创建名为spring-servlet.xml文件使用spring模板并修改头部+配置

src/main/resources/spring-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 声明注解配合 IOC --><!-- Spring管理的注解 -->
    <context:annotation-config></context:annotation-config>

    <!-- 扫描注解的包 -->
    <context:component-scan base-package="org.example.web"></context:component-scan>

    <!-- 声明MVC的注解 --><!-- MVC管理的注解 -->
    <mvc:annotation-driven></mvc:annotation-driven>

    <!-- 请求数据访问 --><!-- 默认的Servlet处理器 -->
    <mvc:default-servlet-handler></mvc:default-servlet-handler>

    <!--thymeleaf模板解析器-->
    <bean id="templateResolver" class="org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver">
        <property name="prefix" value="/WEB-INF/templates/"></property>
        <property name="suffix" value=".html"></property>
        <property name="templateMode" value="HTML5"></property>
        <property name="cacheable" value="false"></property>
        <property name="characterEncoding" value="utf-8"></property>
    </bean>

    <bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
        <property name="templateResolver" ref="templateResolver"></property>
    </bean>

    <!--视图解析器-->
    <bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
        <property name="templateEngine" ref="templateEngine"></property>
        <property name="characterEncoding" value="utf-8"></property>
    </bean>

    <!-- 配置静态资源放行 -->
    <mvc:resources mapping="/css/**" location="/css/"></mvc:resources>
    <mvc:resources mapping="/js/**" location="/js/"></mvc:resources>
    <mvc:resources mapping="/images/**" location="/images/"></mvc:resources>
</beans>

右上角点一下Create new application context

image-20220120161453418

在web.xml中配置SpringMVC的前端控制器

SpringMVC提供了一个名为DispatcherServlet的类前端控制器用于拦截用户请求交由SpringMVC来处理

src/main/webapp/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!-- 前端控制器 -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param> <!-- 加载SpringMVC的配置文件 -->
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-servlet.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
        <!-- / 代表从根目录开始拦截 -->
    </servlet-mapping>
</web-app>
创建控制器 Controller

在SpringMVC中我们把接收用户请求处理用户请求的类称为Controller控制器

  1. 创建一个org.example.web的包包需要在注解扫描的范围内
  2. 创建一个类(无需任何的继承和实现)
  3. 在类上添加 @Controller 注解声明此类为SpringMVC的控制器
  4. 在类上添加 @RequestMapping("url") 声明控制器类的请求url地址可以省略

src/main/java/org/example/web/UserController.java

package org.example.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/user")
public class UserController {

}
在控制器类中定义处理请求的方法

在一个控制器类中可以定义多个方法处理不同的请求

在每个方法上添加 @RequestMapping("/login") 用于声明当前方法的请求url地址

package org.example.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/add")
    public void addUser(){
        System.out.println("增加");
    }

    @RequestMapping("/select")
    public void viewUser(){
        System.out.println("查询");
    }
}
启动

浏览器访问:http://localhost:8080/user/add

image-20220120170419338

服务端成功输出信息

image-20220120170449972

静态资源配置

静态资源就是项目中的HTML, CSS, JS, 图片, 字体等

/* 和 / 的区别

src/main/webapp/WEB-INF/web.xml中url-pattern内部配置

<servlet-mapping>
    <!-- 两者的区别 -->
    <url-pattern>/</url-pattern>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

/* 拦截所有的HTTP请求包括jsp的请求都作为控制器类的请求路径来处理

/ 拦截所有的HTTP请求但不包括jsp的请求不会放行静态资源的请求html、css、js

静态资源放行

在SpringMVC的配置文件中添加以下代码

src/main/webapp/WEB-INF/web.xml

    <!-- 扫描注解的包 -->
    <context:component-scan base-package="org.example.web"></context:component-scan>

    <!-- 声明MVC的注解 --><!-- MVC管理的注解 -->
    <mvc:annotation-driven></mvc:annotation-driven>

    <!-- 请求数据访问 --><!-- 默认的Servlet处理器 -->
    <mvc:default-servlet-handler></mvc:default-servlet-handler>

    <!-- 配置静态资源放行 -->
    <mvc:resources mapping="/css/**" location="/css/"></mvc:resources>
    <mvc:resources mapping="/js/**" location="/js/"></mvc:resources>
    <mvc:resources mapping="/images/**" location="/images/"></mvc:resources>

image-20220120184525560

SpringMVC框架数据应用

前端提交数据到控制器,控制器接收处理数据

前端提交数据到控制器
表单提交

输入框需要提供name属性,SpringMVC控制器是通过name属性取值的

<body>
    <h1>图书管理系统</h1>
    <form action="" method="get">
        <p>图书名称:<input type="text" name="bookName"> </p>
        <p>图书作者:<input type="text" name="author"> </p>
        <p>图书价格:<input type="text" name="price"> </p>
        <p><input type="submit" value="提交" > </p>
    </form>
</body>
URL提交

超链接提交

 <a href="/user/add?id=1">跳转</a>
ajax提交

控制器接收前端提交的数据
@RequestParam("")接收请求行传值

@RequestParam("") 注解用于接收请求行传递的数据

src/main/java/org/example/web/UserController.java

package org.example.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/add")
    public void addUser(@RequestParam("bookName") String bookName, @RequestParam("author") String author, @RequestParam("price") String price) {
        System.out.println(bookName);
        System.out.println(author);
        System.out.println(price);
    }
}

测试

image-20220120214323545

image-20220120214332553

[注意]

1.如果控制器方法中接收数据的参数名与请求过来的参数名称一致,则 @RequestParam("") 注解可以省略

如上述例子中的

public void addUser(@RequestParam("bookName") String bookName, @RequestParam("author") String author, @RequestParam("price") String price)

就可以写为

public void addUser(String bookName, String author, String price)

2.当页面传递过来的参数名称与实体类的属性名一一对应,那么控制器方法可以直接通过对象接收

例如:

src/main/java/org/example/web/UserController.java

   @RequestMapping("/add")
   public void addUser(Book book) {
       System.out.println(book.getBookName());
       System.out.println(book.getAuthor());
       System.out.println(book.getPrice());
   }

src/main/java/org/example/entity/Book.java

public class Book {
   private int bookId;
   private String bookName;
   private String author;
   private double price;
   // ...  此处省略 Getter 和 Setter
}

测试结果相同

控制器响应前端请求

form表单/超链接请求跳转页面

src/main/webapp/index.jsp

<body>
    <a href="/user/add?bookName=1&author=1&price=1">提交</a>
</body>

src/main/webapp/success.jsp

<body>
    <h1>成功页面</h1>
</body>
转发返回类型为String

src/main/java/org/example/web/UserController.java

@RequestMapping("/add")
public String addUser(Book book) {
    return "/success.jsp"; // 或者 return "forward:/success.jsp"; 
}

image-20220120220526068

重定向返回类型为String

src/main/java/org/example/web/UserController.java

@RequestMapping("/add")
public String addUser(Book book) {
    return "redirect:/success.jsp"; // 重定向
}

image-20220120222121539

转发返回类型为ModelAndView

src/main/java/org/example/web/UserController.java

@RequestMapping("/add")
public String addUser(Book book) {
    ModelAndView modelAndView = new ModelAndView("/success.jsp");
    // 或者 "forward:/success.jsp"
    return modelAndView;
}

image-20220120220526068

重定向返回类型为ModelAndView

src/main/java/org/example/web/UserController.java

@RequestMapping("/add")
public String addUser(Book book) {
    ModelAndView modelAndView = new ModelAndView("redirect:/success.jsp");
    return modelAndView;
}

image-20220120222121539

Thymeleaf

模板引擎

介绍

Thymeleaf是一个现代的服务器端 Java 模板引擎,适用于 Web 和独立环境。

Thymeleaf 的主要目标是为您的开发工作流程带来优雅的自然模板——HTML可以在浏览器中正确显示,也可以用作静态原型,从而在开发团队中实现更强大的协作。

Thymeleaf 是现代 HTML5 JVM Web 开发的理想选择

官网

https://www.thymeleaf.org/

导入依赖
导入thymeleaf依赖

https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf/3.0.14.RELEASE

<!-- https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf -->
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf</artifactId>
    <version>3.0.14.RELEASE</version>
</dependency>
导入thymeleaf-spring4依赖

https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf-spring4/3.0.14.RELEASE

<!-- https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf-spring4 -->
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring4</artifactId>
    <version>3.0.14.RELEASE</version>
</dependency>
编写SpringMVC的核心配置文件

src/main/resources/spring-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 声明注解配合 IOC --><!-- Spring管理的注解 -->
    <context:annotation-config></context:annotation-config>

    <!-- 扫描注解的包 -->
    <context:component-scan base-package="org.example.web"></context:component-scan>

    <!-- 声明MVC的注解 --><!-- MVC管理的注解 -->
    <mvc:annotation-driven></mvc:annotation-driven>

    <!-- 请求数据访问 --><!-- 默认的Servlet处理器 -->
    <mvc:default-servlet-handler></mvc:default-servlet-handler>

    <!--thymeleaf模板解析器-->
    <bean id="templateResolver" class="org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver">
        <property name="prefix" value="/WEB-INF/templates/"></property>
        <property name="suffix" value=".html"></property>
        <property name="templateMode" value="HTML5"></property>
        <property name="cacheable" value="false"></property>
        <property name="characterEncoding" value="utf-8"></property>
    </bean>

    <bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
        <property name="templateResolver" ref="templateResolver"></property>
    </bean>

    <!--视图解析器-->
    <bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
        <property name="templateEngine" ref="templateEngine"></property>
        <property name="characterEncoding" value="utf-8"></property>
    </bean>

    <!-- 配置静态资源放行 -->
    <mvc:resources mapping="/css/**" location="/css/"></mvc:resources>
    <mvc:resources mapping="/js/**" location="/js/"></mvc:resources>
    <mvc:resources mapping="/images/**" location="/images/"></mvc:resources>
</beans>
在web.xml中配置首页启动项

src/main/webapp/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!-- 首页启动项 -->
    <welcome-file-list>
        <welcome-file>/WEB-INF/templates/login.html</welcome-file>
    </welcome-file-list>
    
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param> <!-- 加载SpringMVC的配置文件 -->
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-servlet.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
        <!-- / 代表从根目录开始拦截 -->
    </servlet-mapping>
</web-app>
Thymeleaf的使用
启动

一般thymeleaf的模板 放在WEB-INF下面

src/main/webapp/WEB-INF/templates/login.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"> 
    <title>Title</title>
</head>
<body>
    <h1>thymeleaf</h1>
</body>
</html>

image-20220120231646089

运用

src/main/webapp/WEB-INF/templates/login.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>图书管理系统</h1>
<form action="/user/add" method="get">
    <p>图书名称:<input type="text" name="bookName"> </p>
    <p>图书作者:<input type="text" name="author"> </p>
    <p>图书价格:<input type="text" name="price"> </p>
    <p><input type="submit" value="提交" > </p>
</form>
</body>
</html>

src/main/webapp/WEB-INF/templates/success.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>图书管理系统</h1>
<form action="/user/add" method="get">
    <p>图书名称:<input type="text" name="bookName"> </p>
    <p>图书作者:<input type="text" name="author"> </p>
    <p>图书价格:<input type="text" name="price"> </p>
    <p><input type="submit" value="提交" > </p>
</form>
</body>
</html>

image-20220120232421282

image-20220120232442818

语法

Thymeleaf的主要作用是把model中的数据渲染到HTML中因此语法主要是如何解析model中的数据

Thymeleaf使用的是OGNL表达式Object Graph Notation Language

JSP中使用的是JSTL表达式JSP Standard Tag Library、el表达式Expressiong Language

变量基本类型String、int、...

控制器代码

src/main/java/org/example/web/UserController.java

    @RequestMapping("/add")
    public String addUser(Book book, Model model) {
        // 把书籍名称存储起来
        model.addAttribute("name",book.getBookName());
        return "success";
    }

页面获取

通过 tx:next=${控制器传递过来的参数} 显示文本内容

<span th:text="${name}"></span>
对象

控制器代码

src/main/java/org/example/web/UserController.java

    @RequestMapping("/add")
    public String addUser(Book book, Model model) {
        // 把书籍名称存储起来
        model.addAttribute("book",book);
        return "success";
    }

页面获取

通过 tx:next=${控制器传递过来的参数} 显示文本内容

<span th:text="${book.getBookName()}"></span>
<span th:text="${book.bookName}"></span>

SpringMVC字符集编码设置

SpringMVC解决中文乱码问题
前端编码

HTML页面

<meta charset="UTF-8">

jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
服务器编码

tomcat/conf/server.xml

<Connector port="8090" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" URIEncoding="utf-8" />
设置SpringMVC过滤器

在web.xml中配置编码过滤器的方式

<!--编码过滤器-->
<filter>
    <filter-name>EncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>utf-8</param-value>
   </init-param>
</filter>
<filter-mapping>
    <filter-name>EncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

SSM框架整合

MyBatis、Spring、SpringMVC三个框架整合

创建Mavenweb项目

导入依赖

需要导入的依赖

数据库:MyBatisMySQLMyBatis Spring

单元测试:JUnit

实体类:Lombok

数据源:Druid

SpringSpringSpring JDBCSpring Web MVC

页面:ThymeleafThymeleaf Spring4

日志:log4jcommons-loggingslf4j-log4j12

如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>ssm</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <dependencies>
        <!-- mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.9</version>
        </dependency>
        
        <!-- mybatis-spring -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.6</version>
        </dependency>

        <!-- mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>

        <!-- junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
            <scope>provided</scope>
        </dependency>

        <!-- druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.8</version>
        </dependency>

        <!-- spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.19.RELEASE</version>
        </dependency>

        <!-- spring-jdbc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.19.RELEASE</version>
        </dependency>

        <!-- spring-webmvc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.19.RELEASE</version>
        </dependency>

        <!-- thymeleaf -->
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf</artifactId>
            <version>3.0.14.RELEASE</version>
        </dependency>

        <!-- thymeleaf-spring4 -->
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring4</artifactId>
            <version>3.0.14.RELEASE</version>
        </dependency>

        <!-- log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <!-- commons-logging -->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>

        <!-- slf4j-log4j12 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.25</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

编写数据库配置文件

在resources目录下创建db.properties文件

src/main/resources/db.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb?characterEncoding=utf-8
username=root
password=111111

编写Spring核心配置文件

在resources目录下创建db.properties文件

提升

前后端分离

Springboot + Vue

微服务(架构师)

Spring Cloud + ES + Redis