川职院-课堂笔记(2)5-27日起
每日笔记整理:
目录- 每日笔记整理:
- 2022-05-27
- 2022-05-29
- SpringMVC文件上传
- 2022-05-30
- Spring+SpringMVC搭建流程
- 构建第一个MyBatis项目
- 入门版增删改查语句
- 改写为sqlSession获取接口实现的实例
- 封装MyBatis获取连接的工具类
- 2022-05-31
- mybatis核心配置文件
- MapperXMLSQL映射文件配置
- resultMap属性
- resultType类型为map
- 动态SQL标签
- mybatis配置连接池(脱离web容器的方法)
2022-05-27
过滤器
依赖于servlet容器。在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。
使用过滤器的目的是用来做一些过滤操作,获取我们想要获取的数据,比如:在过滤器中修改字符编码;在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等
总之过滤器实际上就是对所有请求进行过滤操作,获取请求携带的数据或者修改请求的某些参数。
Spring-字符编码过滤器配置
characterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
forceEncoding
true
characterEncodingFilter
/*
自定义过滤器
(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 = "" +
"" +
"" +
"" +
"请求被过滤器阻止!";
writer.println(html);
//filterChain.doFilter(servletRequest,servletResponse);//放行请求
}
(2)在web.xml文件中配置过滤器
myFilter
com.huawei.sys.filter.MyFilter
myFilter
/user/*
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配置文件中配置拦截器
2022-05-29
SpringMVC文件上传
(1)引入依赖
org.apache.commons
commons-lang3
3.4
commons-fileupload
commons-fileupload
1.3.1
commons-io
commons-io
2.4
(2)在dispachter-servlet.xml配置文件中配置文件上传选项
(3)前端编写表单上传文件
(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 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 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 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(FileUtils.readFileToByteArray(file),
headers, HttpStatus.CREATED);
}
2022-05-30
Spring+SpringMVC搭建流程
(1)maven依赖整理
<?xml version="1.0" encoding="UTF-8"?>
4.0.0
com.huawei
CZ_SpringMVCDemo1
1.0.0
war
CZ_SpringMVCDemo1 Maven Webapp
http://www.example.com
UTF-8
1.7
1.7
5.2.3.RELEASE
org.springframework
spring-web
${springBBH}
org.springframework
spring-webmvc
5.2.3.RELEASE
org.springframework
spring-context
5.2.3.RELEASE
org.springframework
spring-test
5.2.3.RELEASE
org.springframework
spring-jdbc
5.2.3.RELEASE
org.aspectj
aspectjweaver
1.8.9
junit
junit
4.11
test
org.slf4j
slf4j-log4j12
1.7.21
javax.servlet
javax.servlet-api
3.1.0
javax.servlet.jsp
jsp-api
2.2
javax.servlet
jstl
1.2
mysql
mysql-connector-java
8.0.22
com.alibaba
fastjson
1.2.78
org.apache.commons
commons-lang3
3.4
commons-fileupload
commons-fileupload
1.3.1
commons-io
commons-io
2.4
org.projectlombok
lombok
1.18.22
provided
com.fasterxml.jackson.core
jackson-core
2.12.3
com.fasterxml.jackson.core
jackson-databind
2.12.3
javax.validation
validation-api
1.1.0.Final
org.jboss.logging
jboss-logging
3.1.0.CR2
org.hibernate
hibernate-validator
5.1.0.Final
CZ_SpringMVCDemo1
src/main/resources
**/*.properties
**/*.xml
**/*.js
**/*.css
**/*.html
false
src/main/java
**/*.properties
**/*.xml
**/*.js
**/*.css
**/*.html
false
maven-clean-plugin
3.1.0
maven-resources-plugin
3.0.2
maven-compiler-plugin
3.8.0
maven-surefire-plugin
2.22.1
maven-war-plugin
3.2.2
maven-install-plugin
2.5.2
maven-deploy-plugin
2.8.2
org.apache.maven.plugins
maven-compiler-plugin
8
8
(2)配置web.xml
Archetype Created Web Application
contextConfigLocation
classpath*:applicationContext.xml
org.springframework.web.context.ContextLoaderListener
dispatcher
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:dispatcher-servlet.xml
1
dispatcher
/
hiddenHttpMethodFilter
org.springframework.web.filter.HiddenHttpMethodFilter
hiddenHttpMethodFilter
/*
characterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
forceEncoding
true
characterEncodingFilter
/*
(3)视图解析器配置文件必要配置项目
<?xml version="1.0" encoding="UTF-8"?>
(4)包结构定义规则
父级:公司域名反写(com.huawei)
? 业务包名(sys)
? 控制器层(controller)
? 数据转换层(dto)
? 业务接口层(service)
? 业务接口实现层(impl)
? 工具包(util)
? 过滤器(filters)
? 拦截器(interceptors)
? 配置类(configs)
构建第一个MyBatis项目
(1)在resouces目录下创建一个mybatis配置文件
名称可以自定义
<?xml version="1.0" encoding="UTF-8" ?>
(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"?>
#{}是预编译处理,像传进来的数据会加个" "(#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号)
${}就是字符串替换。直接替换掉占位符。$方式一般用于传入数据库对象,例如传入表名.
使用${}的话会导致 sql 注入。所以为了防止 SQL 注入,能用#{}的不要去用${}
果非要用${}的话,那要注意防止 SQL 注入问题,可以手动判定传入的变量,进行过滤,一般 SQL 注入会输入很长的一条 SQL 语句
(6)在mybatis配置文件中配置xml映射文件
(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 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"?>
INSERT into student VALUES(#{code},#{name},#{age})
update student set name=#{name},age=#{age} where code=#{code}
delete from student where code = #{code}
(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 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 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 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 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 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 studentList = mapper.getStudentList();
for(StudentDo studentDo:studentList){
System.out.println(studentDo);
}
}
2022-05-31
mybatis核心配置文件
(1)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 运行中的行为
比如日志:
然后在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配置文件中
在映射xml中就可以编写别名了
... ...
2.自动扫描包下的pojo类生成别名
配置了 typeAliases 元素,在 Mapper.xml 中的 resultType 属性无须写完全限定名com.huawei.pojo.User,只需要写 User 或 user 不区分大小写。
(4)environments环境配置标签
(5)mapper映射文件配置标签
在之前的学习中,我们是一个xml映射文件编写一个mapper标签
今天,我们学习自动扫描包完成映射。
注意:这种方式必须保证接口名和 SQL 映射文件名相同,还必须在同一个包中。
如:
mybatis配置文件中的配置方法
此时测试调用可能会出现异常:
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.huawei.dao.StudentMapper.getStudentList
原因是:xml文件是一个静态文件,且现如今被放置在java源代码目录中,默认情况下idea是会自动排除静态文件进行打包,所以要配置maven静态文件也进行打包:
pom.xml文件中进行配置
CZ_MyBatisDemo1
src/main/resources
**/*.properties
**/*.xml
**/*.js
**/*.css
**/*.html
false
src/main/java
**/*.properties
**/*.xml
**/*.js
**/*.css
**/*.html
false
... ...
配置完成之后,使用maven工具-》clean-》install,观察是否成功打包
MapperXMLSQL映射文件配置
(1)Select标签
resultMap属性
作用:实现不同名字段和属性实现关联映射赋值
resultType类型为map
在接口中定义方法
//查询出所有的学生信息放回map集合
List
xml中编写sql
动态SQL标签
(1)if标签
执行结果,根据传递参数的值判断是否拼接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关键字
(3)在使用更新语句时可以使用set+if标签动态update语句
/*更新接口方法*/
//修改学生信息
int updateStudent(StudentDo studentDo);
sql映射xml文件
update student
userName = #{name},
age = #{age},
where code = #{code}
(4)分支条件标签choose+when+otherwise
(5)foreach循环sql
1.单参数传入list集合的情况
接口定义
//查询学生的编号是否在集合中出现过
List getStudentListByCodeList(List codes);
sql映射文件xml
2.单参数传入数组的情况
接口定义
//查询学生的编号是否在数组中出现过
List getStudentListByCodeList(String [] codes);
sql映射文件xml
!--查询学生的编号是否在集合中出现过 -->
执行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 getStudentListByCodeList(Map map);
sql映射xml
测试调用
@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 map = new HashMap<>();
List 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连接池依赖
com.alibaba
druid
1.2.8
compile
(2)更换连接池的第一步-创建一个工厂类继承PooledDataSourceFactory
/**
* 创建一个自定义的工厂类,继承PooledDataSourceFactory
* 重新编写DataSource对象的创建方法
* 2022/5/31
*/
public class MyDruidPoolFactory extends PooledDataSourceFactory {
/**
* 定义构造器,替换dataSource对象的创建方法
*/
public MyDruidPoolFactory(){
this.dataSource = new DruidDataSource();
}
}
(3)更换mybatis配置文件中-环境配置数据源标签的type属性