MyBatis持久层框架

数据持久化:将程序的数据在持久状态和瞬时状态转化的过程

官方文档: MyBatis中文网

内存:断电即失

第一个程序

TeacherMapper接口,有一个获取所有Teacher的方法待实现

public interface TeacherMapper {List<Teacher> getTeacherList();}
  1. 导入依赖(操作数据库时,还需要导入一个mysql-connector-java的依赖)
<dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.7</version>
</dependency>

  1. mybatis.xml文件连接数据库

jdbc.properties

driver=com.mysql.cj.jdbc.Driver
username=root
password=root
url=jdbc:mysql:///mybatis?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=UTC

官方配置文件模板

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="${driver}"/><property name="url" value="${url}"/><property name="username" value="${username}"/><property name="password" value="${password}"/></dataSource></environment></environments><mappers><mapper resource="org/mybatis/example/BlogMapper.xml"/></mappers>
</configuration>

  1. 原本的dao接口实现类daoImpl,现在变成一个和接口同名的mapper.xml文件

    TeacherMapper.xml,就是把这里面的configuration全部换成mapper

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace写入完全限定名,表明这是哪个Mapper接口的实现类-->
<mapper namespace="com.changGe.li.mapper.TeacherMapper"><!--查询方法,id要和接口中的方法名相同,resultType写上返回值类型--><select id="getTeacherList" resultType="com.changGe.li.pojo.Teacher">select * from teacher;</select></mapper>

  1. mybatis-config.xml配置文件中注册TeacherMapper的实现类(TeacherMapper.xml)

mybatis-config.xml

注意:文件用/号来分隔,类用.号来分隔

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!--读取配置文件--><properties resource="jdbc.properties"></properties><!--给类型起别名,以后其它文件再引用时,就可以直接使用别名了--><typeAliases><typeAlias type="com.changGe.li.pojo.Teacher" alias="teacher"/></typeAliases><!-- 环境 --><environments default="development"><environment id="development"><!-- 事务管理器类型为jdbc  默认手动提交事务--><transactionManager type="JDBC"/><!-- 连接池状态是POOLED(连接) --><dataSource type="POOLED"><!--#{driver}从配置文件中读取driver的值--><!-- $是Statement模式读取,#是PreparedStatement模式,但是值会变成字符串格式多数情况下用#,但是遇到如分页的情况时:必须用$--><!--这里如果用#,最后的值会变成'#{username}'--><property name="driver" value="${driver}"/><property name="url" value="jdbc:mysql:///mybatis?useUnicode=true&amp;ampcharacterEncoding=utf8"/><property name="username" value="${username}"/><property name="password" value="${password}"/></dataSource></environment></environments><!--必须注册mapper,不然报错,就是让MyBatis知道应该去哪里找mapper文件注意:文件用/号来分隔,类用.号来分隔--><mappers><mapper resource="com/changGe/li/mapper/StudentMapper.xml"/><mapper resource="com/changGe/li/mapper/TeacherMapper.xml"/></mappers></configuration>

xml中的&要加上amp;来表示

<property name="url" value="jdbc:mysql:///mybatis?useUnicode=true&amp;ampcharacterEncoding=utf8"/>

  1. Mybatis工具类,获取sqlSession(数据库操作)对象
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;public class MyBatisUtil {private static SqlSessionFactory sqlSessionFactory;static {try {//读取配置文件InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-onfig.xml");//工厂构建类 构建 得到sql会话工厂sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);} catch (IOException e) {e.printStackTrace();}}//用工厂类来获取执行sql操作的对象public static SqlSession getSqlSession(){//打开会话,也就是开启和数据库的连接return sqlSessionFactory.openSession();}}

  1. 用SqlSession对象来获取实现类对象,然后执行方法
@Test
public void test(){//工具类获取SqlSession对象SqlSession sqlSession = MyBatisUtil.getSqlSession();//底层用反射机制,获取了接口TeacherMapper的类对象TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);//接口被实现类TeacherMapper.xml实现了,调用接口就是调用实现类的方法List<Teacher> teacherList = mapper.getTeacherList();id:1,姓名是:秦老师for (Teacher teacher : teacherList) {System.out.println("id:"+teacher.getId()+",姓名是:"+teacher.getName());}//一定要关闭会话,免得占用资源sqlSession.close();}
  1. 早年间官方给我们提供了一些默认的方法,可以通过传入方法路径,来直接执行.不过没有第一种方法好理解
@Test
public void test(){SqlSession sqlSession = MyBatisUtil.getSqlSession();TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);//sql会话时,直接调用接口中的方法List<Teacher> teacherList = sqlSession.selectList("com.changGe.li.mapper.TeacherMapper.getTeacherList");//id:1,姓名是:秦老师for (Teacher teacher : teacherList) {System.out.println("id:"+teacher.getId()+",姓名是:"+teacher.getName());}sqlSession.close();
}

注意事项

如果找不到对象,可能因为maven是找不到mapper.xml,用下面的代码,让maven在构建项目时把文件构建进来

<build><resources><resource><!--将src,main,java下的.properties和.xml文件,可以被maven发现--><directory>src/main/java</directory><includes><include>**/*.properties</include><include>**/*.xml</include></includes><filtering>false</filtering></resource></resources>
</build>

好像说mapper.xml中的中文注释也会出问题,可能是要把文件格式改成UTF-8


官方名词概念

三大对象

在后面的生命周期和作用域会讲解

完全限定名

就是可以让mybatis直接打到资源的一个精确名字,如com.changGe.li.pojo.Teacher


CRUD

对象中的值可以直接拿来用

<!-- 从parameterType中拿到的参数,可以直接作用于语句中 -->
<select id="getTeacherByIdAndName" resultType="teacher" parameterType="map">select * from teacher where id=#{id} and name = #{name};
</select>
@Test
public void test(){SqlSession sqlSession = MyBatisUtil.getSqlSession();TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);HashMap<String, String> map = new HashMap<String, String>();map.put("id","1");map.put("name","秦老师");Teacher teacherByIdAndName = mapper.getTeacherByIdAndName(map);System.out.println(teacherByIdAndName);sqlSession.close();}

增删改一定要提交事务sqlsession.commit();

<insert id="addTeacher" parameterType="teacher">insert into teacher values(#{id},#{name})
</insert>

@Test
public void test(){SqlSession sqlSession = MyBatisUtil.getSqlSession();TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);Teacher teacher = new Teacher(2,"李长歌");mapper.addTeacher(teacher);//不提交事务,不更新数据sqlSession.commit();sqlSession.close();}

获取更新时记录的key(slelectKey)

https://blog.csdn.net/kongkongyanan/article/details/86096657

<insert id="insertStudent"><!--通过LAST_INSERT_ID() 获得刚插入的自动增长的id的值。order属性设置成BEFORE,表示在插入前就获取对应的键--><selectKey keyProperty="id" order="AFTER">SELECT LAST_INSERT_ID() AS ID</selectKey>insert into student values(#{id},#{name},#{tid})</insert>
Student student = new Student();
student.setName("张三");
student.setTid(1);mapper.insertStudent(student);System.out.println(student.getId());

模糊查询

select * from teacher where name like concat('%',#{name},'%');
Teacher teacher = mapper.getTeacherByName("长歌");

配置优化

xml规定了所有标签的顺序,必须完全符合规定

properties,settings,

typeAliases,typeHandlers,

objectFactory,objectWrapperFactory,

reflectorFactory,plugins,

environments,databaseIdProvider,

mappers

多环境配置

<environments default="test"><environment id="development"><!--environment必须配置事务管理器和dataSourcemybatis默认事务管理器是jdbc,但是还有一个,只要记得不只一个就行了--><transactionManager type="JDBC"/><!-- 数据库连接池:用完不关,可以回收让别人再用连接池状态是pooled(连接),还有unPooled和jedi(现在不用了)--><dataSource type="POOLED"></dataSource></environment><environment id="test"><transactionManager type="jdbc"/><dataSource type="pooled"><property name="driver" value="${driver}"/><property name="url" value="${url}"/><property name="username" value="${username}"/><property name="password" value="${password}"/></dataSource></environment>
</environments>

属性优化properties 替换需要动态配置的属性值

<properties resource="jdbc.properties"><property name="username" value="root"/>
</properties><dataSource type="pooled"><!--先读取properties里的,再去读取${username}对应的配置文件中的属性,然后后来的覆盖前面的--><property name="username" value="${username}"/>
</dataSource>

类型别名: 降低冗余的全限定类名书写

<typeAliases><typeAlias type="com.changGe.li.pojo.Teacher" alias="teacher"></typeAlias><!--自动为包下所有类,创建首字母小写的别名--><package name="com.changGe.li.pojo"/>
</typeAliases><select id="getTeacherByName" resultType="teacher">

注解设置别名

@Alias("teacher")
public class Teacher {}

但是需要在mybatis-config.xml中,配置在哪个包下扫描注解

<typeAliases><package name="com.changGe.li.pojo"/>
</typeAliases>

系统默认别名

基本类型加_,包装类是对应的基本类型,集合首字母小写

int 别名是 _int,Integer = int, Map = map

<select id="getTeacherByName" resultType="teacher" parameterType="_int">

settings系统配置:改变 MyBatis 的运行时行为

可以设置如日志,缓存懒加载

slf4j依赖

<dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>2.0.0-alpha4</version>
</dependency>
<settings><!--MyBatis默认的日志--><setting name="logImpl" value="SLF4J"/><!--缓存--><setting name="cacheEnabled" value="true"/><!--懒加载--><setting name="lazyLoadingEnabled" value="true"/>
</settings>

MapperGesitry注册,映射器: 直接告诉 MyBatis 到哪里去找映射文件

当用实现类或包注册时,要求:实现类和配置文件与接口同名,且同包!

<mappers><!--1.当映射文件与接口同名,且同包时,写上接口名,会自动找到对应的映射文件--><!--2.或者写上原接口的完全限定名,mybatisX插件会自动根据方法结构来解析出sql语句--><mapper class="com.changGe.li.mapper.TeacherMapper"/><!--将包内的映射器接口实现全部注册为映射器--><package name="com/changGe/li/mapper"/>
</mappers>

如果想分离,要在resource包下创建和接口相同结构的包.

因为mybatis的resource是通过classpath来找文件的


生命周期和作用域

错误的使用可能会出现严重的并发问题

  1. 程序开始,配置文件被sqlsessionfactoryBuilder构建,
  2. 得到sqlsessionfatory工厂模式,
  3. 由此创建sqlsession对象,
  4. 产生对应接口的SQLMapper对象,
  5. 执行数据库操作,最后结束.

从 XML 中构建 SqlSessionFactory

  1. SqlSessionFactoryBuilder 可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例
  2. 每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。

从 SqlSessionFactory 中获取 SqlSession

  1. 我们可以从SqlSessionFactory中获得 SqlSession 的实例

  2. SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。

通过 SqlSession 实例来直接执行已映射的 SQL 语句

  1. sqlsession执行rselectOne()或者selectList()等方法,直接执行sql操作,最后结束

  2. 这种方式对使用旧版本 MyBatis 的用户来说,比较熟悉。

更简洁的方式

  1. 使用指定了语句的参数和返回值相匹配的接口(比如 BlogMapper.class)

  2. 现在代码更清晰,更加类型安全不用担心可能出错的字符串字面值,以及强制类型转换

BlogMapper mapper = session.getMapper(BlogMapper.class);
Blog blog = mapper.selectBlog(101);

作用域



结果集映射:解决数据库字段与对象属性不对应的问题

作用就是:把数据库中返回的字段的值,映射到对象的属性上

对象中有id和age两个属性

@Data
@AllArgsConstructor
@NoArgsConstructor
@Alias("teacher")
public class Teacher {private int id;private String ame;}

配置结果集映射

<!--这里的id对应着select标签中的resultMap返回值类型是Teacher类型-->
<resultMap id="tea" type="teacher"><id column="id" property="id"/><!--把数据库中返回的字段name中的值,映射到对象的ame属性上--><result column="name" property="ame"/>
</resultMap><select id="getTeacherByName" resultMap="tea" parameterType="teacher">select * from teacher where id = #{id} and name = #{ame};
</select>

执行查询

Teacher teacher1 = new Teacher(2, "李长歌");
Teacher teacher = mapper.getTeacherByName(teacher1);

写resultMap时,resultType就可以不用写了


日志工厂

Mybatis 通过使用内置的日志工厂提供日志功能。内置日志工厂将会把日志工作委托给下面的实现之一:

  • SLF4J
  • Apache Commons Logging
  • Log4j 2
  • Log4j
  • JDK logging
  1. MyBatis 内置日志工厂:会基于运行时检测信息,选择日志委托实现

  2. 它会(按上面罗列的顺序)使用第一个查找到的实现

  3. 如果你的环境中并不存在 Log4J,你却试图调用了相应的方法,MyBatis 就会忽略这一切换请求 .

  4. 没有找到这些实现时,将会禁用日志功能


STDOUT_LOGGING(标准输出记录)

xml声明

<settings><!--可选的值有SLF4J、LOG4J、LOG4J2、JDK_LOGGING、COMMONS_LOGGING、STDOUT_LOGGING(标准输出记录)、NO_LOGGING--><setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

执行结果

//读者入口
Reader entry: <?xml version="1.0" encoding="UTF-8" ?>
//检查类 com.changGe.li.mapper.StudentMapper 是否符合条件 [可分配给对象]
Checking to see if class com.changGe.li.mapper.StudentMapper matches criteria [is assignable to Object]Checking to see if class com.changGe.li.mapper.TeacherMapper matches criteria [is assignable to Object]//打开 JDBC 连接
Opening JDBC Connection
//创建连接 1312381159
Created connection 1312381159.
//在 JDBC 连接 [com.mysql.cj.jdbc.ConnectionImpl@4e3958e7] 上将 autocommit(自动提交) 设置为 false
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@4e3958e7]
//准备中
==>  Preparing: select * from teacher where id = ? and name = ?;
//参数
==> Parameters: 2(Integer), 李长歌(String)
//列
<==    Columns: id, name
//行
<==        Row: 2, 李长歌
//总计
<==      Total: 1
//返回结果
Teacher(id=2, name=李长歌)
//在 JDBC 连接 [com.mysql.cj.jdbc.ConnectionImpl@4e3958e7] 上将自动提交重置为 true
Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@4e3958e7]
//关闭 JDBC 连接 [com.mysql.cj.jdbc.ConnectionImpl@4e3958e7]
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@4e3958e7]
//将连接 1312381159 返回到池
Returned connection 1312381159 to pool.

Log4j :java日志

log4j_百度百科 (baidu.com)

使用Log4j框架的作用通俗的解释:

  • 能够控制日志信息想往哪里打就往哪里打,比如:控制台、文件、邮箱、数据库等等。
  • 能够控制日志信息想怎么打就怎么打,比如:我想要打印时间、程序的名称、程序的方法名、程序的行号、线程的名称等等。
  • 能够控制日志信息想打什么打什么,不想打的就不打,日志信息是分级别的,有时候我只想看错误的信息或者警告的信息,有时候我想看到所有的信息我想调试程序等等。

依赖

<dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version>
</dependency>

log4j.properties

#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=【%c】-%m%n#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/kuang.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=【%p】【%d{yy-MM-dd}】【%c】%m%n#日志输出级别:输出DEBUG级别及以上的日志信息
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

简单使用

public class MyBatisTest {//在当前类运行时,输出日志private static Logger logger = Logger.getLogger(MyBatisTest.class);@Testpublic void test(){//在debug时,输出当前为debug模式logger.debug("当前为debug模式");SqlSession sqlSession = MyBatisUtil.getSqlSession();//输出一条普通信息:打印sqlSessionlogger.info(sqlSession);TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);Teacher teacher1 = new Teacher(2, "李长歌");Teacher teacher = mapper.getTeacherByName(teacher1);System.out.println(teacher);sqlSession.close();try {}catch (Exception e){}finally {logger.error("报错了");}}}

日志文件的存放地址

部分日志信息


分页

RowBounds

<select id="getStudent" resultType="student">select * from student;
</select>
@Test
public void test(){SqlSession sqlSession = MyBatisUtil.getSqlSession();StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);//分页,从3开始显示,显示4个RowBounds rowBounds = new RowBounds(2, 4);//方法路径,参数和分页List<Student> students = sqlSession.selectList("com.changGe.li.mapper.StudentMapper.getStudent", null, rowBounds);for (com.changGe.li.pojo.Student student : students) {System.out.println(student);}sqlSession.close();}

MyBatis的分页插件:PageHelper: MyBatis 分页插件 PageHelper


注解开发

根本目的为了解耦

@Select("select * from student;")
List<Student> getStudent();
  1. 运行的本质是:sqlSession(User.class)获取User的类对象,
  2. 然后获取其中所有的数据,读取特定数据上的注解,
  3. 得到其中的value(就是我们写的sql语句),
  4. 自动帮我们配置环境,运行.

Mapper中有一个sqlSession,里面保存了所有的配置信息


增删改

TeacherMapper

@Insert("insert into teacher values(#{id},#{name});")
/*** 将传参id的值交给@Param中的id,然后赋值给sql语句中的#{id}** @Param中的参数名必须与#{}一致,mybatis就是从这里取值的*/
int insertTeacher(@Param("id")int id,@Param("name")String name);
//设置开启自动提交
return sqlSessionFactory.openSession(true);

注解里的需要的参数,会自动去方法传参中找.

比如传参是对象,就会去自动匹配对象的字段。

@Insert("insert into teacher values(#{id},#{name});")
/*** 注解里的需要的参数,会自动去方法传参中找.*/
int insertTeacher(Teacher teacher);
mapper.insertTeacher(new Teacher(4,"太平公主"));

运行分析

MyBatis运行流程(源码):https://zhuanlan.zhihu.com/p/67738448

简略易读版本: MyBatis的执行流程详解 - 知乎 (zhihu.com)

  1. Resource类读取配置文件,创建SqlSessionFactroyBuilder对象

    //读取配置文件的流
    InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");//sql会话工厂构建类 构建 得到sql会话工厂
    sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
    
  2. 这个对象底层用,创建了一个XMLConfig对象.

    public SqlSessionFactory build(InputStream inputStream) {return build(inputStream, null, null);
    }
    
    public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {try {//通过流读取properties文件,创建XMLConfigBUiler对象XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);//XMLConfig对象读取xml配置文件//解析文件中数据,返回SqlSessionFactory对象return build(parser.parse());} catch (Exception e) {} finally {ErrorContext.instance().reset();}}
    
  3. XMLConfigBUiler对象读取xml配置文件,创建Configuration对象,这个对象中包含了所有的基本配置信息

    sqlSession中包含了configuration,里面有所有的配置信息,如environment(环境)

public Configuration parse() {if (parsed) {throw new BuilderException("Each XMLConfigBuilder can only be used once.");}parsed = true;parseConfiguration(parser.evalNode("/configuration"));return configuration;
}
  1. SqlSessionFactroy工厂对象,构建SqlSession对象(openSession)时,底层创建Transactional事务管理器–监听事务.同时创建Execetor执行器

    sqlSession中包含executor和transaction对象

return sqlSessionFactory.openSession();

SqlSessionFactory的实现类:DefaultSqlSessionFactory

private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {//新建事务管理器Transaction tx = null;try {//获取环境final Environment environment = configuration.getEnvironment();//从环境中获取:事务管理器工厂final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);//事务管理器赋值:所有的环境数据,等级和是否自动提交tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);//创建执行器,专门用来执行sql操作,和缓存等final Executor executor = configuration.newExecutor(tx, execType);//把事务管理器和执行器都返回return new DefaultSqlSession(configuration, executor, autoCommit);} catch (Exception e) {//关闭事务管理器closeTransaction(tx); // may have fetched a connection so lets call close()throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);}}

lombok

它是一个插件,还需要maven依赖(也可以直接引用依赖)

<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.22</version>
</dependency>

@Data @AllArgsConstractor @NoArgsConstractor

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {private int id;private String name;private int tid;
}

有一种说法是lombok改变了java的源码,让java语言出现了"文明断层"的情况

MyBatis基础原理相关推荐

  1. 后端技术:mybatis插件原理详解

    关注"Java后端技术全栈" 回复"面试"获取全套面试资料 上次发文说到了如何集成分页插件MyBatis插件原理分析,看完感觉自己better了,今天我们接着来 ...

  2. javaweb实训第六天下午——Mybatis基础

    Mybatis基础 1.课程介绍 2.为什么需要Mybatis 3.初识Mybatis 3.1.Mybatis是什么 3.1.1.什么是框架 3.1.2.什么叫数据库持久化 3.1.3.什么是ORM ...

  3. MyBatis基础学习知识点2

    本文衔接MyBatis基础学习知识点1,继续对以下两个问题进行探讨 1.dao配置文件主要是用来干什么的?如何进行配置? 2.使用测试方法测试程序运行是如何实现的?每条语句起什么作用? 目录 dao配 ...

  4. java mybatis基础

    java mybatis基础 1.1 什么是mybatis? mybatis是一个优秀的持久层框架. 避免几乎所有的JDBC代码和手动设置参数以及获取结果集的过程. 可以使用简单的xml或者注解来配置 ...

  5. 面试官:你分析过mybatis工作原理吗?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 Mybatis工作原理也是面试的一大考点,必须要对其非常清晰,这样 ...

  6. Mybatis底层原理学习(二):从源码角度分析一次查询操作过程

    在阅读这篇文章之前,建议先阅读一下我之前写的两篇文章,对理解这篇文章很有帮助,特别是Mybatis新手: 写给mybatis小白的入门指南 mybatis底层原理学习(一):SqlSessionFac ...

  7. MyBatis基础入门《九》ResultMap自动匹配

    MyBatis基础入门<九>ResultMap自动匹配 描述: Mybatis执行select查询后,使用ResultMap接收查询的数据结果. 实体类:TblClient.java 接口 ...

  8. Mybatis基础:增删改查、模糊查询、多条件查询

    Mybatis基础:增删改查.模糊查询.多条件查询http://www.bieryun.com/3132.html 1.新建测试数据库,根据实体类属性创建 2.实体类 [java] view plai ...

  9. Mybatis运行原理及源码解析

    Mybatis源码解析 一.前言 本文旨在mybatis源码解析,将整个mybatis运行原理讲解清楚,本文代码地址: https://github.com/lchpersonal/mybatis-l ...

最新文章

  1. leetcode解题文件夹
  2. MTK深圳公司嵌入式软件工程师笔试题(含部分答案)
  3. mysql锁等待问题
  4. ARM汇编伪指令 .word
  5. 混沌数学之Rössler(若斯叻)吸引子
  6. E-Learning是学习系统而不是教育系统
  7. 利用sobel算子提取图像的水平特征和竖直特征
  8. Add library ‘Maven: ..to classpath
  9. 响应式设计就是这个时代最值得学习、时间的趋势
  10. 英特尔主板快捷启动键_电脑小匠电脑硬件知识科普——主板接口篇
  11. Linux多线程编程之pthread
  12. 【音视频】使用DXGI实现多屏幕采集(4-2)
  13. C#做一年小孩做一个口算题生成器
  14. 止增笑耳的星际迷航前传
  15. UE4 Pak包热更新
  16. 【转载】Aquanaut:水下变形金刚
  17. tableau:柱图的两种实现方式
  18. tensorflow 1.10下Mask RCNN实现自己数据集
  19. 解决Type interface com.kuang.mapper.UserMapper is not known to the MapperRegistry.的问题
  20. MWCS2019:中国联通与TCL通讯5G终端创新联合研发中心正式揭牌

热门文章

  1. attend,join,participate,take part in
  2. 包含高知漫画家珍贵作品的艺术项目“NAKED Manga Mappin’!”3月6日(周五)起在高知龙马机场展出
  3. 神经网络理论及应用答案,神经网络理论名词解释
  4. R语言笔记——”org.Hs.eg.db“脱坑记录
  5. 微信——产品设计分析报告
  6. videojs实现视频打点标记 Vue
  7. 高价值行为用户一键同步,精准投放提升广告效率
  8. godaddy新建二级域名
  9. direction: rtl;
  10. 汇编指令学习(ADD,SUB,MUL,DIV,XADD,INC,DEC,NEG)