GVKun编程网logo

mybatis 学习笔记:mybatis SQL注入问题(mybatis $注入)

10

在本文中,我们将给您介绍关于mybatis学习笔记:mybatisSQL注入问题的详细内容,并且为您解答mybatis$注入的相关问题,此外,我们还将为您提供关于javaday55【Mybatis连接

在本文中,我们将给您介绍关于mybatis 学习笔记:mybatis SQL注入问题的详细内容,并且为您解答mybatis $注入的相关问题,此外,我们还将为您提供关于java day55【 Mybatis 连接池与事务深入 、 Mybatis 的动态 SQL 语句、 Mybatis 多表查询之一对多 、 Mybatis 多表查询之多对多】、java 学习笔记--mybatis 三剑客(mybatis)、java-mybaits-015-mybatis逆向工程最佳实践【基础mybatis-generator、tk.mybatis、mubatis-plus】、JavaEE--Mybatis 学习笔记(一)--Mybatis 简介的知识。

本文目录一览:

mybatis 学习笔记:mybatis SQL注入问题(mybatis $注入)

mybatis 学习笔记:mybatis SQL注入问题(mybatis $注入)

SQL 注入攻击

首先了解下概念,什么叫SQL 注入:

SQL注入攻击,简称SQL攻击或注入攻击,是发生于应用程序之数据库层的安全漏洞。简而言之,是在输入的字符串之中注入SQL指令,在设计不良的程序当中忽略了检查,那么这些注入进去的指令就会被数据库服务器误认为是正常的SQL指令而运行,因此遭到破坏或是入侵。

最常见的就是我们在应用程序中使用字符串联结方式组合 SQL 指令,有心之人就会写一些特殊的符号,恶意篡改原本的 SQL 语法的作用,达到注入攻击的目的。

举个栗子:

比如验证用户登录需要 username 和 password,编写的 SQL 语句如下:

select * from user where (name = ''"+ username +"'') and (pw = ''"+ password +"'');

username 和 password 字段被恶意填入

username = "1'' OR ''1''=''1";

password = "1'' OR ''1''=''1";

将导致原本的 SQL 字符串被填为:

select * from user where (name = ''1'' or ''1''=''1'') and (pw = ''1'' or ''1''=''1'');

实际上运行的 SQL 语句将变成:

select * from user;

也就是不再需要 username 和 password 账密即达到登录的目的,结果不言而喻。

mybatis 解决 SQL 注入问题

我们使用 mybatis 编写 SQL 语句时,难免会使用模糊查询的方法,mybatis 提供了两种方式 #{}${}

  • #{value} 在预处理时,会把参数部分用一个占位符 ? 替代,其中 value 表示接受输入参数的名称。能有效解决 SQL 注入问题
  • ${} 表示使用拼接字符串,将接受到参数的内容不加任何修饰符拼接在 SQL 中,使用${}拼接 sql,将引起 SQL 注入问题。

举个例子:

1 查询数据库 sample 表 user 中的记录,我们故意使用特殊符号,看能否引起 SQL 注入。使用 mybatis 在 mapper.xml 配置文件中编写 SQL 语句,我们先采用拼接字符串形式,看看结果如何:

 <select id="findUserByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User"> <!-- 拼接 MySQL,引起 SQL 注入 --> SELECT * FROM user WHERE username LIKE ''%${value}%'' </select>

注意在配置文件中编写 SQL 语句时,后边不需要加分号。

调用配置文件,编写测试文件,查询数据库内容,采用特殊符号,引起 SQL 注入:

    @Test
    public void testFindUserByName() throws Exception{ SqlSession sqlSession=sqlSessionFactory.openSession(); //创建UserMapper代理对象 UserMapper userMapper=sqlSession.getMapper(UserMapper.class); //调用userMapper的方法 List<User> list=userMapper.findUserByName("'' or ''1''=''1"); sqlSession.close(); System.out.println(list); } }

运行结果如下图所示:

可以看到执行语句其实变为了

select * from user

将user 表中的全部记录打印出来了。发生了 SQL 注入。

2 如果将配置文件中的 SQL 语句改成 #{} 形式,可避免 SQL 注入。

 <select id="findUserByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User"> <!-- 使用 SQL concat 语句,拼接字符串,防止 SQL 注入 --> SELECT * FROM USER WHERE username LIKE CONCAT(''%'',#{value},''%'' ) </select>

再次运行测试程序,控制台输出如下:

可以看到程序中参数部分用 ? 替代了,很好地解决了 SQL 语句的问题,防止了 SQL 注入。查询结果将为空。

java day55【 Mybatis 连接池与事务深入 、 Mybatis 的动态 SQL 语句、 Mybatis 多表查询之一对多 、 Mybatis 多表查询之多对多】

java day55【 Mybatis 连接池与事务深入 、 Mybatis 的动态 SQL 语句、 Mybatis 多表查询之一对多 、 Mybatis 多表查询之多对多】

第1章 Mybatis 连接池与事务深入

1.1 Mybatis 的连接池技术

1.1.1 Mybatis 连接池的分类

1.1.2 Mybatis 中数据源的配置

1.1.3 Mybatis 中 DataSource 的存取

1.1.4 Mybatis 中连接的获取过程分析

 

1.2 Mybatis 的事务控制

1.2.1 JDBC 中事务的回顾

 

1.2.2 Mybatis 中事务提交方式

1.2.3 Mybatis 自动提交事务的设置

第2章 Mybatis 的动态 SQL 语句

2.1 动态 SQL 之标签 

2.1.1 持久层 Dao 接口

2.1.2 持久层 Dao 映射配置

2.1.3 测试

2.2 动态 SQL 之标签 

2.2.1 持久层 Dao 映射配置

2.3 动态标签之标签 

2.3.1 需求

2.3.1.1 在 QueryVo 中加入一个 List 集合用于封装参数

2.3.2 持久层 Dao 接口

2.3.3 持久层 Dao 映射配置

2.3.3.1 编写测试方法

 2.4 Mybatis 中简化编写的 SQL 片段

2.4.1 定义代码片段

2.4.2 引用代码片段

第3章 Mybatis 多表查询之一对多

3.1 一对一查询(多对一)

3.1.1 方式一

3.1.1.1 定义账户信息的实体类

3.1.1.2 编写 Sql 语句

3.1.1.3 定义 AccountUser 类

3.1.1.4 定义账户的持久层 Dao 接口

3.1.1.5 定义 AccountDao.xml 文件中的查询配置信息

3.1.1.6 创建 AccountTest 测试类

3.1.1.7 小结:

3.1.2 方式二

3.1.2.1 修改 Account 类

在 Account 类中加入 User 类的对象作为 Account 类的一个属性。

3.1.2.2 修改 AccountDao 接口中的方法

3.1.2.3 重新定义 AccountDao.xml 文件

3.1.2.4 在 AccountTest 类中加入测试方法

3.2 一对多查询

3.2.1 编写 SQL 语句

3.2.2 User 类加入 List

3.2.3 用户持久层 Dao 接口中加入查询方法

3.2.4 用户持久层 Dao 映射文件配置

3.2.5 测试方法

第4章 Mybatis 多表查询之多对多

4.1 实现 Role 到 User 多对多

4.1.1 用户与角色的关系模型

4.1.2 业务要求及实现 SQL

4.1.3 编写角色实体类

4.1.4 编写 Role 持久层接口

4.1.5 编写映射文件

4.1.6 编写测试类

4.2 实现 User 到 Role 的多对多

4.2.1 User 到 Role 的多对多

4.2.2 作业:实现 User 到 Role 的一对多查询

 

java 学习笔记--mybatis 三剑客(mybatis)

java 学习笔记--mybatis 三剑客(mybatis)

Java项目中使用Mybatis入门程序

 

wanna 关注

2017.03.23 14:33* 字数 270 阅读 1243评论 0喜欢 5

MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。

欢迎访问本人博客:http://wangnan.tech

什么是 MyBatis ?

MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。

MyBatis github

https://github.com/mybatis/mybatis-3

MyBatis 文档

http://mybatis.github.io/mybatis-3/zh/index.html

入门程序

想要使用 MyBatis 只需将 mybatis-x.x.x.jar 文件置于 classpath 中。
如果使用 Maven 构建项目,则需将下面的 dependency 置于 pom.xml 中:

    <dependency> 
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId> 
        <version>3.8.2</version> 
    </dependency>

我选择第二种,在Eclipse中新建一个maven项目

项目结构:

 

01.jpg

各文件介绍:

  • pom文件:由于使用了mySQL数据库,这里还依赖了一个mySQL驱动包
  • 实体类User :
  • UserMapper接口:
  • UserMapper接口的实现,userMapper.xml:
  • 数据源配置 configuration.xml
  • 测试类MyBatisTest:
     <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>Mybatis</groupId>  
      <artifactId>Mybatis</artifactId>  
      <version>0.0.1-SNAPSHOT</version>  
      <dependencies> 
        <dependency> 
          <groupId>org.mybatis</groupId>  
          <artifactId>mybatis</artifactId>  
          <version>3.2.8</version> 
        </dependency>  
        <dependency> 
          <groupId>mysql</groupId>  
          <artifactId>mysql-connector-java</artifactId>  
          <version>5.1.34</version> 
        </dependency> 
      </dependencies> 
     </project>
  package com.mybatis.domain;
 
 
    public class User {
         private String name;
         private Integer age;
         
         public String getName() {
            return name;
         }
         
         public void setName(String name) {
         this.name = name;
         }
         
         public Integer getAge() {
         return age;
         }
         
         public void setAge(Integer age) {
            this.age = age;
         }
         
    }
package com.mybatis.mapper; 
import com.mybatis.domain.User; 
 
public interface UserMapper { 
    public User findById(String Id); 
}
    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--相当于UserMapper接口的实现 namespace必须是UserMapper类路径-->
    <mapper namespace="com.mybatis.mapper.UserMapper"> 
        <!-- findById必须和接口中的方法名一样 返回一个User--> 
        <select id="findById" parameterType="String"
        resultType="com.mybatis.domain.User"> 
        select * from user where id=#{id} 
        </select> 
    </mapper>
    <?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> 
        <!--数据源配置 -->
        <environments default="development"> 
            <environment id="development"> 
                <transactionManager type="jdbc" /> 
                <dataSource type="POOLED"> 
                    <property name="driver" value="com.mysql.jdbc.Driver" /> 
                    <property name="url" value="jdbc:mysql://localhost:3306/test" />
                    <property name="username" value="root" /> 
                    <property name="password" value="123456" /> 
                </dataSource>
            </environment> 
        </environments> <mappers> 
            <!--userMapper.xml装载进来 --> 
            <mapper resource="userMapper.xml" /> 
        </mappers> 
    </configuration>
package com.mybatis.test;
 
import com.mybatis.domain.User;
 
import com.mybatis.mapper.UserMapper;
 
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;
 
 
public class MyBatisTest {
    /** * MyBatis SqlSessionFactory * SqlSessionFactory????SqlSession????????????SqlSession??????????commit?rollback?close???? * @return */ private static SqlSessionFactory getSessionFactory() {
        SqlSessionFactory sessionFactory = null;
        String resource = "configuration.xml";
        try {
            sessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader(
                        resource));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sessionFactory;
    }
 
    public static void main(String[] args) {
        SqlSession sqlSession = getSessionFactory().openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = userMapper.findById("1");
        System.out.println(user.getName());
    }
}
 

数据库中插入条数据:
id=”1” name=”wn” age=”23”

 

java-mybaits-015-mybatis逆向工程最佳实践【基础mybatis-generator、tk.mybatis、mubatis-plus】

java-mybaits-015-mybatis逆向工程最佳实践【基础mybatis-generator、tk.mybatis、mubatis-plus】

一、概述

三款框架的功能对比

 

Mybatis-generator

通用Mapper

Mybatis-Plus

代码生成器

支持自动生成Model,Mapper,Mapper XML文件

生成方式不够灵活;

生成代码功能较为简单

支持自动生成Entity,Mapper,Mapper XML文件;

提供通用的Mapper模板,生成方式较灵活;

生成的Model文件包含注释能够很好地与数据库表完成映射

支持自动生成Entity,Mapper,Mapper XML,Service,Controller文件;

提供BaseMapper接口

CRUD操作

代码生成后每个Mapper有固定的CRUD方法;

在每个Mapper上分别扩展

提供通用Mapper接口;方便构造统一service

可以扩展通用接口

提供BaseMapper接口;

可以扩展通用接口

条件构造器

每个实体类自己的Example构造条件【对象方式】

提供通用Example【构建sql】

提供Wrapper进行复杂条件构造

乐观锁

 

支持

支持

主键策略

 

支持

支持

分页

 

 

支持

逻辑删除

 

 

支持

通用枚举

 

 

支持

攻击Sql阻断

 

 

支持

性能分析

 

 

支持

  通用Mapper是对Mybatis-generator的升级改造,解决了使用Mybatis-generator可能需要大量重构的问题,并且在这个基础上加入了一些新的功能。

  Mybatis-Plus可以看作是在另一个方向上对Mybatis的升级改造,不仅能够根据数据库表快速生成pojo实体类,还封装了大量CRUD方法,使用Wrapper解决了复杂条件构造等问题,更是根据开发中常见的问题给出了一系列解决方案。

  在拥有Maven和Spring boot的开发框架下,MBG、通用Mapper和MP都可以快速地完成安装,相比于MBG和通用Mapper仅需要执行插件就可以完成基本的开发工作,MP可能需要更多的开发工作量。

  最佳实践参看代码:https://github.com/bjlhx15/java_base_architecture.git

二、Mybatis-generator

  MyBatis Generator(MBG)是MyBatis MyBatis 和iBATIS的代码生成器。它为所有版本的MyBatis以及版本2.2.0之后的iBATIS版本生成代码。它将根据数据库表生成可用于访问表的文件。

  Mybatis-generator主要完成的工作是依据数据库表创建对应的model、dao、mapping文件,可以通过Maven插件或者mybatis-generator的jar包生成。

  这里介绍Maven插件使用方法:

    1、在pom.xml文件中加入mybatis-generator系列插件;

    2、创建generatorConfig.xml文件,在配置文件中指定数据库连接地址、生成类的存放地址、生成对应表的类名等信息;

    3、执行mybatis-generator插件,即可生成相应文件;

    4、此外,mybatis-generator自动生成了example类用于构造复杂的筛选条件

  Mybatis-generator使用较为简单,生成的DAO类及映射文件中包含基本的CRUD操作。

  需要注意的是,在一次项目中多次执行mybatis-generator,xml文件会追加,会覆盖原本的Model、DAO;可以使用如下方式

    

    1、每次清理要生成的xml

    2、自动生成的写入auto,

    3、个人扩展的使用上图方式

  可以参看上述github代码

三、通用Mapper【tk.mybatis】

官网:https://github.com/abel533/Mapper/wiki

  当数据库字段变化频繁时,使用MBG(mybatis-generator)会带来大量的重构工作,对此,通用Mapper给出的解决办法是:给予开发者一个具备丰富的单表方法并且容易扩展的通用的Mapper。

  通用Mapper是对单表的CRUD操作进行了较为详细的实现,使得开发人员可以随意的按照自己的需求选择通用的方法,同时允许开发人员便捷地对通用Mapper进行扩展。

1. 在pom.xml中添加插件配置

<!-- 命令:mvn mybatis-generator:generate -->
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.6</version>
                <configuration>
                    <!-- 配置实际调用地址-->
                    <configurationFile>src/main/resources/mybatis_generatorConfig/generatorConfig-base.xml
                    </configurationFile>
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>5.1.38</version>
                    </dependency>
                    <dependency>
                        <groupId>tk.mybatis</groupId>
                        <artifactId>mapper</artifactId>
                        <version>4.0.0</version>
                    </dependency>
                </dependencies>
            </plugin>
View Code

  可以看到,通用Mapper的代码生成实际上是使用了MGB,因此通用Mapper的代码生成器只是调用了MGB,然后在这个基础上加入了一些元素来方便开发。

2. 配置文件generatorConfig.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE generatorConfiguration PUBLIC
        "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
<generatorConfiguration>
    <!--导入属性配置,前面我们写的一个配置文件,你也可以直接使用mybatis的jdbc的配置文件 -->
    <properties resource="jdbc.properties"></properties>
    <!-- 数据库驱动,注意,这里必须要修改成你的数据库的驱动地址 -->
    <!--    如果 pom配置这里可以不写-->
    <!--    <classPathEntry  location=".m2/repository/mysql/mysql-connector-java/5.1.8/mysql-connector-java-5.1.8.jar"/>-->

    <context id="Mysql" targetRuntime="MyBatis3Simple" defaultModelType="flat">
        <property name="beginningDelimiter" value="`"/>
        <property name="endingDelimiter" value="`"/>
        <plugin type="tk.mybatis.mapper.generator.MapperPlugin">
            <property name="mappers" value="tk.mybatis.mapper.common.Mapper"/>
            <property name="caseSensitive" value="true"/>
        </plugin>

        <!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
        <jdbcConnection driverClass="${jdbc.driver}"
                        connectionURL="${jdbc.url}"
                        userId="${jdbc.username}" password="${jdbc.password}">
        </jdbcConnection>

<!--        <javaTypeResolver>-->
<!--            <property name="forceBigDecimals" value="false"/>-->
<!--        </javaTypeResolver>-->
        <!-- targetProject:生成PO类的位置 -->
        <javaModelGenerator targetPackage="com.github.bjlhx15.mybatis.springboot.base.model.auto"
                            targetProject="../tk-mybatis-springboot-base1/src/main/java">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false"/>
            <!-- 从数据库返回的值被清理前后的空格 -->
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>

        <!-- targetProject:mapper xml 映射文件生成的位置 -->
        <sqlMapGenerator targetPackage="autoxml"
                         targetProject="../tk-mybatis-springboot-base1/src/main/resources/mapper/">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false"/>
        </sqlMapGenerator>

        <!--targetPackage:mapper接口生成的位置 -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.github.bjlhx15.mybatis.springboot.base.repository.auto"
                             targetProject="../tk-mybatis-springboot-base1/src/main/java">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="false"/>
        </javaClientGenerator>

        <!-- 指定数据库表 -->
        <table tableName="accountbalance" domainObjectName="AccountBalance">
            <generatedKey column="id" sqlStatement="JDBC"/>
        </table>


    </context>
</generatorConfiguration>
View Code

  与MGB原有的配置文件相比,这里只是多了一个插件的配置,这个插件的作用是:配置生成的Mapper接口都会自动继承这个接口,也就是说,使用通用Mapper生成的mapper接口即使看上去空空如也,但已经具备了大量的对数据库的操作方法。此外,通用 Mapper 专用代码生成器生成的 Model 会在原有基础上增加 @Table,@Id,@Column 等注解,方便自动与数据库字段进行映射。

3. 在 pom.xml 这一级目录的命令行窗口执行 mvn mybatis-generator:generate或者直接在执行mvn插件即可。

4. 通用Mapper同样有Example的设计,与MGB不同的是,MDB会对每一个表生成对应的Example类,而通用Mapper提供了一个统一的Example类,这个类和 MBG 生成的相比,需要自己设置属性名,这个类还额外提供了更多的方法。

  通用Mapper可以看作是MGB的改进和扩展,一定程度上解决了使用MGB重构的问题。

  可以参看上述github代码

四、Mybatis-Plus

  官网地址:https://mp.baomidou.com/guide/generator.html

  (以下简称MP)是Mybatis的增强工具(MBG和通用Mapper可看成插件),在Mybatis的基础上增加了很多功能,简化开发,提高效率。

在Spring Boot中的引入:

1. 在maven中添加MP启动器

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.1.2</version>
</dependency>

2. 要使用代码生成器还需要添加模板引擎依赖

参看地址:AutoGenerator的使用参考 https://mybatis.plus/guide/generator.html 。

添加 模板引擎 依赖,MyBatis-Plus 支持 Velocity(默认)、Freemarker、Beetl,用户可以选择自己熟悉的模板引擎,如果都不满足您的要求,可以采用自定义模板引擎。

Velocity(默认):

<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.1</version>
</dependency>

Freemarker:

<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.29</version>
</dependency>

Beetl:

<dependency>
    <groupId>com.ibeetl</groupId>
    <artifactId>beetl</artifactId>
    <version>3.0.11.RELEASE</version>
</dependency>

注意!如果您选择了非默认引擎,需要在 AutoGenerator 中 设置模板引擎。

AutoGenerator generator = new AutoGenerator();

// set freemarker engine
generator.setTemplateEngine(new FreemarkerTemplateEngine());

// set beetl engine
generator.setTemplateEngine(new BeetlTemplateEngine());

// set custom engine (reference class is your custom engine class)
generator.setTemplateEngine(new CustomTemplateEngine());

// other config
...
View Code

3、代码的自动生成。AutoGenerator是MP的代码生成器,通过调用AutoGenerator,进行相应的模板、策略配置可以快速生成Entity、Mapper、Mapper XML、Service、Controller各个模块的代码。

4. MP将通用的CRUD操作封装进BaseMapper接口,而自动生成的Mapper接口便自动继承了BaseMapper接口。复杂的Sql操作,则可以使用QueryWrapper(LambdaQueryWrapper) 和 UpdateWrapper(LambdaUpdateWrapper)进行动态Sql拼接。

5、此外,MP还支持分页、逻辑删除、通用枚举、Sql注入等功能,在:https://mp.baomidou.com/guide/generator.html

  还有性能分析插件:https://mp.baomidou.com/guide/performance-analysis-plugin.html

与MBG不同,使用Mybatis-Plus自动生成代码需要编写代码,通过调用AutoAutoGenerator类实现代码生成,从这方面来说不如使用插件方便。但是它丰富的功能以及只是相对复杂的配置还是使它领先于MBG以及通用Mapper。

 

 

 

 

 

 

 

 

双方都

JavaEE--Mybatis 学习笔记(一)--Mybatis 简介

JavaEE--Mybatis 学习笔记(一)--Mybatis 简介

一、简介:

  • MyBatis 本是 apache 的一个开源项目 iBatis, 2010 年这个项目由 apache software foundation 迁移到了 google code,并且改名为 MyBatis 。2013 年 11 月迁移到 Github。
  • iBATIS 一词来源于 “internet” 和 “abatis” 的组合,是一个基于 Java 的持久层框架。iBATIS 提供的持久层框架包括 SQL Maps 和 Data Access Objects(DAO)
  • MyBatis 的前身就是 iBatis,iBatis 本是由 ClintonBegin 开发,后来捐给 Apache 基金会,成立了 iBatis 开源项目2010 5 月该项目由 Apahce 基金会迁移到了 GoogleCode,并且改名为 MyBatis。尽管如此,它的包结构仍然为 ibatis
  • 访问网站

        www.mybatis.org/

        https://github.com/mybatis

  • MyBatis 是一个数据持久层 (ORM) 框架。把实体类和 SQL 语句之间建立了映射关系,是一种半自动化的 ORM 实现。
  • 所有 sql 语句,全部定义在 xml(建议)中。也可以通过注解的方式在接口上实现。这些映射文件称之为 mapper。

二、MyBatis 的优点(与其他架构区别)

  • MyBatis 的优点:
      1. 基于 SQL 语法,简单易学。
      2. 能了解底层组装过程。
      3.   SQL 语句封装在配置文件中,便于统一管理与维护,降低了程序的耦合度。
      4. 程序调试方便。
  • 与传统 JDBC 的比较
      1. 减少了 61% 的代码量
      2. 最简单的持久化框架
      3. 架构级性能增强
      4. SQL 代码从程序代码中彻底分离,可重用
      5. 增强了项目中的分工
      6. 增强了移植性
  •   Hibernate 的对比
  • Mybatis 在 XML 文件中配置 SQL 语句,实现了 SQL 语句和代码的分离,给程序的维护带来了很大便利

 

MyBatis 和 Hibernate 比较

 MyBatis

Hibernate

是一个 SQL 语句映射的框架(工具) 主流的 ORM(对象关系映射)框架、提供了从 POJO 到数据库表的全套映射机制 注重 POJO/Map SQL 之间的映射关系。不会为程序员在运行期自动生成 SQL 会自动生成全套 SQL 语句。 自动化程度低、手工映射 SQL, 灵活程度高 因为自动化程度高、映射配置复杂,api 也相对复杂,灵活性低. 需要开发人员熟炼掌据 SQL 语句 开发人同不必关注 SQL 底层语句开发

 

 

 

 

 

 

 

 三、Mybatis 体系结构

1. 功能架构讲解:

我们把 Mybatis 的功能架构分为三层:
  • API 接口层:提供给外部使用的接口 API,开发人员通过这些本地 API 来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。
  • 数据处理层:负责具体的 SQL 查找、SQL 解析、SQL 执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。
  • 基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。
2. 框架架构讲解:
  • 加载配置:配置来源于两个地方,一处是配置文件,一处是 Java 代码的注解,将 SQL 的配置信息加载成为一个
    mybatis 结构
    个 MappedStatement 对象(包括了传入参数映射配置、执行的 SQL 语句、结果映射配置),存储在内存中。
  • SQL 解析:当 API 接口层接收到调用请求时,会接收到传入 SQL 的 ID 和传入对象(可以是 Map、JavaBean 或者基本数据类型),Mybatis 会根据 SQL 的 ID 找到对应的 MappedStatement,然后根据传入参数对象对 MappedStatement 进行解析,解析后可以得到最终要执行的 SQL 语句和参数。
  • SQL 执行:将最终得到的 SQL 和参数拿到数据库进行执行,得到操作数据库的结果。
  • 结果映射:将操作数据库的结果按照映射的配置进行转换,可以转换成 HashMap、JavaBean 或者基本数据类型,并将最终结果返回。

 四、Mybatis 工作原理

 

 

5. 配置文件与约束

其中 mapper.xml 为

1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE mapper 3  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 4  "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 5 <mapper> 6 7 </mapper>

mybatis.xml

1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 3 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 4 <configuration> 5 6 </configuration>

这些都可以在下载的 mybatis 文件夹中的 pdf 找到

6.MyBatis 基本要素

    1). 基础配置文件 mybatis.xml

  •  configuration.xml系统的核心配置文件,包含数据源和事务管理器等设置和属性信息,XML 文档结构如下

 

  • configuration配置
     properties可以配置在Java属性配置文件中
     settings修改MyBatis在运行时的行为方式,如是否需要缓存
     typeAliases 为Java类型命名一个短的名字
     typeHandlers类型处理器-系统默认已经为所有类型设置OK
     objectFactory对象工厂–创建Bean。
     plugins插件  - 拦截CRUD操作。
     environments环境 -配置数据源
     environment 环境变量
     transactionManager事务管理器 JDBC|JNDI|JTA
     dataSource数据源
     mappersl 映射器 XML文件|Mapper类|网络资源

     

  •  配置环境

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  3 "http://mybatis.org/dtd/mybatis-3-config.dtd">  4 <configuration>  5 <!-- 配置运行环境 Ctrl Shift / -->  6 <environments default="mysqlEM">  7 <environment id="mysqlEM">  8 <transactionManager type="JDBC" />  9 <dataSource type="POOLED"> 10 <!-- 使用的是数据库连接池 JDBC也是一种数据源 --> 11 <!-- driver url username password --> 12 <property name="driver" value="com.mysql.jdbc.Driver" /> 13 <!-- jdbc:mysql:/// 就是127.0.0.1:3306 --> 14 <property name="url" value="jdbc:mysql://127.0.0.1:3306/test17182" /> 15 <property name="username" value="root" /> 16 <property name="password" value="123456" /> 17 </dataSource> 18 </environment> 19 <environment id="testEM"> 20 <transactionManager type="JDBC" /> 21 <dataSource type="POOLED"> 22 <!-- 使用的是数据库连接池 JDBC也是一种数据源 --> 23 <!-- driver url username password --> 24 <property name="driver" value="com.mysql.jdbc.Driver" /> 25 <!-- jdbc:mysql:/// 就是127.0.0.1:3306 --> 26 <property name="url" value="jdbc:mysql://127.0.0.1:3306/test17182" /> 27 <property name="username" value="root" /> 28 <property name="password" value="123456" /> 29 </dataSource> 30 </environment> 31 </environments> 32 33 </configuration>

 

 

  • 基础配置文件 事务管理
  MyBatis有两种事务管理类型:
  JDBC- 这个类型直接全部使用JDBC的提交和回滚功能。它依靠使用连接的数据源来管理事务的作用域。
  MANAGED- 这个类型什么不做, 它从不提交 、 回滚和关闭连接 。 而是让窗口来管理事务的全部生命周期 。(比如说 Spring或者JAVAEE服务器)

 

  • 基础配置文件 数据源
    数据源类型有三种:UNPOOLED,POOLED,JNDI。

    UNPOOLED- 这个数据源实现只是在每次请求的时候简单的打开和关闭一个连接。虽然这有点慢,但作为一些不需要性能和立即响应的简单应用来说, 不失为一种好选择 。

    POOLED- 这个数据源缓存JDBC连接对象用于避免每次都要连接和生成连接实例而需要的验证时间。对于并发WEB应用,这种方式非常流行因为它有最快的响应时间。

    JNDI- 这个数据源实现是为了准备和Spring或应用服务一起使用,可以在外部也可以在内部配置这个数据源,然后在JNDI上下文中引用它。这个数据源配置只需要两上属性:

 

  • 基础配置文件 —SQL 映射文件
    SQL 映射文件:

              使用相对路径 (还有全路径等)

    <!-- 注册映射文件 mapper resource/url/class  package name=""-->
      <mappers>
          <mapper resource="com/ryanxu/dao/mapper.xml" />
      </mappers>

 

  • 一些别的要点

    <=1 至多一个 且按顺序

   必须要有俩 且有先后顺序

   >=0

    2).SQL 映射文件 mapper.xml

 

  • SQL 映射文件结构:(有关文件的增删改查结构将用代码来演示)
  cache-  配置给定命名空间的缓存。
  cache-ref–  从其他命名空间引用缓存配置。
  resultMap  –  最复杂,也是最有力量的元素,用来描述如何从数据库结果集中来加载对象。l
  sql–  可以重用的SQL块,也可以被其他语句引用。
  insert–  映射插入语句
  update–  映射更新语句
  delete–  映射删除语句
  select–  映射查询语句

 

  • 动态 SQL
    MyBatis 的一个强大的特性之一通常是它的动态 SQL 能力
    if  
    choose(when,otherwise)
    trim(where,set)
    foreach

7. 核心类的生命周期

  • SqlSessionFactoryBuilder 的生命周期:这个类可以被初始 、 使用和丢弃 , 如果你已经创建好了一个 SqlSessionFactory 后就不用再保留它。 因此 ,SqlSessionFactoryBuilder 的最好作用域是方法体内,比如说定义一个方法变量。你可以重复使用 SqlSessionFactoryBuilder 生成多个 SqlSessionFactory 实例, 但是最好不要强行保留 , 因为 XML 的解析资源要用来做其它更重要的事
  • SqlSession   每个线程都有自己的 SqlSession 实例,SqlSession 实例是不能被共享,也是不是线程安全的。因此最好使用 Request 作用域或者方法体作用域。不要使用类的静态变量来引用一个 SqlSession 实例,甚至不要使用类的一个实例变更来引用。如果你正在使用 WEB 框架,应该让 SqlSession 跟随 HTTP 请求的相似作用域。也就是说,在收到一个 HTTP 请求过后,打开 SqlSession,等返回一个回应以后,立马关掉这个 SqlSession。关闭 SqlSession 是非常重要的。你必须要确保 SqlSession finally 方法体中正常关闭。
  • SqlSession  的获取:

 

 1 import java.io.IOException;
 2 import java.io.InputStream;  3 import java.sql.Connection;  4 import java.sql.SQLException;  5  6 import org.apache.ibatis.io.Resources;  7 import org.apache.ibatis.session.SqlSession;  8 import org.apache.ibatis.session.SqlSessionFactory;  9 import org.apache.ibatis.session.SqlSessionFactoryBuilder; 10 11 public class SqlSessionUtil { 12 private static SqlSessionFactory ssf;// 底层对应的是Connection连接池 13 static { 14  InputStream in; 15 try { 16 in = Resources.getResourceAsStream("mybatis-config.xml");// 从classpath位置加载文件,可以使用相对路径如:cn/hncu/mybatis-config.xml 17 SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder(); 18 ssf=ssfb.build(in); 19 } catch (IOException e) { 20  e.printStackTrace(); 21  } 22  } 23 24 public static SqlSessionFactory getSsf() { 25 return ssf; 26  } 27 28 public static SqlSession getSqlSession() { 29 return ssf.openSession(); 30  } 31 32 public static void main(String[] args) throws SQLException { 33 //SqlSession是Connection的包装类 34 //每次获取的是不同的SqlSession对象,如果获取一个session对象且从中访问con,则就会到池中去拿一个连接。由于我们在配置文件中设置池大小只有5,因此只有前5个session对象能够顺利取出con对象,第6个session在获取con时会阻塞。 35 //一个session对象在获取con之后如果不使用,那么超过默认时间,它所持有的con连接会被收回池中。这样其它session对象又可以从池中获取 36 37 System.out.println("ssf:"+ssf); 38 //下面这段代码,在5个session获取连接之后会阻塞。过一段时间后,才继续执行6-10个session对象 39 for(int i=1;i<=10;i++){ 40 SqlSession ss=getSqlSession(); 41 System.out.println(i+":sqlSession:"+ss);//sqlSession不同 42 Connection con=ss.getConnection(); 43 System.out.println(i+":con:"+con);//Connection相同 44 ss.close();//session对象关闭之后,它所持有的con会还回池中,被下一个session重新持有 45  } 46  } 47 }

 

  • SqlSession 接口主要方法

  新增:

    int  insert(String statement, Object parameter) 

 

  修改:

    int  update(String statement, Object parameter) 

 

  删除:

    int  delete(String statement, Object parameter)   

 

  查询:

    List selectList(String statement, Object parameter)

关于mybatis 学习笔记:mybatis SQL注入问题mybatis $注入的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于java day55【 Mybatis 连接池与事务深入 、 Mybatis 的动态 SQL 语句、 Mybatis 多表查询之一对多 、 Mybatis 多表查询之多对多】、java 学习笔记--mybatis 三剑客(mybatis)、java-mybaits-015-mybatis逆向工程最佳实践【基础mybatis-generator、tk.mybatis、mubatis-plus】、JavaEE--Mybatis 学习笔记(一)--Mybatis 简介的相关信息,请在本站寻找。

本文标签: