川职院-课堂笔记(2)5-27日起
每日笔记整理:
2022-05-27
过滤器
依赖于servlet容器。在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。
使用过滤器的目的是用来做一些过滤操作,获取我们想要获取的数据,比如:在过滤器中修改字符编码;在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等
总之过滤器实际上就是对所有请求进行过滤操作,获取请求携带的数据或者修改请求的某些参数。
Spring-字符编码过滤器配置
<!-- 字符编码过滤器 -->
<filter>
<filter-name>characterEncodingFilter</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>
<init-param>
<!-- 定义是否使用强制字符集(设置为true代表请求和响应都必须要转换字符集) -->
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
自定义过滤器
(1)创建一个自定义过滤器类,实现Filter接口
package com.huawei.sys.filter;
import javax.servlet.*;
import java.io.IOException;
/**
* 测试过滤器类
* 2022/5/27
*/
public class MyFilter implements Filter {
/**
* init 方法
* 过滤器初始化的回调方法
* 当容器初始化,过滤器也初始化,且只会初始化一次
* @param filterConfig
* @throws ServletException
*/
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("MyFilter-初始化!");
}
/**
* doFilter 方法,拦截到请求后会执行的方法(每次请求一旦被拦截都会被调用)
* @param servletRequest 网络io请求流
* @param servletResponse 网络io响应流
* @param filterChain filterChain.doFilter();//让过滤器通过拦截,放行请求
* @throws IOException
* @throws ServletException
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("过滤器被调用!");
filterChain.doFilter(servletRequest,servletResponse);//放行请求
}
/**
* destroy 过滤器销毁的回调
* 当容器销毁,过滤器就随之销毁
*/
@Override
public void destroy() {
System.out.println("过滤器-销毁!");
}
}
demo:拦截请求返回html代码
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("过滤器被调用!");
PrintWriter writer = servletResponse.getWriter();
servletResponse.setCharacterEncoding("UTF-8");
String html = "<html>" +
"<head>" +
"<meta charset='UTF-8' /></head>" +
"<body>" +
"请求被过滤器阻止!</body></html>";
writer.println(html);
//filterChain.doFilter(servletRequest,servletResponse);//放行请求
}
(2)在web.xml文件中配置过滤器
<!-- 自定义配置过滤器 -->
<filter>
<filter-name>myFilter</filter-name>
<filter-class>com.huawei.sys.filter.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<url-pattern>/user/*</url-pattern>
</filter-mapping>
SpringMVC拦截器
是基于Java的jdk动态代实现的,实现HandlerInterceptor接口。不依赖于servlet容器,拦截器针对于contraller方法,并且能获取到所有的类,对类里面所有的方法实现拦截,粒度更小,拦截器中>可以注入service,也可以调用业务逻辑。
自定义拦截器方法
(1)定义一个类实现HandlerInterceptor接口
package com.huawei.sys.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 自定义拦截器
* 2022/5/27
*/
public class MyInterceptor implements HandlerInterceptor {
/**
* 在controller方法调用之前回调
* @param request Http请求对象
* @param response Http响应对象
* @param handler 当前拦截器对象的实例
* @return 需要返回一个布尔值:
* true -》 拦截器放行
* false -》 拦截器阻止通行
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("1.在controller方法调用之前回调");
return true;
}
/**
* 在调用完成controller方法之后返回数据之前回调
* @param request Http请求对象
* @param response Http响应对象
* @param handler 当前拦截器对象的实例
* @param modelAndView 视图解析器需要接收的对象,可以定义要跳转的逻辑视图名以及包含要传送的数据
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("2.在调用完成controller方法之后返回数据之前回调");
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
/**
* 当整个controller方法执行完成,且视图或者数据成功返回后回调
* @param request Http请求对象
* @param response Http响应对象
* @param handler 当前拦截器对象的实例
* @param ex 整个方法结束执行后可能没有成功会抛出异常,返回的异常对象
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("3.当整个controller方法执行完成,且视图或者数据成功返回后回调");
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
(2)dispacther-servlet.xml配置文件中配置拦截器
<!-- 自定义拦截器配置 -->
<!-- 拦截器定义标签 -->
<mvc:interceptors>
<!-- 拦截器的实例 -->
<!-- 综合拦截器(所有的请求都会先进入当前拦截器) 一般不写 -->
<!-- <bean class="com.huawei.sys.interceptor.MyInterceptor" />-->
<!-- 配置拦截器的拦截规则 <mvc:interceptor>可以配置多个,代表多个规则 -->
<mvc:interceptor>
<!-- 配置拦截的路径 -->
<mvc:mapping path="/user/**" />
<!-- 综合拦截器完成之后才会进入,下面的拦截器 -->
<bean class="com.huawei.sys.interceptor.MyInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
2022-05-29
SpringMVC文件上传
(1)引入依赖
<!-- 文件上传下载-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
(2)在dispachter-servlet.xml配置文件中配置文件上传选项
<!-- 文件上传的配置 id值必须要叫multipartResolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" >
<!-- 单次请求做大上传文件大小 -->
<property name="maxUploadSize" value="5000000" />
<!-- 文件字节码编解码方式 -->
<property name="defaultEncoding" value="UTF-8" />
</bean>
(3)前端编写表单上传文件
<!-- 文件上传表单
1.请求方法必须是post请求
2.enctype属性multipart/form-data,代表有媒体元素上传
-->
<form action="${pageContext.request.contextPath}/file/uploadOneFile" method="post" enctype="multipart/form-data">
<!-- 文件上传的表单 -->
<input type="file" name="uploadFile" />
<!-- 其他字段:文件描述 autocomplete="false" 不会出现历史记录提示框-->
<input type="text" autocomplete="false" name="descs" />
<input type="submit" value="文件上传" />
</form>
(4)后端编写一个接收文件上传的pojo对象类
package com.huawei.sys.dto;
import lombok.Data;
import org.springframework.web.multipart.MultipartFile;
/**
* 用于接收上传文件的类
* 2022/5/29
*/
@Data
public class FileDto {
private MultipartFile uploadFile;//上传的文件对象
private String descs;//文件描述字段
}
(5)编写Controller方法接收文件上传的请求
package com.huawei.sys.controller;
import com.huawei.sys.dto.FileDto;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* 文件上传和下载操作类
* 2022/5/29
*/
@Controller
@RequestMapping("/file")
public class FileController {
@RequestMapping(value = "/uploadOneFile",method = RequestMethod.POST)
@ResponseBody
public Map<String,Object> uploadOneFile(FileDto file){
//默认保存上传文件的服务器地址
String savePath = "F://fileupload";
//1.取得上传的文件对象
MultipartFile uploadFile = file.getUploadFile();
//2.获取文件的名称
String originalFilename = uploadFile.getOriginalFilename();
System.out.println("上传的文件名:"+originalFilename);
//3.将文件保存到目标路径中(封装一个File文件对象)
/**
* new File(文件保存的文件位置,文件名称(一定要带后缀))
*/
File saveFile = new File(savePath,originalFilename);
//返回数据的Map对象
Map<String,Object> resMap = new HashMap<>();
//4.调用MulitpartFile对象的tansferTo方法进行文件上传
try {
uploadFile.transferTo(saveFile);
resMap.put("code","0000");
resMap.put("msg","文件上传成功!");
} catch (IOException e) {
System.err.println("文件上传出错!");
resMap.put("code","9999");
resMap.put("msg","文件上传失败!");
e.printStackTrace();
}
return resMap;
}
}
文件下载
(1)Servlet3.0的方法下载文件
/**
* 下载文件(单文件下载)
* @param fileName 要下载的文件名称
* @param response 响应对象
* @return
*/
@RequestMapping("/fileDownLoad")
public String downLoadFile(String fileName, HttpServletResponse response) throws IOException {
//服务器文件保存位置
String savePath = "F://fileupload";
//1.设置响应头的参数
response.setHeader("Content-Type","application/x-msdownload");
response.setHeader("Content-Disposition","attachment;fileName="+ URLEncoder.encode(fileName,"UTF-8"));
//2.文件字节流读取文件
String downLoadFilePath = savePath + "//"+fileName;//拼装出要下载的文件路径
//获取文件字节输入流对象(服务中获取文件信息的io流)
FileInputStream fileInputStream = new FileInputStream(downLoadFilePath);
//3.通过响应对象获取输出流对象(服务器输出到客户端的io流)
ServletOutputStream outputStream = response.getOutputStream();
//4.通过io流输出文件
//创建一个字节数组
byte [] fileByte = new byte[fileInputStream.available()];
fileInputStream.read(fileByte);//把读取的内容赋值到字节数组中
//通过输出流输出
outputStream.write(fileByte);
//输出流
outputStream.flush();
outputStream.close();
fileInputStream.close();
return null;
}
(2)SpringMVC的使用commons-io的下载方式
/**
* SpringMVC文件下载
* @param fileName 要下载的文件名称
* @return
*/
@RequestMapping("/filed2")
public ResponseEntity<byte []> downloadFile2(String fileName) throws IOException {
//服务器文件保存位置
String savePath = "F://fileupload";
//1.创建一个Http响应头对象
HttpHeaders headers = new HttpHeaders();
//2.创建文件对象(要下载的文件)
File file = new File(savePath,fileName);
//设置响应头的参数
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData("attachment", URLEncoder.encode(fileName,"UTF-8"));
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),
headers, HttpStatus.CREATED);
}
2022-05-30
Spring+SpringMVC搭建流程
(1)maven依赖整理
<?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>com.huawei</groupId>
<artifactId>CZ_SpringMVCDemo1</artifactId>
<version>1.0.0</version>
<!-- tomcat运行的就是war包 -->
<packaging>war</packaging>
<name>CZ_SpringMVCDemo1 Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<!-- Spring版本号 -->
<springBBH>5.2.3.RELEASE</springBBH>
</properties>
<dependencies>
<!-- springMVC、Spring相关依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${springBBH}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
<!--测试 @Test在方法上-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!--日志 类上加上@Sl4j注解可以在类内部生成一个log对象-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>
<!--J2EE HttpServletRequest、XXXXXResponse-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!--mysql驱动包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
<!-- Fastjoson JSON处理工具 jackson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.78</version>
</dependency>
<!-- 文件上传下载-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<!-- 开发工具lombok:自动提供构造器、getter、setter方法等等注解 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>provided</scope>
</dependency>
<!-- @ResponesBody的新解决方案-jackson包 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.12.3</version>
</dependency>
<!-- 集成SpringMVC实现@ResponesBody注解的方法返回json数据 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.3</version>
</dependency>
<!-- 数据校验 -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>3.1.0.CR2</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.1.0.Final</version>
</dependency>
</dependencies>
<!-- maven工具构造配置 -->
<build>
<finalName>CZ_SpringMVCDemo1</finalName>
<!-- maven静态资源打包 -->
<resources>
<resource>
<directory>src/main/resources</directory>
<!-- 指定路径下的指定后缀的文件也会进行打包 -->
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.js</include>
<include>**/*.css</include>
<include>**/*.html</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.js</include>
<include>**/*.css</include>
<include>**/*.html</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
(2)配置web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<!-- 项目名称 -->
<display-name>Archetype Created Web Application</display-name>
<!-- 容器初始化参数 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml</param-value>
</context-param>
<!-- 容器加载监听器(加载配置文件时必须要写) -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- SpringMVC的前端控制器Servlet -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:dispatcher-servlet.xml</param-value>
</init-param>
<!-- 当容器加载时就加载当前servlet -->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 将请求的url地址映射对应的Servlet -->
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- HTTP请求REST的配置 如果拦截到delete、put请求就会把他们封装成post请求进行提交-->
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 字符编码过滤器 -->
<filter>
<filter-name>characterEncodingFilter</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>
<init-param>
<!-- 定义是否使用强制字符集(设置为true代表请求和响应都必须要转换字符集) -->
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
(3)视图解析器配置文件必要配置项目
<?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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 自动扫描com.huawei路径下的所有被@Controller注解、@Component注解、@Service的类自动注册实例到ioc容器中国 -->
<context:component-scan base-package="com.huawei" />
<!-- 配置视图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- 静态资源文件夹目录配置 -->
<mvc:annotation-driven />
<mvc:resources location="/static/" mapping="/static/**" />
<!-- 文件上传的配置 id值必须要叫multipartResolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" >
<!-- 单次请求做大上传文件大小 -->
<property name="maxUploadSize" value="5000000" />
<!-- 文件字节码编解码方式 -->
<property name="defaultEncoding" value="UTF-8" />
</bean>
<!-- 推荐编写的一个格式化工具:字符串转日期 -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="formatters">
<!-- 可以注册多个自定义的String转换器 -->
<set>
<bean class="com.huawei.sys.config.String2DateFormatter" />
</set>
</property>
</bean>
</beans>
(4)包结构定义规则
父级:公司域名反写(com.huawei)
业务包名(sys)
控制器层(controller)
数据转换层(dto)
业务接口层(service)
业务接口实现层(impl)
工具包(util)
过滤器(filters)
拦截器(interceptors)
配置类(configs)
构建第一个MyBatis项目
(1)在resouces目录下创建一个mybatis配置文件
名称可以自定义
<?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 default="test">
<environment id="test">
<transactionManager type="JDBC"></transactionManager> <!-- 事务管理类型:JDBC、MANAGED -->
<dataSource type="POOLED"> <!-- 数据源类型:POOLED、UNPOOLED、JNDI -->
<property name="driver" value="com.mysql.cj.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/huawei?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC" />
<property name="username" value="root" />
<property name="password" value="root123456" />
</dataSource>
</environment>
</environments>
</configuration>
(2)创建一个数据表
如:我创建一个学生表
CREATE TABLE `student` (
`code` varchar(20) NOT NULL COMMENT '编号',
`name` varchar(20) COMMENT '姓名',
`age` int(3) COMMENT '年龄',
PRIMARY KEY (`code`)
) ;
(3)创建一个与数据库字段相同的映射javaPOJO类
package com.huawei.dto;
import lombok.Data;
/**
* 与数据库Student表实现映射的类
* 2022/5/30
*/
@Data
public class StudentDo {
private String code;
private String name;
private Integer age;
}
(4)在项目路径中创建一个dao包
dao包就是存放myBatis操作的代码
在dao包中创建接口,接口的目的就是解耦sql操作与业务操作之间的关系,命名规则为:业务+Mapper
/**
* Mybatis映射接口层
* 2022/5/30
*/
public interface StudentMapper {
//根据学生编号查询学生数据
StudentDo getStudentByCode(String code) throws IOException;
}
(5)编写映射xml文件
在项目目录下创建文件夹mybatis,将文件夹设置为资源文件路径
创建xml文件,命名规则为:业务名+Mapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 当前学习阶段 namespace值可自定义 -->
<mapper namespace="StudentMapXML">
<!-- 查询:根据学生编号查询学生数据 parameterType:代表的是参数类型 resultType:数据返回的类型-->
<select id="getStudentByCode" parameterType="java.lang.String" resultType="com.huawei.dto.StudentDo">
select * from student where code = #{code};
</select>
</mapper>
#{}
是预编译处理,像传进来的数据会加个" "(#
将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号)
${}
就是字符串替换。直接替换掉占位符。$方式一般用于传入数据库对象,例如传入表名.
使用${}
的话会导致 sql 注入。所以为了防止 SQL 注入,能用#{}
的不要去用${}
果非要用${}
的话,那要注意防止 SQL 注入问题,可以手动判定传入的变量,进行过滤,一般 SQL 注入会输入很长的一条 SQL 语句
(6)在mybatis配置文件中配置xml映射文件
<!-- 编写在configuration标签中 -->
<!-- 加载映射文件 mapper -->
<mappers>
<mapper resource="student/StudentMapper.xml" />
</mappers>
(7)编写接口的实现类
package com.huawei.dao;
import com.huawei.dto.StudentDo;
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 java.io.IOException;
import java.io.InputStream;
/**
* mybatis自定义接口的实现类
* 2022/5/30
*/
public class StudentMapperImpl implements StudentMapper{
@Override
public StudentDo getStudentByCode(String code) throws IOException {
//1.加载mybatis配置文件-得到输入流对象
InputStream resourceAsStream = Resources.getResourceAsStream("myBatisConfig.xml");
//2.根据配置文件流对象加载出SqlSessionFactory工厂对象(SqlSessionFactory生产连接对象)
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//3.获取数据库连接-SqlSession (类似JDBC中的Connect对象)
SqlSession sqlSession = factory.openSession();
//4.通过数据库连接对象调用mybatis映射文件中的sql方法
StudentDo studentDo = sqlSession.selectOne("StudentMapXML.getStudentByCode", code);
System.out.println(studentDo);
//5.归还连接(关闭连接)
sqlSession.close();
return studentDo;
}
}
入门版增删改查语句
(1)接口中方法定义
/**
* Mybatis映射接口层
* 2022/5/30
*/
public interface StudentMapper {
//根据学生编号查询学生数据
StudentDo getStudentByCode(String code) throws IOException;
//查询出多行学生数据
List<StudentDo> getStudentList() throws IOException;
//新增学生信息(增、删、改-》返回的都是受影响的行数)
int addStudent(StudentDo student) throws IOException ;
//修改学生信息
int updateStudent(StudentDo student) throws IOException ;
//删除学生信息
int deleteStudent(String code) throws IOException ;
}
(2)xml映射文件sql编写
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="StudentMapXML">
<!-- 查询:根据学生编号查询学生数据 parameterType:代表的是参数类型 resultType:数据返回的类型-->
<select id="getStudentByCode" parameterType="java.lang.String" resultType="com.huawei.dto.StudentDo">
select * from student where code = #{code};
</select>
<!-- 查询所有学生信息(多行数据) -->
<select id="getStudentList" resultType="com.huawei.dto.StudentDo">
select * from student
</select>
<!-- 新增数据:添加学生信息 -->
<insert id="addStudent" parameterType="com.huawei.dto.StudentDo" >
INSERT into student VALUES(#{code},#{name},#{age})
</insert>
<!-- 修改数据:修改学生信息 -->
<update id="updateStudent" parameterType="com.huawei.dto.StudentDo">
update student set name=#{name},age=#{age} where code=#{code}
</update>
<!-- 删除数据:删除学生信息 -->
<delete id="deleteStudent" parameterType="java.lang.String">
delete from student where code = #{code}
</delete>
</mapper>
(3)接口实现类实现方法
package com.huawei.dao;
import com.huawei.dto.StudentDo;
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 java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* mybatis自定义接口的实现类
* 2022/5/30
*/
public class StudentMapperImpl implements StudentMapper{
@Override
public StudentDo getStudentByCode(String code) throws IOException {
//1.加载mybatis配置文件-得到输入流对象
InputStream resourceAsStream = Resources.getResourceAsStream("myBatisConfig.xml");
//2.根据配置文件流对象加载出SqlSessionFactory工厂对象(SqlSessionFactory生产连接对象)
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//3.获取数据库连接-SqlSession (类似JDBC中的Connect对象)
SqlSession sqlSession = factory.openSession();
//4.通过数据库连接对象调用mybatis映射文件中的sql方法
StudentDo studentDo = sqlSession.selectOne("StudentMapXML.getStudentByCode", code);
System.out.println(studentDo);
//5.归还连接(关闭连接)
sqlSession.close();
return studentDo;
}
@Override
public List<StudentDo> getStudentList() throws IOException {
//1.加载mybatis配置文件-得到输入流对象
InputStream resourceAsStream = Resources.getResourceAsStream("myBatisConfig.xml");
//2.根据配置文件流对象加载出SqlSessionFactory工厂对象(SqlSessionFactory生产连接对象)
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//3.获取数据库连接-SqlSession (类似JDBC中的Connect对象)
SqlSession sqlSession = factory.openSession();
List<StudentDo> objects = sqlSession.selectList("StudentMapXML.getStudentList");
for(StudentDo studentDo:objects){
System.out.println(studentDo);
}
return objects;
}
@Override
public int addStudent(StudentDo student) throws IOException {
//1.加载mybatis配置文件-得到输入流对象
InputStream resourceAsStream = Resources.getResourceAsStream("myBatisConfig.xml");
//2.根据配置文件流对象加载出SqlSessionFactory工厂对象(SqlSessionFactory生产连接对象)
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//3.获取数据库连接-SqlSession (类似JDBC中的Connect对象)
SqlSession sqlSession = factory.openSession();
int insert = sqlSession.insert("StudentMapXML.addStudent", student);
System.out.println("新增【"+insert+"】行");
sqlSession.commit();//提交事务
return 0;
}
@Override
public int updateStudent(StudentDo student) throws IOException {
//1.加载mybatis配置文件-得到输入流对象
InputStream resourceAsStream = Resources.getResourceAsStream("myBatisConfig.xml");
//2.根据配置文件流对象加载出SqlSessionFactory工厂对象(SqlSessionFactory生产连接对象)
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//3.获取数据库连接-SqlSession (类似JDBC中的Connect对象)
SqlSession sqlSession = factory.openSession();
int update = sqlSession.update("StudentMapXML.updateStudent", student);
System.out.println("修改【"+update+"】行");
sqlSession.commit();//提交事务
return 0;
}
@Override
public int deleteStudent(String code) throws IOException {
//1.加载mybatis配置文件-得到输入流对象
InputStream resourceAsStream = Resources.getResourceAsStream("myBatisConfig.xml");
//2.根据配置文件流对象加载出SqlSessionFactory工厂对象(SqlSessionFactory生产连接对象)
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//3.获取数据库连接-SqlSession (类似JDBC中的Connect对象)
SqlSession sqlSession = factory.openSession();
int delete = sqlSession.delete("StudentMapXML.deleteStudent", code);
System.out.println("删除【"+delete+"】行");
sqlSession.commit();//提交事务
return 0;
}
}
改写为sqlSession获取接口实现的实例
调用mybatis映射xml中的sql方法,改写为面向接口调用的方法
@Override
public List<StudentDo> getStudentList() throws IOException {
//1.加载mybatis配置文件-得到输入流对象
InputStream resourceAsStream = Resources.getResourceAsStream("myBatisConfig.xml");
//2.根据配置文件流对象加载出SqlSessionFactory工厂对象(SqlSessionFactory生产连接对象)
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//3.获取数据库连接-SqlSession (类似JDBC中的Connect对象)
SqlSession sqlSession = factory.openSession();
//4.获取接口对象 !!!!!!! 重点改变的位置 !!!!!!!
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<StudentDo> studentList = mapper.getStudentList();
return studentList;
}
所以在这基础上,我们发现可以不用编写接口实现层,直接让mybatis完成实现调用
比如:在测试类中我们把接口实现层删掉,直接获取接口对象调用方法,它就会自动关联调用xml中的sql方法了
@Test
public void test1() throws IOException {
//1.加载mybatis配置文件-得到输入流对象
InputStream resourceAsStream = Resources.getResourceAsStream("myBatisConfig.xml");
//2.根据配置文件流对象加载出SqlSessionFactory工厂对象(SqlSessionFactory生产连接对象)
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//3.获取数据库连接-SqlSession (类似JDBC中的Connect对象)
SqlSession sqlSession = factory.openSession();
//通过接口字节码文件对象获取接口的实例
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<StudentDo> studentList = mapper.getStudentList();
for(StudentDo studentDo:studentList){
System.out.println(studentDo);
}
}
封装MyBatis获取连接的工具类
目的:减少创建工厂、获取连接的重复代码
package com.huawei.util;
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 java.io.IOException;
import java.io.InputStream;
/**
* 获取mybatis数据连接的工具包
* 2022/5/30
*/
public class SqlSessionUtil {
//定义一个类常量:保证工厂类只有一个实例
private final static SqlSessionFactory FACTORY;
private SqlSessionUtil(){}
//静态代码块
static{
//1.加载mybatis配置文件-得到输入流对象
InputStream resourceAsStream = null;
try {
resourceAsStream = Resources.getResourceAsStream("myBatisConfig.xml");
} catch (IOException e) {
System.err.println("MyBatis配置文件加载错误!");
e.printStackTrace();
}
//2.根据配置文件流对象加载出SqlSessionFactory工厂对象(SqlSessionFactory生产连接对象)
FACTORY = new SqlSessionFactoryBuilder().build(resourceAsStream);
}
/**
* 获取mybatis连接对象
* @return sqlSession对象
*/
public static SqlSession getSqlSession(){
return FACTORY.openSession(true);
}
}
测试:
@Test
public void test1() throws IOException {
//省略之前复杂的声明过程,直接调用工具类中的方法来获取即可
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
//通过接口字节码文件对象获取接口的实例
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<StudentDo> studentList = mapper.getStudentList();
for(StudentDo studentDo:studentList){
System.out.println(studentDo);
}
}
2022-05-31
mybatis核心配置文件
(1)properties配置标签
引入外部资源,注意顺序
<configuration>
<!-- 引入外部配置文件 -->
<properties resource="database.properties"></properties>
... ...
外部配置文件
#这个是mybatis的配置属性文件
#mysql驱动
driver=com.mysql.cj.jdbc.Driver
#mysql的服务器连接地址
url=jdbc:mysql://localhost:3306/huawei?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
#用户名
userName=root
#密码
pwd=root123456
(2) settings 配置标签
settings 元素的作用是设置一些非常重要的设置选项,用于设置和改变 MyBatis 运行中的行为
比如日志:
<!-- mybatis参数配置标签 -->
<settings>
<!-- 配置mybatis的日志用log4j实现 -->
<setting name="logImpl" value="LOG4J" />
</settings>
然后在resources文件夹下创建log4j.properties配置文件
######################## ????DEBUG????????consoleh?file?????, console?file?????????
log4j.rootLogger=DEBUG,console,file
########################??????????
log4j.appender.console = org.apache.log4j.ConsoleAppender
#??????
log4j.appender.console.Target = System.out
#?DEBUG????
log4j.appender.console.Threshold = DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
#????
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
######################??????
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
(3)typeAliases配置标签
给java中数据库与实体映射的类编写别名,以简化映射xml文件中返回值或者参数的编写
1.在typeAliases标签中直接配置typeAlias字标签,一个类一个标签的配置
在mybatis配置文件中
<!-- 给pojo类取别名 -->
<typeAliases>
<!-- 申明类的别名以及类的全限定名 -->
<typeAlias alias="studentDo" type="com.huawei.dto.StudentDo"/>
</typeAliases>
在映射xml中就可以编写别名了
<mapper namespace="com.huawei.dao.StudentMapper">
<!-- 查询:根据学生编号查询学生数据 parameterType:代表的是参数类型 resultType:数据返回的类型可以使用别名-->
<select id="getStudentByCode" parameterType="string" resultType="studentDo">
select * from student where code = #{code};
</select>
... ...
2.自动扫描包下的pojo类生成别名
配置了 typeAliases 元素,在 Mapper.xml 中的 resultType 属性无须写完全限定名com.huawei.pojo.User,只需要写 User 或 user 不区分大小写。
<!-- 给pojo类取别名 -->
<typeAliases>
<!-- 自动扫描包的全限定名,自动生成别名 -->
<package name="com.huawei.dto" />
</typeAliases>
(4)environments环境配置标签
<configuration>
<!-- 配置开发环境,可以配置多个,在具体用时再做切换 -->
<environments default="test">
<environment id="test">
<transactionManager type="JDBC"></transactionManager> <!-- 事务管理类型:JDBC、MANAGED -->
<dataSource type="POOLED"> <!-- 数据源类型:POOLED、UNPOOLED、JNDI -->
<property name="driver" value="com.mysql.cj.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/huawei?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC" />
<property name="username" value="root" />
<property name="password" value="root123456" />
</dataSource>
</environment>
</environments>
(5)mapper映射文件配置标签
在之前的学习中,我们是一个xml映射文件编写一个mapper标签
今天,我们学习自动扫描包完成映射。
注意:这种方式必须保证接口名和 SQL 映射文件名相同,还必须在同一个包中。
如:
mybatis配置文件中的配置方法
<!-- 加载映射文件 mapper -->
<mappers>
<!-- 自动扫描com.huawei.dao包下的同名接口和xml映射文件实现关联 -->
<package name="com.huawei.dao" />
</mappers>
此时测试调用可能会出现异常:
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.huawei.dao.StudentMapper.getStudentList
原因是:xml文件是一个静态文件,且现如今被放置在java源代码目录中,默认情况下idea是会自动排除静态文件进行打包,所以要配置maven静态文件也进行打包:
pom.xml文件中进行配置
<build>
<finalName>CZ_MyBatisDemo1</finalName>
<!-- maven静态资源打包 -->
<resources>
<resource>
<directory>src/main/resources</directory>
<!-- 指定路径下的指定后缀的文件也会进行打包 -->
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.js</include>
<include>**/*.css</include>
<include>**/*.html</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/java</directory><!-- 源代码路径下的配置 -->
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include> <!-- 让xml文件也打包 -->
<include>**/*.js</include>
<include>**/*.css</include>
<include>**/*.html</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
... ...
配置完成之后,使用maven工具-》clean-》install,观察是否成功打包
MapperXMLSQL映射文件配置
(1)Select标签
<select id="getStudentByCode" parameterType="string" resultType="studentDo" >
select * from student where code = #{code};
</select>
resultMap属性
作用:实现不同名字段和属性实现关联映射赋值
<!-- 创建结果集映射规则从表字段映射实体字段 -->
<resultMap id="StudentRes" type="studentDo">
<id column="code" property="code" />
<!-- column指定数据库字段名 property指向实体中的属性名-->
<result column="userName" property="name" />
<result column="age" property="age" />
</resultMap>
<!-- 查询:根据学生编号查询学生数据 resultMap 代表要使用哪个字段和实体的映射规则,值为resultMap标签id值-->
<select id="getStudentByCode" parameterType="string" resultType="studentDo" >
select * from student where code = #{code};
</select>
resultType类型为map
在接口中定义方法
//查询出所有的学生信息放回map集合
List<Map<String,Object>> getAllStudentData() throws IOException;
xml中编写sql
<select id="getAllStudentData" resultType="map">
select * from student
</select>
动态SQL标签
(1)if标签
<!-- 查询所有学生信息(多行数据) -->
<select id="getStudentList" parameterType="studentDo" resultType="studentDo">
select * from student where 1=1
<if test="name!=null or name !=''">
and userName = #{name}
</if>
<if test="age!=0">
and age = #{age}
</if>
</select>
执行结果,根据传递参数的值判断是否拼接if标签中的sql语句
[com.huawei.dao.StudentMapper.getStudentList]-==> Preparing: select * from student where 1=1 and userName = ? and age = ?
[com.huawei.dao.StudentMapper.getStudentList]-==> Parameters: 张三(String), 47(Integer)
[com.huawei.dao.StudentMapper.getStudentList]-<== Total: 0
(2)if+where 标签结合
我们有多个条件时,不知道那个回是第一个条件,因为第一个条件前sql要拼接上where关键字,此时可以如下使用,mybatis会自动判断字段先后添加where关键字
<!-- 查询所有学生信息(多行数据) -->
<select id="getStudentList" parameterType="studentDo" resultType="studentDo">
select * from student
<where>
<if test="name!=null or name !=''">
userName = #{name}
</if>
<if test="age lte 10">
age = #{age}
</if>
</where>
</select>
(3)在使用更新语句时可以使用set+if标签动态update语句
/*更新接口方法*/
//修改学生信息
int updateStudent(StudentDo studentDo);
sql映射xml文件
<!-- 修改学生信息 -->
<update id="updateStudent">
update student
<set>
<if test="name!=null or name != ''">
userName = #{name},
</if>
<if test="age!=0">
age = #{age},
</if>
</set>
where code = #{code}
</update>
(4)分支条件标签choose+when+otherwise
<select id="getStudentList" parameterType="studentDo" resultType="studentDo">
select * from student
<where>
<!-- 条件分支标签 -->
<!--
1.多个when标签执行顺序从上至下判断,如果有一个when标签满足条件后,
之后的when标签和otherwise标签都不会再判断执行
2.当所有的when标签都不满足条件,则直接执行otherwise标签内容
if(){//when标签
}else if(){//when标签
}else{//otherwise标签
}
-->
<choose>
<when test="code==1">
code = 1
</when>
<when test="name=='张三'">
name = '张三'
</when>
<otherwise>
1=1
</otherwise>
</choose>
</where>
</select>
(5)foreach循环sql
1.单参数传入list集合的情况
接口定义
//查询学生的编号是否在集合中出现过
List<StudentDo> getStudentListByCodeList(List<String> codes);
sql映射文件xml
<!--查询学生的编号是否在集合中出现过 -->
<select id="getStudentListByCodeList" resultType="com.huawei.dto.StudentDo">
select * from student
where code in
<foreach collection="list" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</select>
2.单参数传入数组的情况
接口定义
//查询学生的编号是否在数组中出现过
List<StudentDo> getStudentListByCodeList(String [] codes);
sql映射文件xml
!--查询学生的编号是否在集合中出现过 -->
<select id="getStudentListByCodeList" resultType="com.huawei.dto.StudentDo">
select * from student
where code in
<foreach collection="array" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</select>
执行sql拼接效果
[com.huawei.dao.StudentMapper.getStudentListByCodeList]-==> Preparing: select * from student where code in ( ? , ? , ? , ? , ? )
[com.huawei.dao.StudentMapper.getStudentListByCodeList]-==> Parameters: 1(String), 2(String), 3(String), 10(String), 12(String)
3.传入一个对象或者map集合,遍历对象中的集合属性或者map中的集合元素
此案例以map元素演示:
接口定义:
//查询学生的编号是否在数组中出现过
List<StudentDo> getStudentListByCodeList(Map<String,Object> map);
sql映射xml
<!--查询学生的编号是否在集合中出现过 -->
<select id="getStudentListByCodeList" resultType="com.huawei.dto.StudentDo">
select * from student
where code in
<foreach collection="codeList" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</select>
测试调用
@Test
public void test1() throws IOException {
//1.加载mybatis配置文件-得到输入流对象
InputStream resourceAsStream = Resources.getResourceAsStream("myBatisConfig.xml");
//2.根据配置文件流对象加载出SqlSessionFactory工厂对象(SqlSessionFactory生产连接对象)
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//3.获取数据库连接-SqlSession (类似JDBC中的Connect对象)
SqlSession sqlSession = factory.openSession();
//4.通过数据库连接对象调用mybatis映射文件中的sql方法
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
//设置查询参数
Map<String,Object> map = new HashMap<>();
List<String> codes = new ArrayList<>();
codes.add("1");
codes.add("2");
codes.add("3");
codes.add("4");
//!!!!! 重点 !!!!!!
map.put("codeList",codes);
mapper.getStudentListByCodeList(map);
//5.归还连接(关闭连接)
sqlSession.close();
}
mybatis配置连接池(脱离web容器的方法)
(1)引入druid连接池依赖
<!-- 阿里的druid连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
<scope>compile</scope>
</dependency>
(2)更换连接池的第一步-创建一个工厂类继承PooledDataSourceFactory
/**
* 创建一个自定义的工厂类,继承PooledDataSourceFactory
* 重新编写DataSource对象的创建方法
* 2022/5/31
*/
public class MyDruidPoolFactory extends PooledDataSourceFactory {
/**
* 定义构造器,替换dataSource对象的创建方法
*/
public MyDruidPoolFactory(){
this.dataSource = new DruidDataSource();
}
}
(3)更换mybatis配置文件中-环境配置数据源标签的type属性
<!-- dataSource标签的type属性为我们创建的连接池类的全限定名 -->
<environments default="test">
<environment id="test">
<transactionManager type="JDBC"></transactionManager> <!-- 事务管理类型:JDBC、MANAGED -->
<dataSource type="com.huawei.config.MyDruidPoolFactory"> <!-- 数据源类型:POOLED、UNPOOLED、JNDI -->
<!-- 切换为阿里druid连接池后驱动名称变为了 driverClass -->
<property name="driverClass" value="${driver}" />
<!-- 切换为阿里druid连接池后连接地址变为了 jdbcUrl -->
<property name="jdbcUrl" value="${url}" />
<property name="username" value="${userName}" />
<property name="password" value="${pwd}" />
</dataSource>
</environment>
</environments>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)