mybatis
- mybatis是一款优秀的持久层框架,即专门和数据库打交道。
- 他支持定制化SQL,存储过程以及高级映射。
- mybatis 避免了几乎所有jdbc代码和手动设置参数以及结果集的获取。
- mybatis 即可使用简单的xml或注解来配置和映射原生类型,接口和POJO。
创建 mybatis 项目步骤:
- 创建maven项目,并删除src目录,方便我们创建子模块module。创建好子module。
- 在pom中导入mybatis依耐,其中junit是做单元测试用的 @Test
3. 在resource下创建mybatis核心配置文件 mybatis-config.xml。
核心配置文件做的事就是连接数据库。
4. sqlSession 和 sqlSessionFactory
sqlSession包含了向数据库执行SQL命令所需的所有方法,类似于jdbc里的preparedStatement。通过sqlSession 类直接操作数据库。下面通过sqlSessionFactory获得sqlSession。
通过sqlSession 工具类获得 sqlSession。
- 以前的jdbc我们是要写实体类的dao层和其对应的实现类,例如 UserDao和 UserDaoImpl,但用mybatis我们只用写 UserDao和一个对应的Mapper.xml文件,dao层需要实现的CRUD的SQL语句全在Mapper.xml中。一个xml对应一个dao接口,根据xml中的namespace对应起来。xml文件相当于dao接口的实现类.每一个mapper.xml都需要在mybatis核心配置文件中注册。
我们接下来要通过 sqlsession.getMapper() 方法获得dao接口的实现类即Mapper,从而使用接口方法。
- maven约定大于配置,可能我们写的配置文件无法被导出或生效,我们要在pom中进行build配置。
总结:mybatis中操作数据库需要 sqlsession和对应的实体类mapper。
可以采用 sqlsession.getMapper(mapper.class)获得对应mapper,用mapper进行增删改查。注意曾删改必须要提交事务, sqlsession.commit()。才能持久化到数据库中。
mybatis可以选择多套环境,通过default id来选择开发环境还说测试环境,事务管理我们默认采用JDBC,数据库连接池默认使用,提高连接数据库的响应。
mybatis核心配置
-
mapper映射,每一个mapper.xml都需要在核心配置文件中配置好映射,映射配置主要有三种方法。常用第一种。所有我们要准守规范,将mapper和mapper.xml同名且都放在dao包中。
第一种:
第二种:使用对应的class进行注册,这样mapper和mapper.xml必须同名,并且必须在同一个包下。
第三种:使用包进行注册,注册整个包下的mapper,但mapper和mapper.xml必须同名,并且必须在同一个包下。 -
environment 环境配置,transactionManager事务管理, dataSource数据源。通过default id来选择开发环境还说测试环境。
-
可以通过properties引入外部配置文件,这样直接在核心配置文件中加载外部properties文件中的属性。例如resource下的配置文件。
-
在核心配置文件中给java类型起别名,typeAliases.。
这样我们在mapper.xml中写的crud语句就不用写resultType的全名了,不然比较麻烦。或者我们干脆扫描实体类包,这样该包下的所有类在mapper.xml中都不用写全名,直接写类名就行啦。
两种方式,第一种可以diy别名,第二种不行,如果非要改,需在实体类上加上别名注解。 -
mybatis核心配置中的设置
-
mybatis日志工厂,在核心配置文件中要是配置了日志工厂,则运行时则会在控制台输出很多操作数据库的信息。
高级的日志工厂例如LOG4J,是Apach的一个开元项目,可以向控制台,文件,GUI组件,套接口服务器,,,输出日志。我们可以通过一个配置文件灵活的配置每一条日志的格式,级别。在pom中导入LOG4J依耐。
再设置日志工厂log4j。
然后在classpath下即resource下面建立log4j.properties配置文件,配置内容可百度。将debug级别的信息输出到控制台和文件。
LOG4J简单实用:实现要在使用log4j的类中导入包,
import org.apache.log4j.Logger,然后在类中弄一个log4j对象的静态引用。
我们就可以使用该静态引用在类中分级别打印日志。
sqlSession, sqlsessionFactory, sqlSessionFactoryBuilder三者的注意事项
- sqlSessionFactoryBuilder可以被实例化使用和丢弃,他用来创建完sqlsessionFactory后就可以被丢弃,因此可以考虑在局部变量中使用它。
- sqlsessionFactory一但被创建就应该在运行期间一直存在,没有理由丢弃它或者重新实例化一个它,可以把它想象成数据库连接池。考虑使用单例模式。
- sqlSession是由sqlsessionFactory.openSession()得到的,他直接和数据库打交道,相当于连接池的连接器每个线程都应该有自己的sqlSession实例,sqlSession不是线程安全的,因此不能被共享,因此我们每当要crud时当场打开一个sqlSession,用完后就给关闭,就相当于随时连接数据库连接池,用完后及时关闭,避免占用sqlsessionFactory的资源,**尤其是在高并发的情况下。通过debug发现我们在核心配置文件中的很多配置最终会赋给sqlsession实例的属性。
结果集映射 resultMap
CRUD时数据库中查出来的字段名和实体类属性名不一样时,对象的自动封装就会失败,这是需要结果集映射。下面的例子是数据库中字段为pwd,而实体类中为password。开发中只需要映射不一样的字段和属性组即可。
使用注解开发
使用注解来映射简单语句有优势,然而对于复杂点的语句,注解就力不从心了,比如结果集映射。如过要完成复杂的事最好还说通过mapper.xml来实现。使用注解只需要mapper接口就不需要其实现mapper.xml了。同时在核心配置文件中注册接口class而不是mapper.xml。
mybatis框架底层原理
不是太明白,回看狂神mybatis 的 p16 mybatis执行流程剖析。
mybatis复杂环境查询
分为一对多和多对一的情况,多对一比如每个学生里面都有一个老师的引用,这样我们从数据库里面查出来要封装对象的时候就需要特别处理,因为学生的老师属性是个对象,此时用 assocation结果查询嵌套。
一对多的情况时,比如一个老师有多个学生,且老师的学生属性是个List《student》,这样我们根据查询结果封装对象的时候就要采用collection结果嵌套查询。
maybatis动态SQL
根据传入的map的不同,实现sql的复用,实现一个查询函数可以查询多种条件下的结果,下面的是动态sql的 if-test查询条件。
条件查询是我们通常都用 where标签搭配 if-test 来使用。这样我们就不需要在查询语句里加where关键字,它会自动生成,即上图的where=1不用写了。总的来说就是第一个满足的if-test会去除and,非第一个满足if-test的会留下and。而要是没有if-test满足,则where都不会留下。
所谓的动态sql。本质还是sql语句,只是我们可以在sql层面去执行一个逻辑代码。
mybatis缓存
只有查询才有缓存,写入是没有缓存的。
mybatis有两个级别的缓存:
一级缓存:
一级缓存是对于sqlsession来说的。一次会话期间有效。默认开启。
二级缓存:
二级缓存是对于mapper来说的,每一个一级缓存即sqlsession针对该mapper的select内容会被保存到该mapper的二级缓存中。
二级缓存需要在mapper中开启。打个cache标签就行了。
二级缓存的内容只能来自一级缓存,如果开启了二级缓存,一级缓存挂了后会把信息交给对应的mapper的二级缓存。这样新的会话来了时查该mapper,就可以从二级缓存里读取信息。