1
0
mirror of https://gitee.com/coder-xiaomo/java-note synced 2025-01-11 03:58:14 +08:00
Code Issues Projects Releases Wiki Activity GitHub Gitee
java-note/张博凯的Java学习笔记.md

3554 lines
88 KiB
Markdown
Raw Normal View History

2022-01-20 14:52:20 +08:00
# 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](张博凯的Java学习笔记.assets/image-20220116152649260.png)
(可以和包一起建)
`org.example.entity.User``org.example.pojo.User`
> 类名首字母大写;包名首字母小写
![image-20220116153103336](张博凯的Java学习笔记.assets/image-20220116153103336.png)
##### 创建main方法
`main + <回车>`
![image-20220116153728996](张博凯的Java学习笔记.assets/image-20220116153728996.png)
![image-20220116153844861](张博凯的Java学习笔记.assets/image-20220116153844861.png)
#### 新建接口
![image-20220116153417709](张博凯的Java学习笔记.assets/image-20220116153417709.png)
> 接口没有方法体不可以new对象
#### 实现接口
UserDao
![image-20220116154126155](张博凯的Java学习笔记.assets/image-20220116154126155.png)
![image-20220116154238246](张博凯的Java学习笔记.assets/image-20220116154238246.png)
![image-20220116154415712](张博凯的Java学习笔记.assets/image-20220116154415712.png)
![image-20220116154448653](张博凯的Java学习笔记.assets/image-20220116154448653.png)
#### 集合与数组
```java
/*
* 数组:存储相同数据类型的一组数据
* 集合:可以存储不同数据类型的数据
* 泛型集合:存储有相同类型的数据
*/
// 集合
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](张博凯的Java学习笔记.assets/image-20220117103539600.png)
###### 安装和配置
**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](张博凯的Java学习笔记.assets/image-20220117114331099.png)
>
> - 配置镜像
>
> ```xml
> <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 -version``mvn -version`
![image-20220117105823106](张博凯的Java学习笔记.assets/image-20220117105823106.png)
**4. 依赖管理流程**
![Maven.drawio](张博凯的Java学习笔记.assets/Maven.drawio.png)
本地仓库:就是本地计算机上的某个文件夹(可以自定义的任何文件夹)
远程仓库就是远程主机上的jar文件仓库
### Java项目打包三种方式
1. pomMaven项目
2. jarJava普通项目
3. warJavaweb项目
## IntelliJ IDEA开发
### 配置
#### 主题配置
Settings > Appearance & Behavior > Appearance
![image-20220116150937119](张博凯的Java学习笔记.assets/image-20220116150937119.png)
#### 编码设置
Settings > Editor > File Encodings
改成UTF-8
![image-20220116150815030](张博凯的Java学习笔记.assets/image-20220116150815030.png)
#### 设置IDEA启动时不自动打开上次打开的项目
Settings > Appearance & Behavior > System Settings
![image-20220118002219620](张博凯的Java学习笔记.assets/image-20220118002219620.png)
#### 查看JDK版本
```bash
java -version
```
![image-20220116151812896](张博凯的Java学习笔记.assets/image-20220116151812896.png)
#### 配置idea中的JDK
File > Project Structure
![image-20220116161629613](张博凯的Java学习笔记.assets/image-20220116161629613.png)
![image-20220116161555885](张博凯的Java学习笔记.assets/image-20220116161555885.png)
#### 配置idea中的Maven
Settings > Build, Execution, Deployment > Build Tools > Maven
![image-20220117142419973](张博凯的Java学习笔记.assets/image-20220117142419973.png)
#### IDEA创建自定义模板
[点击文档内跳转](#IDEA自定义模板)
### 快捷键
> 有些快捷键在其他部分顺带提到了,这里仅写其他部分没有提到的快捷键
- main+回车 创建main方法
```java
public static void main(String[] args) {
}
```
- xxxx.var+回车 生成赋值语句
```java
"apple".var
// 👇
String apple = "apple";
```
- sout+回车 输出语句
```java
System.out.println();
```
- Alt+Enter 添加try catch ...
- Alt+Insert 生成构造器、Getter and Setter等
![image-20220118005611780](张博凯的Java学习笔记.assets/image-20220118005611780.png)
-
### 创建项目
#### 创建简单Java项目控制台项目
![image-20220116152139474](张博凯的Java学习笔记.assets/image-20220116152139474.png)
不使用模板直接Next
![image-20220116152438232](张博凯的Java学习笔记.assets/image-20220116152438232.png)
设置项目名称和路径,点击完成
![image-20220116152545188](张博凯的Java学习笔记.assets/image-20220116152545188.png)
#### 创建Javaweb项目
2021.3与2019版本不同
##### 2021.3版本idea
参考了https://blog.csdn.net/znufe_newer/article/details/113115002
**2021.3版本不是选左边的Java Enterprise而是选Java**
![image-20220116163216848](张博凯的Java学习笔记.assets/image-20220116163216848.png)
![image-20220116163237365](张博凯的Java学习笔记.assets/image-20220116163237365.png)
![image-20220116163251053](张博凯的Java学习笔记.assets/image-20220116163251053.png)![image-20220116163341532](张博凯的Java学习笔记.assets/image-20220116163341532.png)
![image-20220116163519894](张博凯的Java学习笔记.assets/image-20220116163519894.png)
##### 2019版本idea
步骤如下
**图中要勾上Create web.xml**
![image-20220116163623140](张博凯的Java学习笔记.assets/image-20220116163623140.png)
![image-20220116163649763](张博凯的Java学习笔记.assets/image-20220116163649763.png)
#### 创建普通Maven项目控制台项目
![image-20220117142625153](张博凯的Java学习笔记.assets/image-20220117142625153.png)
![image-20220117142728008](张博凯的Java学习笔记.assets/image-20220117142728008.png)
##### 项目目录介绍
![image-20220117145353469](张博凯的Java学习笔记.assets/image-20220117145353469.png)
```
src/main/java # Java后端代码
src/main/resources # 配置文件
src/test/java
pom.xml # Maven依赖
```
##### Maven的pom.xml配置
> **artifactId配置中不可以有中文**artifictid的正则表达式为`[A-Za-z0-9_\-.]`
```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>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](张博凯的Java学习笔记.assets/image-20220117143830281.png)
依赖添加后需要点击图中 Load Maven Changes 按钮
![image-20220117144038244](张博凯的Java学习笔记.assets/image-20220117144038244.png)
如果没有的话可以右键 Maven > Reload Project
![image-20220118110133670](张博凯的Java学习笔记.assets/image-20220118110133670.png)
#### 创建Mavenweb项目
> 有两种方式
>
> 1. 创建项目时选择Maven勾上Create from archtype
>
> 不建议使用这种方式,因为会生成很多依赖和没有用的东西在项目中
>
> ![image-20220118002503343](张博凯的Java学习笔记.assets/image-20220118002503343.png)
>
> 2. 手动操作(见下方步骤)
![image-20220118002605490](张博凯的Java学习笔记.assets/image-20220118002605490.png)
![image-20220118002804532](张博凯的Java学习笔记.assets/image-20220118002804532.png)
配置打包方式war包
pom.xml中添加 `<packaging>war</packaging>` ,如下:
```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>mavenweb项目</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
</project>
```
添加 web.xml 文件
![image-20220118003605867](张博凯的Java学习笔记.assets/image-20220118003605867.png)
![image-20220118003711365](张博凯的Java学习笔记.assets/image-20220118003711365.png)
`WEB-INF` 前添加 `src\main\webapp\`
![image-20220118003805398](张博凯的Java学习笔记.assets/image-20220118003805398.png)
删除 Web Resource Directory 重新加载
![image-20220118004012885](张博凯的Java学习笔记.assets/image-20220118004012885.png)
![image-20220118004227647](张博凯的Java学习笔记.assets/image-20220118004227647.png)
即可
![image-20220118004559833](张博凯的Java学习笔记.assets/image-20220118004559833.png)
2022-01-20 14:55:29 +08:00
#### 创建SpringIOC Maven项目
<span id="创建SpringIOC_Maven项目"></span>
##### 创建项目
![image-20220118002605490](张博凯的Java学习笔记.assets/image-20220118002605490.png)
![image-20220119185937940](张博凯的Java学习笔记.assets/image-20220119185937940.png)
##### 添加依赖
###### 添加Spring依赖
core(核心依赖)、beans(组件)、aop(AOP处理)、context(context组件)
<span id="spring依赖"></span>
Spring Context
https://mvnrepository.com/artifact/org.springframework/spring-context/5.2.19.RELEASE
```xml
<!-- 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](张博凯的Java学习笔记.assets/image-20220119201948073.png)
###### 添加lombok依赖
[传送门](#Lombok依赖)
##### 创建Spring核心配置文件
<span id="创建Spring核心配置文件"></span>
> Spring核心配置文件“告诉Spring容器创建什么对象”给对象属性赋什么值
在resources目录下创建applicationContext.xml文件备注名称可以自定义但是建议一般使用applicationContext.xml
![image-20220119213008054](张博凯的Java学习笔记.assets/image-20220119213008054.png)
> 第一次需要新建模板,如图
>
> ![image-20220119212825415](张博凯的Java学习笔记.assets/image-20220119212825415.png)
src/main/resources/applicationContext.xml
```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](张博凯的Java学习笔记.assets/image-20220119215150497.png)
![image-20220119215211686](张博凯的Java学习笔记.assets/image-20220119215211686.png)
2022-01-20 14:52:20 +08:00
### 连接数据库
##### IDEA连接MySQL
![image-20220116172510338](张博凯的Java学习笔记.assets/image-20220116172510338.png)
![image-20220116172545108](张博凯的Java学习笔记.assets/image-20220116172545108.png)
注意:
![image-20220116172803614](张博凯的Java学习笔记.assets/image-20220116172803614.png)
填写用户名&密码
![image-20220116172859540](张博凯的Java学习笔记.assets/image-20220116172859540.png)
连接之后默认值会显示一个数据库
![image-20220117100543999](张博凯的Java学习笔记.assets/image-20220117100543999.png)
选择其他数据库
![image-20220117100636687](张博凯的Java学习笔记.assets/image-20220117100636687.png)
![image-20220117100732206](张博凯的Java学习笔记.assets/image-20220117100732206.png)
## Java
### Lombok
> Lombok是简化javabean实体类可以使用注解简化代码
#### 导入依赖
<span id='Lombok依赖'></span>
https://mvnrepository.com/artifact/org.projectlombok/lombok
```xml
<!-- 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](张博凯的Java学习笔记.assets/image-20220118005337949.png)
#### 常用注解
1. @Data
> 相当于实体类封装的get和set方法
2. @Setter
> 相当于实体类封装的set方法
3. @Getter
> 相当于实体类封装的get方法
4. @NoArgsConstructor
> 相当于无参构造函数
5. @AllArgsConstructor
> 相当于有参构造函数
## Javaweb
### 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](张博凯的Java学习笔记.assets/image-20220116164807251.png)
下载后放入项目web/lib文件夹下
![image-20220116164942847](张博凯的Java学习笔记.assets/image-20220116164942847.png)
添加jar包
![image-20220116165411807](张博凯的Java学习笔记.assets/image-20220116165411807.png)
创建User.java并编写Java代码
全限定名com.mysql.jdbc.Driver是这样复制出来的
![image-20220116165755225](张博凯的Java学习笔记.assets/image-20220116165755225.png)
![image-20220116165818350](张博凯的Java学习笔记.assets/image-20220116165818350.png)
```java
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](张博凯的Java学习笔记.assets/image-20220117101802262.png)
#### Maven
<span id='mysql依赖'></span>
从网上下载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](张博凯的Java学习笔记.assets/image-20220117143510876.png)
![image-20220117143541787](张博凯的Java学习笔记.assets/image-20220117143541787.png)
```xml
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
```
### 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
2022-01-20 14:55:29 +08:00
<span id="mybatis依赖"></span>
添加mybatis依赖目前官网最新版是3.5.9
2022-01-20 14:52:20 +08:00
https://mvnrepository.com/artifact/org.mybatis/mybatis
```xml
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.9</version>
</dependency>
```
同时还需要添加
- MySQL依赖[点击文档内跳转](#mysql依赖)
- Lombok依赖[点击文档内跳转](#Lombok依赖)
##### 创建MyBatis配置文件
在resources目录下创建mybatis-config.xml文件
```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创建自定义模板
<span id='IDEA自定义模板'></span>
![image-20220118103532515](张博凯的Java学习笔记.assets/image-20220118103532515.png)
Name: `mybatis-config`
Extension: `xml`
File Name: `mybatis-config.xml`
勾选 Enable Live Templates 激活当前模板
模板代码👇
```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>
```
出现如图问题解决方案
![image-20220118104342493](张博凯的Java学习笔记.assets/image-20220118104342493.png)
![image-20220118104541497](张博凯的Java学习笔记.assets/image-20220118104541497.png)
###### 在mybatis-config.xml中进行数据库连接信息配置
> environments标签中可以定义多个environment每个environment标签可以定义一套连接配置default属性用来指定使用哪个environment标签
>
> transactionManager标签用于配置数据库管理方式默认是JDBC
>
> dataSource标签用于配置数据库的连接信息
配置模板idea中Maven配置好后输入 `<en` 回车即可自动补全)
```xml
<configuration>
<environments default="">
<environment id="">
<transactionManager type=""></transactionManager>
<dataSource type=""></dataSource>
</environment>
</environments>
</configuration>
```
配置信息
```xml
<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文件中[传送门](#使用db.properties文件进行数据库配置)
> 如果出现了中文乱码在jdbc:mysql://localhost:3306/mydb后面添加 `characterEncoding=utf-8`
##### MyBatis框架使用
> 案例:学生信息的数据库操作
###### 创建数据库表
创建一个数据库创建student数据表并插入数据
```sql
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
```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
```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文件模板如下[参考](#IDEA自定义模板)
>
> ```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>
>
> </mapper>
> ```
- **创建StudentMapper.xml文件**
src/main/resources/mappers/StudentMapper.xml
> 使用上方的mapper文件模板创建
- **StudentDao.java与StudentMapper.xml保持一致将StudentDao.java接口改为StudentMapper.java**
###### 在映射文件中对DAO中的方法进行实现
```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文件相当于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`, `...` 实现
>
> 如上方代码中的实现方式
>
> ```xml
> <select id="login" resultType="org.example.entity.Student">
> select * from student where stuName=#{arg0} and stuGender=#{arg1}
> </select>
> ```
>
> 2. `param1`, `param2`, `param3`, `...` 实现
>
> ```xml
> <select id="login" resultType="org.example.entity.Student">
> select * from student where stuName=#{param1} and stuGender=#{param2}
> </select>
> ```
>
> 3. 使用注解配置(推荐)
>
> 首先在Dao接口中添加注解如下
>
> ```java
> /**
> * 查询
> * @param stuName
> * @param stuGender
> * @return
> */
> public Student login(@Param("name") String stuName, @Param("pwd") String stuGender);
> ```
>
> 然后在xml文件中如下配置
>
> ```xml
> <select id="login" resultType="org.example.entity.Student">
> select * from student where stuName=#{name} and stuGender=#{pwd}
> </select>
> ```
目前为止,项目的结构应该如下
![image-20220118161808106](张博凯的Java学习笔记.assets/image-20220118161808106.png)
###### 将映射文件添加到主配置文件中
在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>
```
##### 单元测试
2022-01-20 14:55:29 +08:00
> JUnit单元测试
2022-01-20 14:52:20 +08:00
###### 添加单元测试的依赖
2022-01-20 14:55:29 +08:00
<span id="junit依赖"></span>
2022-01-20 14:52:20 +08:00
https://mvnrepository.com/artifact/junit/junit/4.12
```xml
<!-- 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
```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](张博凯的Java学习笔记.assets/image-20220118172524278.png)
![image-20220118172654675](张博凯的Java学习笔记.assets/image-20220118172654675.png)
查询成功
![image-20220118182635014](张博凯的Java学习笔记.assets/image-20220118182635014.png)
查询所有成功
![image-20220118190921546](张博凯的Java学习笔记.assets/image-20220118190921546.png)
> [输出]
>
> ```java
> [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标签
<span id='使用db.properties文件进行数据库配置'></span>
> 用于设置键值对,或者加载属性文件
在resources目录下创建db.properties文件配置键值对
src/main/resources/db.properties
```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>` 之前
```xml
<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用于给实体类取别名在映射文件中可以直接使用别名来替换实体类的全限定名
```xml
<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插件
> 插件标签:向分页插件的使用
```xml
<configuration>
<plugins>
<plugin interceptor=""></plugin>
</plugins>
</configuration>
```
###### mappers标签
> 加载映射文件配置
```xml
<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
```xml
<!-- 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中配置
```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](张博凯的Java学习笔记.assets/image-20220118232516699.png)
#### log4j日志打印
> 查看日志信息
##### log4j依赖
https://mvnrepository.com/artifact/log4j/log4j/1.2.17
```xml
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
```
##### 导入log4j.propertites文件
2022-01-20 14:55:29 +08:00
[log4j.properties](张博凯的Java学习笔记.assets\file\log4j.properties)
2022-01-20 14:52:20 +08:00
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
```
#### 数据表关联映射
> 至少两张表,表与表之间有关系
>
> 映射关系:一对一,一对多,多对一,多对多
##### 一对一关系
> 实例:用户表—用户详情表
>
> **查询用户的姓名、密码、年龄、地址、电话号码**
>
> ```sql
> # 两种方式:
> 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;
> ```
###### 数据库设计
用户信息表
```sql
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;
```
用户详情表
```sql
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
```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
```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
```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
```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>`
>
> ```xml
> <configuration>
2022-01-20 14:55:29 +08:00
> <mappers>
> <mapper resource="mappers/UserMapper.xml"></mapper>
> </mappers>
2022-01-20 14:52:20 +08:00
> </configuration>
> ```
###### 测试类
src/test/java/org/example/test/UserTest.java
```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查询该班级的信息及班级下的所有学生的信息**
>
>```sql
>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;
>```
###### 创建数据库表
<span id="一对多关系创建数据表"></span>
班级表
```sql
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;
```
学生表
```sql
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
```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
```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
```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
```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>`
>
> ```xml
> <configuration>
2022-01-20 14:55:29 +08:00
> <mappers>
> <mapper resource="mappers/StudentMapper.xml"></mapper>
> <mapper resource="mappers/ClassesMapper.xml"></mapper>
> </mappers>
2022-01-20 14:52:20 +08:00
> </configuration>
> ```
###### 测试类
src/test/java/org/example/test/ClassesTest.java
```java
...
ClassesMapper mapper = sqlSession.getMapper(ClassesMapper.class);
Classes classes = mapper.showClasses(1);
System.out.println(classes);
...
```
输出结果
![image-20220119152029499](张博凯的Java学习笔记.assets/image-20220119152029499.png)
##### 多对一关系
> 案例学生n: 班级(1)
>
> **通过学生id查询该学生所在班级的信息**
>
> ```sql
> 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
```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
```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
```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
```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>`
>
> ```xml
> <configuration>
2022-01-20 14:55:29 +08:00
> <mappers>
> <mapper resource="mappers/StudentMapper.xml"></mapper>
> <mapper resource="mappers/ClassesMapper.xml"></mapper>
> </mappers>
2022-01-20 14:52:20 +08:00
> </configuration>
> ```
###### 测试类
src/test/java/org/example/test/StudentTest.java
```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)
>
> 注意:一般对于多对多的关系都会有一个中间表,对另外两张表进行关系。
>
> ```sql
> # 查询学生时,同时查询该学生选择的课程
> # 三张表联合查询 inner join on
>
> select * from student s inner join grades g inner join course c on
2022-01-20 14:55:29 +08:00
> s.sid=g.sid and g.course_id=c.course_id;
2022-01-20 14:52:20 +08:00
>
2022-01-20 14:55:29 +08:00
> select * from student s,grades g,course c where s.sid=g.sid and g.course_id=c.course_id;
2022-01-20 14:52:20 +08:00
> ```
###### 数据库表设计
课程表
```sql
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;
```
学生表
```sql
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;
```
中间表
```sql
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;
```
2022-01-20 14:55:29 +08:00
###### 创建实体类
学生类
src/main/java/org/example/entity/Student.java
```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
```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
```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
```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>`
>
> ```xml
> <configuration>
> <mappers>
> <mapper resource="mappers/StudentMapper.xml"></mapper>
> </mappers>
> </configuration>
> ```
###### 测试类
src/test/java/org/example/test/StudentTest.java
```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. 在多的一方添加集合,一的一方添加对象。
2022-01-20 14:52:20 +08:00
2022-01-20 14:55:29 +08:00
2. 如果实体类中的属性与数据库的字段名不一致时mapper文件中选择resultmap映射
2022-01-20 14:52:20 +08:00
#### 动态SQL
2022-01-20 14:55:29 +08:00
##### 什么是动态SQL
2022-01-20 14:52:20 +08:00
2022-01-20 14:55:29 +08:00
> 根据查询条件动态完成SQL拼接
2022-01-20 14:52:20 +08:00
2022-01-20 14:55:29 +08:00
###### 创建数据库表
2022-01-20 14:52:20 +08:00
2022-01-20 14:55:29 +08:00
```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
```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
```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
<?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>`
2022-01-20 14:52:20 +08:00
>
2022-01-20 14:55:29 +08:00
> ```xml
> <configuration>
> <mappers>
> <mapper resource="mappers/MemberMapper.xml"></mapper>
> </mappers>
> </configuration>
> ```
###### 测试类
src/test/java/org/example/test/MemberTest.java
```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);
}
...
```
```java
...
// 修改
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](张博凯的Java学习笔记.assets\file\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](张博凯的Java学习笔记.assets/image-20220119185108127.png)
> 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](张博凯的Java学习笔记.assets/image-20220119190419786.png)
#### Spring IOC和DI的使用
> IOC控制反转可以完成对象的创建
>
> DI对象属性赋值对象管理
##### Spring IOC基于XML
###### 创建SpringIOC Maven项目
[创建SpringIOC Maven项目](#创建SpringIOC_Maven项目)
###### 创建实体类
src/main/java/org/example/entity/User.java
```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
```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
<?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
```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
```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
```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
```java
public class Book {
private int bookId;
private String bookName;
private String author;
}
```
方式1在property标签中通过ref引用Spring容器中的另一个对象
src/main/resources/applicationContext.xml
```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
<?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
```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
<?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
```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](张博凯的Java学习笔记.assets/image-20220119224034975.png)
###### 构造器注入
**简单类型**
假设有实体类
src/main/java/org/example/entity/User.java
```java
public class User {
private int id;
private String name;
private int age;
private String address;
}
```
src/main/resources/applicationContext.xml
```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
```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
```java
public class Book {
private int bookId;
private String bookName;
private String author;
}
```
src/main/resources/applicationContext.xml
```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
<!-- 修改前 -->
<?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
<!-- 配置好后 -->
<?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标签的作用
>
> ```java
> @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
```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
```java
@Data
@AllArgsConstructor
@NoArgsConstructor
@Service
public class Book {
@Value("3")
private int bookId;
@Value("Java编程")
private String bookName;
@Value("dd")
private String author;
}
```
测试
```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) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) context.getBean("user");
System.out.println(user);
}
}
```
输出
```bash
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](张博凯的Java学习笔记.assets/image-20220119234814230.png)
###### 导入依赖
需要导入的依赖:[MyBatis](#mybatis依赖)、[MySQL](#mysql依赖)、[Lombok](#Lombok依赖)、[JUnit](#junit依赖)、[Spring](#spring依赖)、MyBatis Spring、Druid
**MyBatis Spring依赖**
https://mvnrepository.com/artifact/org.mybatis/mybatis-spring/2.0.6
```xml
<!-- 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
```xml
<!-- 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
```xml
<!-- 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**
https://mvnrepository.com/artifact/org.springframework/spring-jdbc/5.2.19.RELEASE
```xml
<!-- 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
<?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
```properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb?characterEncoding=utf-8
username=root
password=111111
```
###### 创建Spring核心配置文件
在resources目录下创建applicationContext.xml文件[传送门](#创建Spring核心配置文件)
>当Spring和MyBatis整合后MyBatis核心配置文件mybatis-config.xml可以不要
```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>
```
###### 数据库建表语句
用户表
```sql
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
```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
```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
<?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
```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);
}
}
}
```
运行结果
![image-20220120005858883](张博凯的Java学习笔记.assets/image-20220120005858883.png)
2022-01-20 14:52:20 +08:00
### SpringMVC框架
> Web框架Servlet角色
#### Thymeleaf
> 模板引擎
## 提升
### 前后端分离
Springboot + Vue
### 微服务(架构师)
Spring Cloud + ES + Redis