Java教程

百万架构师第九课:设计模式:设计模式容易混淆的几个对比|JavaGuide

本文主要是介绍百万架构师第九课:设计模式:设计模式容易混淆的几个对比|JavaGuide,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

一、认识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

JDBC的连接

MyBatis架构.png

MyBatis架构

二、使用 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

MyBatis 连接的过程

3. 工作当中的使用方式:

分析业务
定义表结构
generotor生成我们所需要的类

4. Generator

  1. 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>
    
  2. 配置 generatorConfig.xml

  3. 执行 mvn mybatis-generator:generate

  4. 生成 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 是一个方法,一次RequestResponse 建立一次 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&amp;characterEncoding=utf-8&amp;useSSL=false&amp;useJDBCCompliantTimezoneShift=true&amp;useLegacyDatetimeCode=false&amp;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})})

课后作业:

  1. 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

  2. MyBatis 在 Spring 集成下没有 mapper 的 xml 文件会不会报错,为什么?

  3. TypeHandler 手写

  4. 手写多个 Plugin,多个 interceptor 到底谁先执行? 顺序由谁去决定的?

来源于: https://javaguide.net

微信公众号:不止极客

这篇关于百万架构师第九课:设计模式:设计模式容易混淆的几个对比|JavaGuide的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!