初识Mybatis,聊聊mybatis对我们编写的影响,安利lombok简化开发流程(上)

一、了解MyBatis

1、历史(百度百科)

  • MyBatis 本是apache的一个开源项目【iBatis】, 2010年这个项目由apache software foundation(Apache软件基金会) 迁移到了google code(谷歌的代码托管平台),并且改名为MyBatis ,2013年11月迁移到Github。

2、作用 (百度百科)

  • MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。

3、说说持久化

​ 持久化是将程序数据在持久状态和瞬时状态间转换的机制。通俗的讲,就是瞬时数据(比如内存中的数据,是不能永久保存的)持久化为持久数据(比如持久化至数据库中,能够长久保存)。

  1. 程序产生的数据首先都是在内存。
  2. 内存是不可靠的,他丫的一断电数据就没了。
  3. 那可靠的存储地方是哪里?硬盘、U盘、光盘等。
  4. 我们的程序在运行时说的持久化通常就是指将内存的数据存在硬盘。

4、说说持久层

其实分层的概念已经谈到过:

  • 业务是需要操作数据的
  • 数据是在磁盘上的
  • 具体业务调用具体的数据库操作,耦合度太高,复用性太差
  • 将操作数据库的代码统一抽离出来,自然就形成了介于业务层和数据库中间的独立的层

5、聊聊ORM

​ ORM,即Object-Relational Mapping(对象关系映射),它的作用是在关系型数据库和业务实体对象之间作一个映射,这样,我们在具体的操作业务对象的时候,就不需要再去和复杂的SQL语句打交道,只需简单的操作对象的属性和方法。

  • jpa(Java Persistence API)是java持久化规范,是orm框架的标准,主流orm框架都实现了这个标准。
  • hibernate:全自动的框架,强大、复杂、笨重、学习成本较高,不够灵活,实现了jpa规范。Java Persistence API(Java 持久层 API)
  • MyBatis:半自动的框架(懂数据库的人 才能操作) 必须要自己写sql,不是依照的jpa规范实现的。

很多人青睐 MyBatis ,原因是其提供了便利的 SQL 操作,自由度高,封装性好...... JPA对复杂 SQL 的支持不好,没有实体关联的两个表要做 join ,的确要花不少功夫。

6、MyBatis的优点和缺点

  • sql语句与代码分离,存放于xml配置文件中:

    优点:便于维护管理,不用在java代码中找这些语句;

    缺点: JDBC方式可以用打断点的方式调试,但是MyBatis调试比较复杂,一般要通过log4j日志输出日志信息帮助调试,然后在配置文件中修改。

  • 用逻辑标签控制动态SQL的拼接:

    优点:用标签代替编写逻辑代码;

    缺点:拼接复杂SQL语句时,没有代码灵活,拼写比较复杂。不要使用变通的手段来应对这种复杂的语句。

  • 查询的结果集与java对象自动映射:

    优点:保证名称相同,配置好映射关系即可自动映射或者,不配置映射关系,通过配置列名=字段名也可完成自动映射。

    缺点:对开发人员所写的SQL依赖很强。

  • 编写原生SQL:

    优点:接近JDBC,比较灵活。

    缺点:对SQL语句依赖程度很高;并且属于半自动,数据库移植比较麻烦,比如MySQL数据库编程Oracle数据库,部分的SQL语句需要调整。

  • 最重要的一点,使用的人多!公司需要!

二、搭建个环境

1、建立数据库

sql 复制代码
CREATE DATABASE `ssm`;
USE `ssm`;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(20) NOT NULL,
`username` varchar(30) DEFAULT NULL,
`password` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert  into `user`(`id`,`username`,`password`) values (1,'itnanls','123456'),(2,'itlils','abcdef'),(3,'ydlclass','987654');

2、构建一个父工程

尝试学习聚合工程的规范,当然可以搭建独立的工程,我们选择一个比较新的jdk版本11:

将父工程的打包方式修改成pom,表示一个聚合工程:

xml 复制代码
<packaging>pom</packaging>

#3、父工程的maven配置

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.ydlclass</groupId>
    <artifactId>ssm</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <!-- 父模块用于约束版本信息 -->
    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <junit.version>4.13.1</junit.version>
        <mybatis.version>3.5.7</mybatis.version>
        <mysql-connector-java.version>8.0.26</mysql-connector-java.version>
        <lombok.version>1.18.22</lombok.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- 单元测试 -->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>
            <!-- mybatis 核心 -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>${mybatis.version}</version>
            </dependency>
            <!-- 数据库确定 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql-connector-java.version}</version>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
                <scope>provided</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>

4、创建子模块

pom

xml 复制代码
<properties>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <scope>provided</scope>
    </dependency>
</dependencies>

<!-- 处理资源被过滤问题 -->
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
                <source>${maven.compiler.target}</source> <!-- 源代码使用的JDK版本 -->
                <target>${maven.compiler.target}</target> <!-- 需要生成的目标class文件的编译版本 -->
                <encoding>UTF-8</encoding><!-- 字符集编码 -->
            </configuration>
        </plugin>
    </plugins>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
    </resources>
</build>

5、回顾我们的jdbc代码

ini 复制代码
@Test
public void testConnection1() throws Exception{
    //1.数据库连接的4个基本要素:
    String url = "jdbc:mysql://localhost:3306/ssm?characterEncoding=utf8&serverTimezone=Asia/Shanghai";
    String username = "root";
    String password = "root";
    //8.0之后名字改了  com.mysql.cj.jdbc.Driver
    String driverName = "com.mysql.cj.jdbc.Driver";

    //2.实例化Driver
    Class clazz = Class.forName(driverName);
    Driver driver = (Driver) clazz.newInstance();
    //3.注册驱动
    DriverManager.registerDriver(driver);
    //4.获取连接
    Connection conn = DriverManager.getConnection(url, username, password);

    PreparedStatement preparedStatement = conn.prepareStatement("select * from user where id = ?");
    preparedStatement.setInt(1,1);
    ResultSet resultSet = preparedStatement.executeQuery();

    // 处理结果集
    while (resultSet.next()){
        User user = new User();
        user.setId(resultSet.getInt("id"));
        user.setUsername(resultSet.getString("username"));
        user.setPassword(resultSet.getString("password"));
        System.out.println(user);
    }
}

6、编写MyBatis核心配置文件,mybatis-config.xml

有兴趣的自行深入研究。

  1. UNPOOLED:不使用连接池的数据源
  2. POOLED:使用连接池的数据源
  3. JNDI:使用JNDI实现的数据源,我们在学习JavaEE的时候学习过了

配置文件我们从官网复制:mybatis.org/mybatis-3/z...

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>
        <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/ssm?characterEncoding=utf8&amp;serverTimezone=Asia/Shanghai"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </properties>

    <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>
</configuration>

小知识:

#(1)DTD:

DTD(Document Type Definition)即文档类型定义,是一种XML约束模式语言,是XML文件的验证机制

如下所示是公共DTD示例。

xml 复制代码
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

关于DTD的声明解释如下:

1、DTD声明始终以!DOCTYPE开头,空一格后跟着文档根元素的名称。

2、根元素名:configuration。所以每一个标签库定义文件都是以taglib为根元素的,否则就不会验证通过。

3、PUBLIC "-//mybatis.org//DTDopen in new window Config 3.0//EN,这是一个公共DTD的名称(私有的使用SYSTEM表示)。这个东西命名是有些讲究的。首先它是以"-"开头的,表示这个DTD不是一个标准组织制定的。(如果是ISO标准化组织批准的,以"ISO"开头)。接着就是双斜杠"//",跟着的是DTD所有者的名字,很明显这个DTD是MyBatis公司定的。接着又是双斜杠"//",然后跟着的是DTD描述的文档类型,可以看出这份DTD描述的是DTD Config 3.0的格式。再跟着的就是"//"和ISO 639语言标识符。

4、绿色的字"mybatis.org/dtd/mybatis...",表示这个DTD的位置。

疑问:是不是xml分析器都会到java.sun.com上去找这个dtd呢?答案是否定的,xml分析器首先会以某种机制查找公共DTD的名称,查到了,则以此为标准,如果查不到,再到DTD位置上去找。

(2)XSD

​ 文档结构描述XML Schema Definition 缩写,这种文件同样可以用来定义我们xml文件的结构!

我们看看pom文件的xml头部:

ini 复制代码
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd
">

1、第一行的xmlns代表了一个xml文件中的一个命名空间,通常是一个唯一的字符串,一般使用一个url,因为不会重复嘛。

它的语法如下:

ini 复制代码
xmlns:namespace-prefix="namespaceURI"

后边什么也不加,代表默认命名空间,我们在书写标签的时候不需要加任何前缀。

如果我将其改为:

ini 复制代码
xmlns:c="http://maven.apache.org/POM/4.0.0"

image-20211104144031737

2、xmlns:xsi 定义了一个命名空间前缀 xsi 对应的唯一字符串 www.w3.org/2001/XMLSch... xmlns:xsi 在不同的 xml 文档中似乎都会出现。 这是因为, xsi 已经成为了一个业界默认的用于 XSD((XML Schema Definition) 文件的命名空间。 而 XSD 文件(也常常称为 Schema 文件)是用来定义 xml 文档结构的。剩余两行的目的在于为我们的命名空间指定对应的xsd文件。

事实上我们这么写也是可以的:

image-20211104144300243

上面这行的语法其实是, xsi:schemaLocation = "ns1url xsd1 ns2url xsd2"

XML Schema相对于DTD的优点在于:

  1. XML Schema基于XML,没有专门的语法。
  2. XML Schema可以像其他XML文件一样解析和处理。
  3. XML Schema比DTD提供了更丰富的数据类型。
  4. XML Schema提供可扩充的数据模型。
  5. XML Schema支持综合命名空间。
  6. XML Schema支持属性组。

7、lombok

平时的工作中写setter和getter以及toString方法是不是已经烦了,每次添加一个字段都要重新添加这些方法。

今天我们学习一个神器,从此再也不用写这些重复的代码了,它们在编译的时候动态的帮我们生成这些代码。

  1. javac对源代码进行分析,生成了一棵抽象语法树(AST)
  2. 运行过程中调用实现了"JSR 269 API"的Lombok程序
  3. 此时Lombok就对第一步骤得到的AST进行处理,找到@Data注解所在类对应的语法树(AST),然后修改该语法树(AST),增加getter和setter方法定义的相应树节点
  4. javac使用修改后的抽象语法树(AST)生成字节码文件,即给class增加新的节点(代码块)

1,首先,我们必须安装一个插件,否则编译的时候会报错,你没有写setter方法,又去调用它当然不能编译:

image-20211020113926489

2、引入依赖,lombok在编译的时候,会根据我们的注解动态生成我们需要的构造方法,setter和getter等,运行的时候就没用了。所以scope选择provided。

xml 复制代码
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.16</version>
    <scope>provided</scope>
</dependency>

从今往后,只需要在对应的类上加上这几个注解,就能完成对应的编译工作

  • @AllArgsConstructor:生成全参构造器。
  • @NoArgsConstructor:生成无参构造器。
  • @Getter/@Setter: 作用类上,生成所有成员变量的getter/setter方法;作用于成员变量上,生成该成员变量的getter/setter方法。可以设定访问权限及是否懒加载等。
  • @Data:作用于类上,是以下注解的集合:@ToString @EqualsAndHashCode @Getter @Setter @RequiredArgsConstructor
  • @Log:作用于类上,生成日志变量。针对不同的日志实现产品,有不同的注解。

注解还有很多,自行学习。

less 复制代码
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {

    private static final Long serialVersionUID = 1L;

    private int id;
    private String username;
    private String password;
}
相关推荐
Estar.Lee3 小时前
查手机号归属地免费API接口教程
android·网络·后端·网络协议·tcp/ip·oneapi
2401_857610035 小时前
SpringBoot社团管理:安全与维护
spring boot·后端·安全
凌冰_5 小时前
IDEA2023 SpringBoot整合MyBatis(三)
spring boot·后端·mybatis
码农飞飞5 小时前
深入理解Rust的模式匹配
开发语言·后端·rust·模式匹配·解构·结构体和枚举
一个小坑货5 小时前
Rust 的简介
开发语言·后端·rust
monkey_meng6 小时前
【遵守孤儿规则的External trait pattern】
开发语言·后端·rust
Estar.Lee6 小时前
时间操作[计算时间差]免费API接口教程
android·网络·后端·网络协议·tcp/ip
新知图书7 小时前
Rust编程与项目实战-模块std::thread(之一)
开发语言·后端·rust
盛夏绽放7 小时前
Node.js 和 Socket.IO 实现实时通信
前端·后端·websocket·node.js
Ares-Wang7 小时前
Asp.net Core Hosted Service(托管服务) Timer (定时任务)
后端·asp.net