一、认识MyBatis
MyBatis 是什么?
What is MyBatis?
MyBatis is a first class persistence framework with support for custom SQL, stored procedures and advanced mappings. MyBatis eliminates almost all of the JDBC code and manual setting of parameters and retrieval of results. MyBatis can use simple XML or Annotations for configuration and map primitives, Map interfaces and Java POJOs (Plain Old Java Objects) to database records.
MyBatis 是一个一流的持久性框架,它支持定制SQL、存储过程和高级映射。(是什么)
MyBatis 消除了几乎所有的JDBC代码和参数的手动设置和结果的检索。(优势)
MyBatis 可以使用简单的XML或注释来进行配置和映射原语,映射接口和Java pojo(普通旧式Java对象)到数据库记录。 (怎么做到的)
对比 JDBC 和 MyBatis
MyBatis使用需要一个动词(TestMapper),一个名词(Test),
JDBC
Class.forName("com.mysql.cj.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/gp?useUnicode=true&characterEncoding=utf-8&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC", "root", "123456");
preparedStatement = connection.prepareStatement("SELECT * FROM test WHERE id = ?");
preparedStatement.setInt(1, id);
MyBatis
TestMapper testMapper = sqlSession.getMapper(TestMapper.class);
return testMapper.insert(test);
JDBC的连接.png
MyBatis架构.png
二、使用 Mybatis
使用过程
可以采用 XML 的形式来配置,还可以采用 Annotation 的形式来配置
在一开始,每一个 XML 的 name 都对应 JAVA 实体类的一个属性!
1. 编程式
2. 集成式 managed (集成到 Spring)
Mybatis 编程式的代码
public static SqlSession getSqlSession() throws FileNotFoundException {
//配置文件
InputStream configFile = new FileInputStream(
"E:\\workspace\\code\\git\\gupaoedu-mybatis\\src\\main\\java\\com\\gupaoedu\\mybatis\\demo\\mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configFile);
//加载配置文件得到SqlSessionFactory
return sqlSessionFactory.openSession();
}
public static void main(String[] args) throws FileNotFoundException {
TestMapper testMapper = getSqlSession().getMapper(TestMapper.class);
Test test = testMapper.selectByPrimaryKey(1);
}
COC:coversation over configuration
约定优于配置。
MyBatis 连接的过程.png
3. 工作当中的使用方式:
4. Generator
-
pom.xml 配置 generator 插件
<plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.3</version> <configuration> <configurationFile>${project.basedir}/src/main/resources/mybatis/generatorConfig.xml</configurationFile> </configuration> </plugin>
-
配置 generatorConfig.xml
-
执行 mvn mybatis-generator:generate
-
生成 Bean 和 Example
要分包,防止出错(逆向生成的文件和工程里的要分开)
当 自动生成的文件和平时用的放到一起的时候,每一次逆向生成文件都容易和以前的产生冲突,每一次的回滚都是非常痛苦的。
我们能不能用架构来驾驭人,有些人你怎么说都没用,我就用一些规范来规范你,你要生成去另一个包里边去生成,永远不可能损害到我工程里边,防患于未然。有些人不是爱乱搞,他就是不会。
Example
的简单使用例子
@Test
public void example() {
TestExample example = new TestExample();
example.setLimitClause("0,10");
List<com.gupao.dal.dao.Test> tests = mapper.selectByExample(example);
System.out.printf(tests.toString());
}
Example
的不好的原因
大公司会有 DBA,他会去审查你的 SQL 语句,你要将你的 SQL 语句 + Mapper 都发给 DBA,然后让他帮你建表,然后过一遍。
然后你直接不用再写了 SQL,然后 DBA 也没办法审查你的 SQL 了。
example.createCriteria().andIdEqualTo(11).andNameEqualTo("");
和example.createCriteria().andNameEqualTo("").andIdEqualTo(11);
如果你建了索引,他是完全不同的速度 **。一个命中索引,一个没有命中索引。**很难查到这个问题,
5. 作用域 SCOPE-生命周期
Scope | |
---|---|
SqlSessionFactoryBuilder | method |
SqlSessionFactory | application |
SqlSession | request/method (可以 认为是线程级) |
Mapper | method |
SqlSessionFactoryBuilder
用一次,就返回了
//配置文件 InputStream configFile = new FileInputStream( "E:\\workspace\\code\\git\\gupaoedu-mybatis\\src\\main\\java\\com\\gupaoedu\\mybatis\\demo\\mybatis-config.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configFile); //加载配置文件得到SqlSessionFactory return sqlSessionFactory.openSession();
SqlSessionFactory
它是全局性的。
SqlSession
是一个方法,一次Request
和 Response
建立一次 SqlSession,可以认为是 线程级别的。
Mapper
method
6. Mapper 的 xml 和 annotation 形式
一个 接口对应一个 XML
Interface
Test selectByPrimaryKey(Integer id);
XML
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from test
where id = #{id,jdbcType=INTEGER}
</select>
annotation 注解形式
@Select("select * from test where id = 2")
Test selectByPrimaryKey(Integer id);
XML 形式和 Annotation 是兼容的吗?
是互补式的兼容,没有优先,–> 是一种互补的形式。
同时存在启动会报错
Mapped Statements collection already contains value for com.darian.dal.dao.Testmapper.selectByPrimaryKey
PROS VS cons
Pros | Cons | |
---|---|---|
Mapper.xml | 1. 跟接口分离、统一管理 2. 复杂的语句可以不影响接口的可读性 |
1. 过多的 XML 文件 |
Annotation | 1. 接口就能够看到 Sql 语句,可读性高,不需要再去找 xml 文件,方便 | 1. 复杂的联合查询不好维护,代码的可读性差。 |
7.MyBatis 配置文件 Config 文件部分解读
Environment
数据源,可以配置多个数据源
<environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/gp?useUnicode=true&characterEncoding=utf-8&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments>
TypeHandler
转换了,不需要做 数据库 和 JAVA 的处理
我们可以自定义 TypeHandler 转化:
枚举类型:Color
JAVA 英文 数据库 JAVA 中文 red 1 红色 green 2 绿色
sqlSessionFactoryBean.setTypeHandlers(new TypeHandler[]{new TestTypeHandle()});
基于某一个 SQL 来做的,不会影响你全局的东西。(BUG 比较难找)
<typeHandlers> <typeHandler handler="xxxx"></typeHandler> </typeHandlers>
然后在某一个 SQL 上去配置对应的 typeHandler
Plugins
拦截器。
@Intercepts({@Signature(type = Executor.class,
method = "query",
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})
课后作业:
-
Mapper 在 Spring 管理下其实是单例,为什么可以是一个单例?
Keep it simple, keep Mappers in the method scope. The following example demonstrates this practice.
SqlSession session = sqlSessionFactory.openSession(); try { BlogMapper mapper = session.getMapper(BlogMapper.class); // do work } finally { session.close(); }
官网上是这样写的。
SCOPE --> application
-
MyBatis 在 Spring 集成下没有 mapper 的 xml 文件会不会报错,为什么?
-
TypeHandler 手写
-
手写多个 Plugin,多个 interceptor 到底谁先执行? 顺序由谁去决定的?
微信公众号:不止极客
共同学习,写下你的评论
评论加载中...
作者其他优质文章