2019.5.19学习周报-----servlet上传下载、过滤器监听器、EL表达式、JSTL、Ajax、mybatis

一、Java Web部分

1、上传文件

使用Servlet来处理上传文件的请求。 与寻常的请求处理不同,如果请求中带有文件,那么需要使用commons组件(需要同时安装commons-FileItem.jar和commons-io.jar)来解析请求中的文件。

  1. 首先,前端提交文件的表单中,需要有enctype="multipart/form-data"属性。
    提交按钮需要将type设置为file。
  2. 服务端
    • 首先需要设置解析请求和响应的编码格式
      request.setCharacterEncoding("utf-8");
      response.setCharacterEncoding("utf-8");
      response.setContentType("text/html;charset=UTF-8");
      
    • 判断multipart属性
      if(ServletFileUpload.isMultipartContent(request))
      
    • 提取请求中的数据
      在这种解析方式中,请求都被封装在一个List中。如何得到这个对象:
      FileItemFactory factory = new DiskFileItemFactory();
      ServletFileUpload upload = new ServletFileUpload(factory);
      List<FileItem> items = upload.parseRequest(request);
      
    • 使用迭代器迭代判断并存储数据
      Iterator<FileItem> iter = items.iterator()
      循环遍历。。。。
      使用FileItem对象承载取自迭代器中的每一个元素。
      item.isFormField()//判断是否是普通表单字段。
      FileItem.GetFieldName();//得到当前元素的字段名(前端中的name)和字符串比较确定当前取得的字段。
      
    • 确定文件字段之后进行存储
      FileItem.getName();//得到上传的文件的文件名
      FileItem.Write(File)//将文件存储在File对象的位置(File对象需要手动创建)
      
      这里需要注意的是: 将文件上传到一定路径下,建议使用本地的路径, tomcat服务器里的路径每次重新编译项目回进行清空

2、下载文件

下载文件较上传简单很多,不需要依赖其他jar包。

  1. 前端
    前端需要给出一个请求,包括需要下载的文件名(下载后存储的文件名)
  2. 后台
    • 首先设置请求的编码格式

      request.setCharacterEncoding("utf-8");
      
    • 确定下载的文件名

    •   StringfileName=request.getParameter("filename");
      
    • 设置响应消息头

    •   response.setContentType(getServletContext().getMimeType(fileName));
        response.addHeader("Content-Disposition","attachment;filename="+fileName);
      
    • 将本地文件连接道输入流

    •   InputStreamin=getServletContext().getResourceAsStream("/image/picture.jpg");
      
    • 从响应处得到输出流

    •   ServletOutputStreamout=response.getOutputStream();
      
    • 将输入流中的数据读取,写入输出流即可

需要注意的是:

  1. 响应消息头可以使用getServletContext().getMimeType(fileName)得到响应的文件的格式,也可以直接写“application/octet-stream”来代表所有二进制文件
  2. 获取本地文件的输入流时,路径指向web文件夹,也就是说,要下载至客户端的文件都应该放置在web文件夹中。项目部署至服务器后,只剩下了web文件夹。

3、过滤器

  • 过滤器会在请求和响应过程中拦截请求或响应。
  • 需要等待过滤器放行才能继续执行请求或响应。
    (要想把一个普通的Java Class编程某个具有特定功能的类如Servlet和过滤器,要么继承,要么实现接口,或者添加注解)
  • 过滤器需要实现Filter接口,需要实现init,doFilter,destroy方法,其中init和destroy方法的执行和servlet中一样。
  • 过滤器和Servlet一样,同样可以使用web.xml和注解两种方式进行配置:
    1. 使用web.xml进行配置
      • Servlet的配置一样,需要将所有的Servlet改成Filter。
        servlet----->filter
        servlet-mapping----->filter-mapping
        servlet-name----->filter-name
        Servlet-class----->filter-class
        url-pattern不用修改
      • 过滤器链的执行顺序由filter-mapping在xml中的顺序决定
      • 可以对拦截的类型进行设置
        • REQUEST:只拦截HTTP请求
        • FORWARD:只拦截经过转发的请求
        • INCLUDE
        • ERROR
    2. 使用注解进行配置
      • 使用@WebFilter(filterName = "", value = "")注解进行配置url
      • 过滤器链的执行顺序由filterName的字符串比较顺序决定
  • 通配符“/*”表示拦截所有的请求和响应
  • 过滤器对请求进行放行要使用chain.doFilter(req,resp);方法,调用该方法相当于调用servlet中的doxxx方法

4、监听器

按监听的对象划分,可以分为

  • ServletContext对象监听器
  • HttpSession对象监听器
  • ServletRequest对象监听器

按监听的事件划分

  • 对象自身的创建和销毁的监听器
  • 对象中属性的创建和消除的监听器
  • session中的某个对象的状态变化的监听器

5、EL表达式

EL:Expression Language,可以替代页面中的JAVA代码

  • 传统使用Java代码来显示数据的弊端:
    1. 需要进行类型转换(返回Object)
    2. 需要处理null(字段名对应的属性不一定都被填充)
    3. HTML代码中混杂Java代码非常混乱
  • EL表达式的语法:
    ${域对象.属性.属性。。。(级联属性)}
  • EL操作符:
    1. 点操作符–>使用方便
    2. 中括号操作符–>功能强大,属性名中可以使用特殊字符,可以使用变量值
      [" 属性名 "]
  • 获取map属性
    使用中括号表达式—${reqiestScope.map.keyName}
  • 关系运算符,逻辑运算符
    1. >, <, ||, or, and等等
    2. Empty运算符:判断一个值null、是否不存在${requestScope[“属性名”]},如果属性存在则返回false
  • EL表达式的隐式对象:
    1. 作用域访问对象:pageScope、requestScope、sessionScope、applicationScope
    2. 参数访问对象:param、paramValues
    3. JSP隐式对象

6、JSTL

  • 需要引入两个jar包:jstl.jar和standard.jar
  • 引入tablib:
<%@ tagliburi="http://java.sun.com/jsp/jstl/core"prefix="c"%>

其中prefix为设置前缀

  • 核心标签库:
    1. 通用标签库
      • <c:set/>赋值
        • 在某个作用域(四个范围对象)中,给变量赋值(或声明变量)
          <c:set var = "key" value = "value" scope = "xxxScope" />
          
        • ***给某个对象的属性赋值(不需要指定scop,对象和属性必须存在)
          <c:set target = “${…EL找到该对象…}” property = “attributeName” value = “value” />
      • <c:out/>输出
        输出某值
        <c:out value = "${…EL…}" default = "如果没有该值的默认输出" escapeXml="是否按文本输出(忽略HTML的翻译)">
        
      • <c:remove/>删除
        <c:remove var = varName" scope = "xxxScope" />
        
    2. 条件标签库
      • 单充选择
        <c:if test = "${…EL判断的条件…}">
        	条件为真显示的内容
        </c:if>
        
      • 多重选择(很像switch)
        <c:choose>
        	<c:when test = "${…EL判断的条件…}">
        		显示的内容
        	</c:when>
        	<c:when test = "${…EL判断的条件…}">
        		显示的内容
        	</c:when>
        	<c:otherwise>
        		其他情况下显示的内容
        	</c:otherwise>
        </c:choose>
        	```
        
    3. 迭代标签库(循环)
      • for(int I = 0; I <= num; i++)
        <c:foreach begin = "开始位置int" end = "结束位置int(这里包含结束位置)" step = "步长">``
        	循环体
        </c:foreach>
        
      • for(Object[] oo : Object o)
        <c:foreach var = "${…EL单个元素的载体…}" items = "${…EL容器集合等…}">
        

7、AJAX

Ajax(异步JavaScript和XML)是一种创建交互式网页应用的网页开发技术。
Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
传统网页使用全局刷新,局限性非常大。

  • 实现方式:
  1. JS:依赖XMLHttpRequest对象
    • 方法:
      • open(提交方式(get or post),方法名, boolean);
        与服务端建立连接,参数boolean为是否异步刷新,一般为true
      • send();
        get:send(null);
        post:send(参数值);
      • setRequestHeader(header, value);
        get不需要设置
        post需要设置:
        • 包含文件上传:
          setRequestHeader(“Content-Type”, “multipart/form-data”);
          
        • 不包含文件上传:
          setRequestHeader(“Content-Type”, “application/x-www-from-urlencoded”);
          
    • 属性:
      • readtstate:请求状态,只有状态为4时,状态为完毕
        在这里插入图片描述
      • status:响应状态:200为正常
        在这里插入图片描述
      • onreadtstatechange:回调函数(获取服务端返回值,并且进行处理和响应)
      • responseText:响应格式为String
      • responseXML:响应格式为XML
  2. jQuery
    • 需要引入jQuery.js
      <script type="text/javascript" src="jQuery.js的地址"></script>
      
    • $.ajax({
      	url:服务器地址,
      	请求方式:get/post,
      	data:请求数据,
      	success:function(){
      		请求成功的回调函数;
      	},
      	error:function(){
      		请求失败的回调函数;
      	}
      }

二、mybatis部分

1、原生JDBC在编程中存在的问题

1. 数据库连接使用时创建,然后进行释放。重复频繁的对数据库资源进行访问和释放回造成很大的资源浪费。使用数据库连接池解决此问题。
2. sql语句过于硬编码,不利于系统的维护。
3. 像prepareStatement中设置参数时也有硬编码的成分。
4. 从resultSet遍历结果集数据时,存在硬编码。

2、mybatis框架

  1. mybatis是什么?
    mybatis是一个持久层的框架,是apache下的顶级项目。
    mybatis让开发者将主要精力放在sql上,通过mybatis提供的映射方式,自由灵活(半自动化,大部分还是需要开发者编写sql)地生成满足需要的sql语句。
    mybatis可以向prepareStatement中的输入参数自动继续宁输入映射,将结果集灵活的
  2. mybatis框架
    在这里插入图片描述

3、mybatis结构

在这里插入图片描述

  • Log4j.properties
    	# Global logging configuration
    	log4j.rootLogger=DEBUG, stdout
    	# Console output...
    	log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    	log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    	log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
    
  • SqlMapConfig.xml
    	<?xmlversion="1.0"encoding="UTF-8"?>
    	<!DOCTYPEconfiguration
    			PUBLIC"-//mybatis.org//DTDConfig3.0//EN"
    			"http://mybatis.org/dtd/mybatis-3-config.dtd">
    	<configuration>
    		<!--和spring整合后environments配置将废除-->
    		<environmentsdefault="development">
    			<environmentid="development">
    				<!--使用jdbc事务管理,事务控制由mybatis-->
    				<transactionManagertype="JDBC"/>
    				<!--数据库连接池,由mybatis管理-->
    				<dataSourcetype="POOLED">
    					<propertyname="driver"value="com.mysql.cj.jdbc.Driver"/>
    					<propertyname="url"value="jdbc:mysql://localhost:3306/xxxxxx?characterEncoding=utf-8"/>
    					<propertyname="username"value="root"/>
    					<propertyname="password"value="xxxx"/>
    				</dataSource>
    			</environment>
    		</environments>
    	</configuration>
    

4、创建映射文件

  1. 在映射文件中配置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">
<!-- namespace 命名空间,作用就是对sql进行分类化管理,理解为sql隔离
 注意:使用mapper代理方法开发,namespace有特殊重要的作用
 -->
<mapper namespace="student">
    <!-- 在映射文件中配置很多sql语句 -->
    <!--需求:通过id查询用户表的记录 -->
    <!-- 通过select执行数据库查询
     id:标识映射文件中的sql,称为statement的id
     将sql语句封装到mappedStatement对象中,所以将id称为statement的id
     parameterType:指定输入参数的类型
     #{}标示一个占位符,
     #{value}其中value表示接收输入参数的名称,如果输入参数是简单类型,那么#{}中的值可以任意。
     resultType:指定sql输出结果的映射的java对象类型,select指定resultType表示将单条记录映射成java对象
     -->
   <select id="findStudentById" parameterType="int" resultType="pojo.Student">
       select * from test_mybatis.student where sno = #{id};
   </select>
    <!-- 根据用户名称模糊查询用户信息,可能返回多条
    resultType:指定就是单条!!记录所映射的java对象类型
    ${}:表示拼接sql串,将接收到参数的内容不加任何修饰拼接在sql中。
    使用${}拼接sql,引起 sql注入
    ${value}:接收输入参数的内容,如果传入类型是简单类型,${}中只能使用value
     -->
    <select id="findStudentByName" parameterType="java.lang.String" resultType="pojo.Student">
        select * from test_mybatis.student where sname like '%${value}%';
    </select>
    <!-- 添加学生信息 -->
    <!-- 如果需要多个参数,则需要在parameterType设置pojo的类型,然后直接使用#{}中取得pojo的成员变量 -->
    <!-- 插入没有返回值 -->
    <!-- 自增加主键 -->
    <insert id="insertStudent" parameterType="pojo.Student">
        insert into test_mybatis.student (sname, sage, saddress) values (#{sname}, #{sage}, #{saddress});
        <selectKey keyProperty="sno" order="AFTER" resultType="java.lang.Integer">
            select last_insert_id();
        </selectKey>
    </insert>
    <!--&lt;!&ndash; 非自增加主键 &ndash;&gt;-->
    <!--&lt;!&ndash; 这里相当于先填充studentPojo,所以再sql中要留下sno的位置 &ndash;&gt;-->
    <!--<insert id="addStudent" parameterType="pojo.Student">-->
        <!--insert into test_mybatis.student (sno, sname, sage, saddress) values (#{sno}, #{sname}, #{sage}, #{saddress});-->
        <!--<selectKey keyProperty="sno" order="BEFORE" resultType="java.lang.Integer">-->
            <!--select uuid();-->
        <!--</selectKey>-->
    <!--</insert>-->
    <!-- 删除学生信息 -->
    <delete id="deleteStudentById" parameterType="java.lang.Integer">
        delete from test_mybatis.student where sno = #{sno};
    </delete>
    <!-- 更新学生信息 -->
    <!-- 这里根据sno更新学生信息,需要传入有sno的Student对象,然后根据sno查询数据,根据其他属性的值进行修改 -->
    <update id="updateStudentById" parameterType="pojo.Student">
    update test_mybatis.student set sname = #{sname}, sage = #{sage}, saddress = #{saddress} where sno = #{sno};
    </update>
</mapper>
  1. 在sqlMapConfig.xml中加载studentMapper.xml
<!-- 加载映射文件-->
<mappers>
    <mapper resource="sqlmap/studentMapper.xml"/>
</mappers>

5、简单的查询过程

1. 首先根据SqlMapConfig.xml文件的位置得到该文件的流
2. 创建会话工厂对象,根据流载入位置文件信息
3. 通过工厂得到会话对象
4. 调用会话对象的一系列方法操作数据库
5. 关闭流
@Test
// 根据学生的sno查询学生
// 初次使用mybatis进行数据库的操作
public void findStudentByIdTest() {
    //添加mybatis配置文件
    String resource = "config/SqlMapConfig.xml";
    SqlSession sqlSession = null;
    try ( //得到配置文件的流
          InputStream inputStream = Resources.getResourceAsStream(resource)
    ) {
        //创建会话工厂,载入配置文件信息
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //通过工厂得到SqlSession
        sqlSession = sqlSessionFactory.openSession();

        //通过SqlSession操作数据库
        //第一个参数是映射文件studentMapper.xml中的statement的id,其值等于namePlace + "." + statementId
        //第二个参数是映射文件中设置的要传入的参数类型所匹配的对象
        Student student = sqlSession.selectOne("student.findStudentById", 4173188);
        System.out.println(student);
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (sqlSession != null)
            sqlSession.close();
    }
}

6、插入数据案例

插入数据和之前的简单查询相同,只需要在配置文件设置插入数据所使用的sql语句的映射。
需要注意的是:如果需要多个参数,则需要在parameterType设置pojo的类型,然后直接使用#{}中取得pojo的成员变量作为各个参数进行输入
需要在后台中得到数据库分配的主键则分为自增主键和非自增主键:

  1. 自增主键使用MySQL的last_insert_id(),并在insert之后进行查询,设置返回到id中即可
  2. 非自增主键使用MySQL的uuid()在insert之前进行主键的设置,并返回到id中,然后再进行insert

由于这里相当于先填充Student对象,然后把id正常的传入,所以要再sql中添加sql字段

	<!-- 添加学生信息 -->
    <!-- 如果需要多个参数,则需要在parameterType设置pojo的类型,然后直接使用#{}中取得pojo的成员变量 -->
    <!-- 插入没有返回值 -->

    <!-- 自增加主键 -->
    <insert id="insertStudent" parameterType="pojo.Student">
        insert into test_mybatis.student (sname, sage, saddress) values (#{sname}, #{sage}, #{saddress});
        <selectKey keyProperty="sno" order="AFTER" resultType="java.lang.Integer">
            select last_insert_id();
        </selectKey>
    </insert>

    <!-- 非自增加主键 -->
    <!-- 这里相当于先填充studentPojo,所以再sql中要留下sno的位置 -->
    <insert id="addStudent" parameterType="pojo.Student">
        insert into test_mybatis.student (sno, sname, sage, saddress) values (#{sno}, #{sname}, #{sage}, #{saddress});
        <selectKey keyProperty="sno" order="BEFORE" resultType="java.lang.Integer">
            select uuid();
        </selectKey>
    </insert>
@Test
//通过传入Student对象插入Student数据
public void addStudent() {
    String resource = "config/SqlMapConfig.xml";
    SqlSession sqlSession = null;
    try (
            InputStream inputStream = Resources.getResourceAsStream(resource)
    ) {
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        sqlSession = sqlSessionFactory.openSession();
        Student student = new Student("Benjamin", 19, "bj");
        sqlSession.insert("student.insertStudent", student);
        sqlSession.commit();
        System.out.println(student);
    } catch (IOException e) {
        e.printStackTrace();
    }finally {
        if(sqlSession != null){
            sqlSession.close();
        }
    }
}

在这里插入图片描述

7、入门程序总结

总结
#{}和${}

#{}表示一个占位符号,#{}接收输入参数,类型可以是简单类型,pojo、hashmap。
如果接收简单类型,#{}中可以写成value或其它名称。
#{}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性…的方式获取对象属性值。
${}表示一个拼接符号,会引用sql注入,所以不建议使用${}。
${}接收输入参数,类型可以是简单类型,pojo、hashmap。
如果接收简单类型,${}中只能写成value。
${}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性…的方式获取对象属性值。

8、mybatis和hibernate本质区别和应用场景

  • hibernate
  1. 是一个标准ORM框架(对象关系映射)。入门门槛较高的,不需要程序写sql,sql语句自动生成了。对sql语句进行优化、修改比较困难的。
  2. 应用场景:适用与需求变化不多的中小型项目,比如:后台管理系统,erp、orm、oa。。
  • mybatis
  1. 专注是sql本身,需要程序员自己编写sql语句,sql修改、优化比较方便。mybatis是一个不完全的ORM框架,虽然程序员自己写sql,mybatis也可以实现映射(输入映射、输出映射)。
  2. 应用场景:适用与需求变化较多的项目,比如:互联网项目。

企业进行技术选型,以低成本高回报作为技术选型的原则,根据项目组的技术力量进行选择。

8、原始开发dao的方法

  • sqlSession的使用范围分析:
    1. SqlSessionFactoryBuilder
      通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory。
      将SqlSessionFactoryBuilder当成一个工具类使用即可,不需要使用单例管理SqlSessionFactoryBuilder。
      再需要创建SqlSessionFactory时,new一个SqlSessionFactoryBuilder即可。
    2. SqlSessionFactory
      通过SqlSessionFactory创建SqlSession,使用单例模式管理SqlSessionFactory(工厂一旦创建,就一直存在,并且只使用这一个工厂)。
      将来mybatis和spring整合之后,也使用单例模式管理。
    3. SqlSession
      SqlSession是一个面向用户(开发者)的接口。
      SqlSession中提供了很多操作数据库的方法:如selectOne和selectList等。
      SqlSession线程不安全,因为SqlSession的实现类中除了有接口中的方法还存在数据域属性。 因此,SqlSession使用的最佳方式使作为方法的局部变量来使用

dao接口:

package code.dao;

import pojo.Student;

/**
 * Student的dao接口,用于管理学生
 */
public interface StudentDao {
    /**
     * 插入Student信息
     * @param student 需要插入的Student对象
     * @throws Exception
     */
    public void insertStudent(Student student) throws Exception;

    /**
     * 根据sno删除学生信息
     * @param sno 需要删除的学生的sno
     * @throws Exception
     */
    public void deleteStudent(int sno) throws Exception;

    /**
     * 更新Student信息
     * @param student 传入的需要修改的Sutdent的新的信息
     * @throws Exception
     */
    public void updateStudent(Student student) throws Exception;

    /**
     * 通过sno查询学生
     * @param sno 需要查询的学生的sno
     * @return 查询到的Student对象
     * @throws Exception
     */
    public Student findStudentBySno(int sno) throws Exception;
}

dao接口实现类:

package code.dao;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import pojo.Student;

/**
 * StudentDao的接口实现类
 */
public class StudentDaoImpl implements StudentDao {
    private SqlSessionFactory sqlSessionFactory;

    public StudentDaoImpl(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory = sqlSessionFactory;
    }

    @Override
    public void insertStudent(Student student) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.insert("student.insertStudent", student);
        sqlSession.commit();
        sqlSession.close();
    }

    @Override
    public void deleteStudent(int sno) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.delete("student.deleteStudentById", sno);
        sqlSession.commit();
        sqlSession.close();
    }

    @Override
    public void updateStudent(Student student) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.update("student.updateStudentById", student);
        sqlSession.commit();
        sqlSession.close();
    }

    @Override
    public Student findStudentBySno(int sno) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        Student student = sqlSession.selectOne("student.findStudentById", sno);
        //释放资源
        sqlSession.close();
        return student;
    }
}

原始dao开发问题:

  1. dao接口实现类方法中存在大量的模板方法,大量的重复代码,可以对此进行优化减轻工作量。
  2. 调用sqlsession中的方法时将statementid硬编码了。
  3. 调用sqlsession中方法时传入的变量,由于接收的是泛型,所以即使传入的类型不正确,也不会在编译阶段被检查出。这样并不利于开发者的检查。

9、mapper代理开发dao的方法

开发者编写xxxMapper.xml文件,其中需要遵循一些开发规范,让mybatis可以自动生成mapper接口实现类代理对象:

  1. 在xxxMapper.xml中需要将namespace设置成mapper接口的全类名地址
    <mapper namespace="student">
    
  2. mapper接口中的方法名要与xxxMapper.xml中statement的id一致。
  3. mapper接口中方法的参数要与xxxMapper.xml中statement的parameterType指定的类型一致。
  4. mapper接口中的方法返回值类型要和xxxMapper.xml中statement的resultType指定的类型一致。
    <select id="findStudentById" parameterType="int" resultType="pojo.Student">
       select * from test_mybatis.student where sno = #{id};
    </select>
    
    /**
     * 通过sno查询学生
     * @param sno 需要查询的学生的sno
     * @return 查询到的Student对象
     * @throws Exception
     */
    public Student findStudentBySno(int sno) throws Exception;
    

需要注意的是:mybatis在进行代理生成接口实现对象时,会根据返回值的不同选择性的调用selectOne或selectList。所以模糊查询之类的操作在返回值出设置为List<xxxpojo>即可。
使用mapper时需要注意的是:

  1. 在SqlMapConfig.xml中加载新的xxxMapper.xml。
  2. SqlSession对象需要自己创建,接口中没有定义如何得到SqlSession对象。
  3. 要先根据SqlSession得到代理的mapper接口实现对象。
    //通过SqlSession得到代理的mapper接口对象
    StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
    

10、SqlMapConfig.xml

SqlMapConfig.xml中配置的内容和顺序如下

  • properties(属性)
  • settings(全局配置参数)
  • typeAliases(类型别名)
  • typeHandlers(类型处理器)
  • objectFactory(对象工厂)
  • plugins(插件)
  • environments(环境集合属性对象)
    • environment(环境子属性对象)
      • transactionManager(事务管理)
      • dataSource(数据源)
  • mappers(映射器)
    (注:粗体是重点,斜体不常用)
  1. properties属性
    • 需求:
      将数据库连接参数单独配置在db.properties中,只需要在SqlMapConfig.xml中加载db.properties中的各个属性值。
      在这里插入图片描述
      将数据库连接参数之配置在db.properties中的原因是方便对参数进行统一的管理,其他的xml引用该db.properties即可。
      在这里插入图片描述

    • properties特性:
      MyBatis 将按照下面的顺序(优先级)来加载属性:

      • 在properties元素体内定义的属性首先被读取。
      • 然后会读取properties元素中resource或url加载的属性,它会覆盖已读取的同名属性。
      • 最后读取parameterType传递的属性,它会覆盖已读取的同名属性。

      建议:

      • 不要在properties元素体内添加任何属性值,只将属性值定义在properties文件中。
      • 在properties文件中定义属性名要有一定的特殊性,如:XXXXX.XXXXX.XXXX
  2. settings配置
    mybatis框架在运行时可以调整一些运行参数,比如:开启二级缓存、开启延迟加载…
    全局参数将会影响mybatis的运行行为。具体参考官网:
    http://www.mybatis.org/mybatis-3/configuration.html#settings
  3. typeAliases(别名)
    在mapper.xml中,定义很多statement时需要parameterType指定输入参数的类型,需要resultType指定输出结果的映射类型。
    每次都使用全路径,会不方便开发,可以针对其中的类型进行别名的设置,在mapper.xml中使用别名进行开发。
    • mybatis默认支持的别名
      在这里插入图片描述
    • 自定义别名
      • 单个别名的定义
      • 批量定义别名
        <!-- 定义别名 -->
        <typeAliases>
        	<!-- 设置单个的别名
        	type:类型的路径
         	alias:别名
        	 -->
        	<typeAlias type="pojo.Student" alias="student"/>
        	<!-- 批量设置别名
        	指定报名,mybatis会自动扫描包中的类,并设置别名为类名(首字母不区分大小写)
        	-->
        	<package name="pojo"/>
        </typeAliases>
        
  4. typeHandlers(类型处理器)
    mybatis中通过typeHandlers完成jdbc类型和java类型的转换。
    mybatis自带的类型处理器基本上满足日常需求,不需要单独定义。
    mybatis支持类型处理器:http://www.mybatis.org/mybatis-3/configuration.html#typeHandlers
  5. mappers(映射配置)
    • 通过resource方法一次加载一个映射文件
      在这里插入图片描述
    • 通过mapper接口加载映射文件
      需要遵循一些规则:
      • 首先,mapper接口需要和mapper.xml文件放在同一个目录下
      • 文件名必须保持一致
      • 使用的是mapper代理的方法来进行dao开发
        在这里插入图片描述
        在这里插入图片描述
        批量加载mapper:
        在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值