今日内容

1 引言
2 MyBatis介绍
3 环境搭建
4 入门演示(MyBatis开发步骤)
5 CRUD
6 配置细节

一、引言

1.1 复习

第一阶段(JavaSE)

  • java基本语法
  • 流程控制
  • 面向对象
  • 常用类
  • 集合
  • 异常
  • IO
  • 多线程
  • JDK新特性

第二阶段(JavaWeb)

  • 前端

    • html
    • css
    • js --> JQuery
    • boostrap
    • layui
      • 页面元素
      • 内置模块
  • 服务器端
    • Maven

      • 项目结构(java/javaweb)
      • pom依赖文件
    • Tomcat
    • Servlet
      • 接收请求
      • 做出响应
  • 数据库
    • 基本语句(DDL,DML, DQL) 牛客网-复习
    • 函数
    • 索引,事务,存储引擎
    • JDBC
    • DBUtil
  • 项目
    • 项目整个开发流程
    • 项目结构
    • 项目开发的三层架构
    • 项目中前端后端如何交互
    • 如何调试
      • 输出语句
      • idea - debug
        • 用过之后及时取消
      • 浏览器 - debug
      • 多看日志(控制台,上下翻开)
      • 按照功能逻辑,从头到尾去讲一遍

1.2 框架

SSM --> Spring,SpringMVC,Mybatis , 目前市面很流行的开发框架


什么是框架?

就是为了简化开发步骤,提高开发效率

MyBatis --> 数据访问层框架,把之前的JDBC再封装一下,变得简单易用

SpringMVC --> 控制层框架,基于spring,把之前Servlet再封装一下,变得简单易用

Spring —> 是一个大型容器,是一个"管家",管理项目中所有"对象"(javabean)(不是业务层框架)

特别注意: 框架只是提高开发效率,但是具体业务逻辑,还要自己写

二、Mybatis

2.1 之前的JDBC的使用缺点?

  • 大量的代码重复
  • 手动加载驱动,创建连接(Connection),关流
  • 封装数据麻烦(ORM)
  • 效率不高(没有缓存)

2.2 Mybatis的介绍

官网: mybatis – MyBatis 3 | Introduction

MyBatis本是apache的一个开源项目iBatis,2010年这个项目由apache software foundation迁移到了google code,并且改名为MyBatis。2013年11月迁移到Github。

iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。用于操作数据库。


MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。且有缓存机制,可以提高查询效率。


Mybatis是一个半ORM框架,可以消除JDBC的代码和步骤,让开发者只关注SQL本身。

ORM是对象关系映射,是指数据库表和java实体类一一对应.

半ORM框架,还是需要写SQL,由框架帮你完成映射

完全ORM框架,连SQL都不需要写,只需要遵循ORM的要求,就会自动生成SQL完成映射(Hibernate,JPA等)

三、 MyBatis开发步骤【重点】

官网入门手册中说明如下:

  • 创建项目
  • 加入依赖
  • 执行SQL
    • XML

      • XML 配置文件中包含了对 MyBatis 系统的核心设置,包括获取数据库连接实例的数据源(DataSource)以及决定事务作用域和控制方式的事务管理器(TransactionManager)
    • 获得SqlSessionFactoryBuilder
    • 获得SqlSessionFactory
    • 获得SqlSession
    • 执行SQL

自己确定开发步骤

  • 确定表结构和数据
  • 创建项目,加入依赖
  • 确定实体类
  • 写mybatis核心配置文件
  • 写Mapper接口
  • 写Mapper接口对应的映射文件XML
  • 核心配置文件,加载映射文件
  • 通过核心配置文件,获得SqlSessionFactoryBuilder
  • 通过SqlSessionFactoryBuilder 获得 SqlSessionFactory
  • 通过SqlSessionFactory获得SqlSession
  • SqlSession获得接口文件的代理对象
  • 通过代理对象调用方法执行

3.0 数据准备

create database 2307_mybatis;
create table tb_user(id int primary key auto_increment,username varchar(50),password varchar(50),phone varchar(50),createTime date,money double
)default charset = utf8;

3.1 依赖

    <dependencies><!-- mybatis --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.6</version></dependency><!-- mysql驱动包 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency><!-- 小辣椒 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version></dependency></dependencies>

idea安装插件

实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User {private int id;private String username;private String password;private String phone;private Date createTime;private double money;private int sex;
}

3.2 写mybatis核心配置文件

名字: 名称任意,一般有这么几种: sqlconfing.xml或者mybatis-config.xml

位置:resources下

内容:(第一次从官网拷贝)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/database_name"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment></environments><mappers><!-- TODO 加载映射文件 --></mappers>
</configuration>

3.3 写Mapper接口文件

以前需要创建dao层包结构,创建XxxDao接口,以及XxxDaoImpl实现类

现在使用mybatis后,dao层包结构命名为mapper,在包下创建XxxMapper.java接口文件

3.4 写Mapper映射文件

  • 为什么要?

    • 以前是写接口的实现类,自己在类中自己写JDBC步骤,完成CRUD操作;现在,需要使用Mybatis的映射文件,我们需要在配置文件中写sql,剩下的动作mybatis完成.即不需要再写实现类.而是需要创建一个接口的映射文件
  • 写到哪?

  • 一种写到resources下 (今天用这种)

  • 另一种,可以写在com.qf.mapper包下(后续再用)

  • 名字?

    • 与接口文件一样UserMapper.xml
  • 怎么写?如下

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace名称空间 -->
<!-- 用来关联,映射文件(XML)和接口文件,即接口的类路径 -->
<mapper namespace="com.qf.mapper.UserMapper"><!--select标签,用于执行查询语句id: 是接口中的方法名resultType: 返回的结果类型,是接口对应方法的返回值[现在只写User报错,要写完整类路径]--><select id="findUserById" resultType="com.qf.model.User"><!-- #{id} 就相当于是之前的预处理的 ?,会自动给此处复制  --><!-- 其实就是接口方法的参数列表的值,会传给 #{id} -->select * from tb_user where id = #{id}</select>
</mapper>

3.5 核心配置文件得加载映射文件

3.6 测试

package com.qf.test;import com.qf.mapper.UserMapper;
import com.qf.model.User;
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;/*** --- 天道酬勤 ---** @author QiuShiju* @desc*/
public class TestMybatis {// TODO 优化public static void main(String[] args) throws IOException {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);// 不用背,知道有这一步,下次直接复制SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);// 获得SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession( );// BlogMapper mapper = session.getMapper(BlogMapper.class);// Blog blog = mapper.selectBlog(101);// 利用的动态代理技术,获得UserMapper的代理对象UserMapper userMapper = sqlSession.getMapper(UserMapper.class);// 调用方法干活User user = userMapper.findUserById(1);System.out.println(user);}
}

四、 单元测试【熟练】

以前测试代码,都需要创建主方法,但是一个主方法只能完成一个功能! 再有新功能,就需要抽取方法,再继续再main方法中再写 —>这些写很麻烦


测试,就可以使用单元测试来测试代码,每个方法都可以独立执行,还可以抽取一些公用代码,减少重复

4.1 加入依赖

<!-- 单元测试 -->
<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13</version><!-- scope使用范围,test是指只能测试环境生效--><scope>test</scope>
</dependency>

4.2 使用

在测试包下,创建类,定义方法,加上注解即可使用

// 方法不能是static,不能有返回值,不能有参数
@Test
public void selectById() throws IOException {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);// 不用背,知道有这一步,下次直接复制SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);// 获得SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession( );// BlogMapper mapper = session.getMapper(BlogMapper.class);// Blog blog = mapper.selectBlog(101);// 利用的动态代理技术,获得UserMapper的代理对象UserMapper userMapper = sqlSession.getMapper(UserMapper.class);// 调用方法干活User user = userMapper.findUserById(1);System.out.println(user);
}

4.3 抽取公共代码

SqlSession sqlSession = null;@Before  // 该注解一加,该方法就会在每个单元测试方法【执行前】执行
public void init() throws IOException {System.out.println("前前前前前前" );String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);// 不用背,知道有这一步,下次直接复制SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);// 获得SqlSessionsqlSession = sqlSessionFactory.openSession( );
}

五、 CRUD

5.1 查询

5.1.1 单条件查询

略,详情看入门演示

【特别注意:ORM时字段名要和实体类属性一致,否则封装失败】

<select id="findUserById" resultType="com.qf.model.User"><!-- #{id} 就相当于是之前的预处理的 ?,会自动给此处赋值  --><!-- 其实就是接口方法的参数列表的值,会传给 #{id} --><!-- 查询返回的结果集,会自动封装到resultType指定的对象!! --><!--  但是ORM能自动封装有个前提: 查询返回的列名和实体类的属性名要完全一致--><!--select id uid,username uname,password pwd,phone tel,createTime,sex,money from tb_user where id = #{id}
-->select id,username,password,phone,createTime,sex,money from tb_user where id = #{id}
</select>

5.1.2 查询全部

设计查询接口方法

public interface UserMapper {List<User> findAll();
}

映射文件

    <!-- 一个标签,就是一个SQL执行的语句 --><!-- 【注意】虽然查询返回集合,但是返回类型此处还要写集合中存储的类型 --><!-- 【或者这样理解】虽然返回集合,此处定义的是查询返回要封装的实体类类型 --><select id="findAll" resultType="com.qf.model.User">select * from tb_user</select>

测试

@Test
public void selectAll() throws IOException {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);// 不用背,知道有这一步,下次直接复制SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);// 获得SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession( );UserMapper mapper = sqlSession.getMapper(UserMapper.class);List<User> list = mapper.findAll( );for (User user : list) {System.out.println(user );}
}

5.1.3 多参数查询

需求: 通过用户名和密码查询

接口方法

public interface UserMapper {User findUserByLogin(String username,String password);
}

映射文件

<select id="findUserByLogin" resultType="com.qf.model.User"><!-- 默认是不支持传多个参数,传入多个参数时,需要如下操作(2选1) --><!--方案1: #{}内按顺序写param1,param2,....-->select * from tb_user where username = #{param1} and password = #{param2}
</select>



接口方法(参数加注解)

public interface UserMapper {User findUserByLogin(@Param("username") String username, @Param("password") String password);}

映射文件

    <select id="findUserByLogin" resultType="com.qf.model.User"><!-- 默认是不支持传多个参数,传入多个参数时,需要如下操作(2选1) --><!--方案2: 1)在接口方法添加注解@Param 2)在#{}内写注解的值-->select * from tb_user where username = #{username} and password = #{password}</select>

5.1.4 Map参数查询

需求: 查询时,就要传递分页数据,又要传递模糊查询关键词,此时就可以使用Map来封装参数.

接口方法

public interface UserMapper {User findUserByLoginMap(HashMap<String,Object> map);
}

映射文件

<select id="findUserByLoginMap" resultType="com.qf.model.User"><!-- 参数是Map,#{}内写的map的key -->select * from tb_user where username = #{usernameKey} and password = #{passwordKey}
</select>

测试

@Test
public void selectByLoginMap() throws IOException {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);// 不用背,知道有这一步,下次直接复制SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);// 获得SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession( );UserMapper mapper = sqlSession.getMapper(UserMapper.class);HashMap<String, Object> map = new HashMap<>( );map.put("usernameKey","李豪");map.put("passwordKey","123456");User user = mapper.findUserByLoginMap(map);System.out.println("user = " + user);
}

5.2 增加

接口方法

public interface UserMapper {int addUser(User user);
}

映射文件

    <!--执行插入语句的标签是insertid 是方法名参数类型parameterType="" 可以省略没有指定返回类型,默认返回受影响行数--><insert id="addUser"><!-- 单参数,#{}内随便写 --><!-- 多参数,#{}内要么固定param1,parma2,要么固定是注解的值 --><!-- map参数,#{}内写map的key --><!-- 对象参数,#{}内属性名 -->insert into tb_user values (#{id},#{username},#{password},#{phone},#{createTime},#{money},#{sex});</insert>

测试

    @Testpublic void addUser() throws IOException {UserMapper mapper = sqlSession.getMapper(UserMapper.class);User user = new User( );user.setId(4);user.setUsername("谢博");user.setPassword("123456");user.setPhone("1111");user.setcreateTime(new Date());user.setSex(1);user.setMoney(10000 );int i = mapper.addUser(user);System.out.println(i > 0 ? "插入成功":"失败");// mysql默认的事务是一句话就是一个独立的事务,自动提交// mybatis封装后,默认事务没有自动提交// 所以执行增删改需要手动提交事务sqlSession.commit();}

5.3 增加后主键回填

场景: 下订单,返回订单号

需求: 插入数据后,要得到数据库自增的id

实现: mysql提供一个sql语句select last_insert_id();可以获得上次自增的id

    int insertUser(User user);
    <insert id="insertUser" parameterType="com.qf.model.User">insert into user (username,password,createTime,phone,address)values(#{username},#{password},#{createTime},#{phone},#{address})<!--keyProperty : 装载id的属性order  : 顺序,是指在insert前或者后执行该句话resultType : 结果类型解释: 在插入数据后,执行该句话,将主键查询到将其赋值给User类的id属性--><selectKey keyProperty="id" order="AFTER" resultType="int">select last_insert_id()</selectKey></insert>
   /*** 测试更新*/@Testpublic void testInsert() throws IOException {// 加载配置文件,变成流InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");// 通过流获得工厂SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder( ).build(inputStream);// 通过工厂SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession( );// 通过SqlSession获得接口的代理对象UserMapper mapper = sqlSession.getMapper(UserMapper.class);// 创建一个对象User user = new User( );user.setUsername("喻去子");user.setPassword("123456");user.setAddress("中国 贵州 黔南布依族苗族自治州");user.setcreateTime(new Date());// 执行插入,其中会有主键回填System.out.println("插入前: " +user );int i = mapper.insertUser(user);System.out.println(i );// 提交sqlSession.commit();// 再次打印对象,此时对象中的id有值System.out.println("插入后: " +user );}

5.4 修改

接口方法

public interface UserMapper {int updateUser(User user);
}

映射文件

    <update id="updateUser"><!-- 对象参数,#{}内属性名 -->update tb_user set username=#{username},password=#{password},phone= #{phone},createTime=#{createTime},money=#{money},sex=#{sex}where id = #{id}</update>

测试

    @Testpublic void updateUser() throws IOException {UserMapper mapper = sqlSession.getMapper(UserMapper.class);User user = new User( );user.setId(4);user.setUsername("谢大博");user.setPassword("123456");user.setPhone("22222");user.setcreateTime(new Date());user.setSex(2);user.setMoney(20000 );int i = mapper.updateUser(user);System.out.println(i > 0 ? "更新成功":"失败");// mysql默认的事务是一句话就是一个独立的事务,自动提交// mybatis封装后,默认事务没有自动提交// 所以执行增删改需要手动提交事务sqlSession.commit();}

5.5 删除

自己写

六、细节补充


6.1 解决mapper.xml存放在resources以外路径中的读取问题

Mapper.xml文件除了放在resources下,也可以放在其他位置,常见的会和接口放在一起

如上这样,那么在mybatis-config.xml中就可以这么写

    <mappers><mapper resource="com/qf/mapper/UserMapper.xml"/></mappers>

但是,IDEA默认不会加载这个UserMapper.xml,需要在POM.xml加入如下配置

在pom.xml文件最后追加< build >标签,以便可以将xml文件复制到classes中,并在程序运行时正确读取。

<build>
<!--IDEA的maven项目中,默认源代码目录下的xml等资源文件并不会在编译的时候一块打包进classes文件夹,而是直接舍弃掉。方法1:将xml或properties等配置文件放到resource下,并修改获取配置文件的代码,比如注册mapper.xml的位置等;方法2:在maven中添加过滤:将java下的xml过滤--><resources><resource><directory>src/main/java</directory><includes><include>*.xml</include><!-- 默认(新添加自定义则失效) --><include>**/*.xml</include><!-- 新添加 */代表1级目录 **/代表多级目录 --></includes><filtering>true</filtering></resource></resources>
</build>

如上配置,随着项目模块功能的增多,接口也多了起来,随之对应的映射文件也多了起来,如下

<mappers><mapper resource="com/qf/model/DogMapper.xml"/><mapper resource="com/qf/model/PigMapper.xml"/><mapper resource="com/qf/model/CatMapper.xml"/>......
</mappers>

怎么解决呢?

mybatis的全局配置文件提供了一个简单写法

    <mappers><package name="com.qf.mapper"/></mappers>
<!-- 这样就可以指定包结构,将该包下的所有映射文件全部加载但是这样有要求: 1) 接口和映射文件要在同一个包下2) 接口和映射文件要同名!!!
-->

6.2 properties配置文件

对于mybatis-config.xml的核心配置中,如果存在需要频繁改动的数据内容,可以提取到properties中。

#在resources下创建db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/example?useUnicode=true&characterEncpding=utf8
jdbc.username=root
jdbc.password=123456

修改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><!--添加properties配置文件路径(外部配置、动态替换)--><properties resource="db.properties" /><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><!--使用$ + 占位符--><property name="driver" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></dataSource></environment></environments></configuration>

6.3 类型别名

为实体类定义别名,提高书写效率。

在映射XML文件时,resultType中的类名是全路径,设置了别名就可以简单只写类名即可

<?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><properties ... /><!-- 类型别名 --><typeAliases><!-- 这样是给每一个类单独设置别名 --><!--<typeAlias alias="User" type="com.qf.model.User"/>--><!-- 这样可以直接设置整个包下所有类都有别名,且别名就是类名 --><package name="com.qf.model"/></typeAliases>...
</configuration>

6.4 下换线转驼峰

场景描述:

数据库有个字段create_time,mybatis查询时封装数据到User类中时,User类的属性createTime没有值,是null , 为什么??

原因:

​ 就是因为数据库列create_time和属性名createTime不一致,导致封装失败

解决方案:

​ 开启mybatis中,数据库列,下划线转驼峰

    <settings><setting name="mapUnderscoreToCamelCase" value="true"/></settings>

官方解释:是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn, 默认是false,需要指定成true开启

映射文件,只写类名即可

 <select id="findUserById" resultType="User">select * from tb_user where id = #{id}</select>

6.5 创建log4j配置文件

pom.xml添加log4j依赖

<!-- log4j日志依赖 https://mvnrepository.com/artifact/log4j/log4j -->
<dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version>
</dependency>

创建在resources并命名为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

特别注意: 可以配置只打印sql

log4j.rootLogger=info
# 设置mapper接口类或者配置文件中mapper的路径为debug
log4j.logger.com.qf.mapper=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
级别 描述
ALL LEVEL 打开所有日志记录开关;是最低等级的,用于打开所有日志记录。
DEBUG 输出调试信息;指出细粒度信息事件对调试应用程序是非常有帮助的。
INFO 输出提示信息;消息在粗粒度级别上突出强调应用程序的运行过程。
WARN 输出警告信息;表明会出现潜在错误的情形。
ERROR 输出错误信息;指出虽然发生错误事件,但仍然不影响系统的继续运行。
FATAL 输出致命错误;指出每个严重的错误事件将会导致应用程序的退出。
OFF LEVEL 关闭所有日志记录开关;是最高等级的,用于关闭所有日志记录。

mybatis-config.xml设置使用日志

    <settings><setting name="logImpl" value="LOG4J"/></settings>

然后在执行mybatis代码的是就会有日志输出

作业

练习1 代码重复2遍
作业2 换一张表,再来一遍
思考思考MyBatis到底帮你省了哪些事情?接口文件和映射文件如何关联?接口文件中方法又是如何和映射文件中的语句关联?语句执行时入参都可以有哪些?有什么注意事项?语句执行后返回的有哪些类型?

he.log4j.ConsoleAppender

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

级别 描述
ALL LEVEL 打开所有日志记录开关;是最低等级的,用于打开所有日志记录。
DEBUG 输出调试信息;指出细粒度信息事件对调试应用程序是非常有帮助的。
INFO 输出提示信息;消息在粗粒度级别上突出强调应用程序的运行过程。
WARN 输出警告信息;表明会出现潜在错误的情形。
ERROR 输出错误信息;指出虽然发生错误事件,但仍然不影响系统的继续运行。
FATAL 输出致命错误;指出每个严重的错误事件将会导致应用程序的退出。
OFF LEVEL 关闭所有日志记录开关;是最高等级的,用于关闭所有日志记录。

mybatis-config.xml设置使用日志

    <settings><setting name="logImpl" value="LOG4J"/></settings>

然后在执行mybatis代码的是就会有日志输出

作业

练习1 代码重复2遍
作业2 换一张表,再来一遍
思考思考MyBatis到底帮你省了哪些事情?接口文件和映射文件如何关联?接口文件中方法又是如何和映射文件中的语句关联?语句执行时入参都可以有哪些?有什么注意事项?语句执行后返回的有哪些类型?

day49_mybatis相关推荐

最新文章

  1. kafka异步推送设置重试_一篇文章了解 Kafka 幂等性的原理及实践
  2. ScrollMagic – 酷毙了!超炫的页面滚动交互效果
  3. 第二十七讲 微分方程组解的图像
  4. opsforhash 过期时间_药品过期还能吃吗?本文带你秒懂药品有效期~
  5. Windows文件夹、文件源代码对比工具--WinMerge
  6. 【PD】PowerDesigner生成数据字典
  7. Silverlight 2 应用程序部署到任意HTML页面
  8. codeforces Gargari and Bishops(很好的暴力)
  9. python消息队列celery_python—Celery异步分布式
  10. Scala Case Class
  11. bzoj 5084: hashit
  12. 移动CMPP2.0封装
  13. Reviewboard使用介绍
  14. Adb 微信APP降级工具使用教程
  15. 4k纸是几厘米乘几厘米_4k纸多大(4k纸有几张a4纸大)
  16. 行车记录仪数据被删除了怎么恢复?解决方法分享
  17. 被遗忘的设计模式——空对象模式(Null Object Pattern)
  18. python生成分形图片_如何用TensorFlow生成令人惊艳的分形图案
  19. GTD时间管理:高效管理你的时间,GTD软件一款就够
  20. 用MMD做mmd动态模型

热门文章

  1. [转]为革命保护视力 --- 给 Visual Studio 换颜色
  2. 一分钟教你简单教程:AutoCAD怎么绘制红绿灯?
  3. 祝贺 | 蚂蚁金服年轻科学家曾晓东入选MIT TR35中国榜单
  4. 单分散Eu3+-PS荧光微球/吸附荧光素生物素化聚苯乙烯微球/包覆TiO2粉体的制备方式
  5. 夏天电动汽车起火事故频繁,在于它实在太怕热了
  6. 阿里达摩院python视频教学_阿里达摩院出品的758集的python教程,据说懂中文就能入门高清版...
  7. redis的5种数据类型
  8. charCodeAt()的一些用法
  9. java poi 常用功能代码
  10. python 网络文件传输(邮件+百度网盘(百度云盘)+阿里云盘)