Mybatis

Posted 蜗牛丶sky

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis相关的知识,希望对你有一定的参考价值。

一、MyBatis快速入门

1.1 MyBatis介绍

  MyBatis是支持普通SQL查询存储过程高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数库中的记录。

  JDBC-->MyBatis-->Hibernate


1.2 MyBatis与Hibernate有何区别

  1)Hibernate是通过对象得到SQL语句

     Mybatis是通过SQL语句得到对象

  2)Hibernate比较重量级,上手难度更高

    Mybatis轻量级,上手简单,可以优化SQL

1.3 Mybatis实现原理:

  1)使用java 解析xml技术解析配置文件 mybatis.xml

  2)获取JDBC值,进行反射创建数据源

  3)创建会话工厂,获取到某个会话工厂的连接

  4)通过namespace定位到具体的Mapper地址,通过反射实例该Mapper接口

  5)再通过类名到具体的Mapper.xml,找到具体的SQL节点

二、MyBatis环境搭建

2.1添加maven坐标

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.4</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.21</version>
        </dependency>
    </dependencies>

2.2建表

2.3添加mybatis配置文件

<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEconfigurationPUBLIC"-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environmentsdefault="development">
        <environmentid="development">
    <!-- 数据库连接 -->
            <transactionManagertype="JDBC"/>
            <dataSourcetype="POOLED">
                <propertyname="driver"value="com.mysql.jdbc.Driver"/>
                <propertyname="url"value="jdbc:mysql://localhost:3306/test"/>
                <propertyname="username"value="root"/>
                <propertyname="password"value="root"/>
            </dataSource>
        </environment>
    </environments>
</configuration>

    

2.4定义表的实体类

package com.entity;
public class User {
    private int id;
    private String name;
    private int age;
//get,set方法
}

2.5定义Mapper接口

package com.stu.mapper;
import com.stu.entity.User;
public interface UserMapper {
    public User getUser(intid);
}

2.6定义操作users表的sql映射文件userMapper.xml

<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEmapperPUBLIC"-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mappernamespace="com.itmayiedu.mapper.UserMapper">
    <selectid="getUser"parameterType="int"resultType="com.itmayiedu.entity.User">
        SELECT *
        FROM users where id =#{id}
    </select>
</mapper>

2.7mybatis的配置文件mybatis.xml添加加载配置

<!-- 定义mybatis配置要加载的mapper文件 -->
<mappers>
<mapperresource="mapper/userMapper.xml"/>
</mappers>

2.8MyBatis测试

importjava.io.File;
import java.io.IOException;
import java.io.Reader;
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 com.stu.entity.User;
public class TestMybatis {
    public static void main(String[] args) throws IOException {
        String resource = "mybatis.xml";
        // 读取配置文件
        Reader reader = Resources.getResourceAsReader(resource);
        // 获取会话工厂
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        SqlSession openSession = sqlSessionFactory.openSession();
        // 查询
        String sql = "com.stu.mapper.UserMapper.getUser";
        // 调用api查询
        User user = openSession.selectOne(sql, 1);
        System.out.println(user.toString());
    }
}

2.9增加案例(增)

1)UserMapper接口添加addUser(User user)方法
2)userMapper.xml添加
<insertid="addUser"parameterType="com.stu.entity.User">
    INSERT INTO users(NAME, age) VALUES(#{name}, #{age});
</insert>

  3)测试代码

static public void add() throws IOException{
        String resource = "mybatis.xml";
        // 读取配置文件
        Reader reader = Resources.getResourceAsReader(resource);
        // 获取会话工厂
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        SqlSession openSession = sqlSessionFactory.openSession();
        // 查询
        String sql = "com.stu.mapper.UserMapper.addUser";
        // 调用api查询
        User userPa = new User();
        userPa.setAge(19);
        userPa.setName("张三");
        int reuslt = openSession.insert(sql, userPa);
        System.out.println(reuslt);
    }

2.10 删除(删)

  1)mapper接口添加delete(int id)方法

  2)mapper.xml文件添加

<deleteid="delUser"parameterType="int">
      delete from users where id=#{id}
</delete>

  3)测试代码

    static public void delUser() throws IOException{
        String resource = "mybatis.xml";
        // 读取配置文件
        Reader reader = Resources.getResourceAsReader(resource);
        // 获取会话工厂
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        SqlSession openSession = sqlSessionFactory.openSession();
        // 查询
        String sql = "com.stu.mapper.UserMapper.delUser";
        int reuslt = openSession.delete(sql,1);
        System.out.println(reuslt);
    }

2.11 修改案例(改)

  1)mapper接口添加update(User user)方法

  2)mapper.xml添加

<insertid="addUser" resultType="int" parameterType="com.stu.entity.User">
    update users set username=#{username}, age=#{age} where id=#{id}
</insert>

  3)测试代码

static public void update() throws IOException{
        String resource = "mybatis.xml";
        // 读取配置文件
        Reader reader = Resources.getResourceAsReader(resource);
        // 获取会话工厂
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        SqlSession openSession = sqlSessionFactory.openSession();
        // 查询
        String sql = "com.stu.mapper.UserMapper.addUser";
        // 调用api查询
        User userPa = new User();
        userPa.setAge(19);
        userPa.setName("张三");
        int reuslt = openSession.insert(sql, userPa);
        System.out.println(reuslt);
    }

三、SQL语句注入

3.1什么是SQL注入

  当SQL语句为:select * from user where name=‘+name+‘ and pwd=‘+pwd+‘,当我们传入的name为(‘  OR 1=1 --)时,最终的语句为 select * from user where name=‘‘  OR 1=1 --‘ and pwd=‘+pwd+‘ 。这样语句都将返回所有数据,这就是SQL注入。

  在MyBatis中使用$符号时,由于也是拼接语句的,也会造成SQL注入。

3.2如何解决SQL注入

  将SQL语句先编译,后执行。  

String sql = "SELECT id,username FROM user WHERE username=? AND password=?";
Class.forName("com.mysql.jdbc.Driver");
        Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
        PreparedStatement stat = con.prepareStatement(sql);
        stat.setString(1, username);
        stat.setString(2, password);
        System.out.println(stat.toString());
        ResultSet rs = stat.executeQuery();
        while (rs.next()) {
            String id = rs.getString(1);
            String name = rs.getString(2);
            System.out.println("id:" + id + "---name:" + name);
        }

  这样即使传入的参数含有非法字符,也能将其作为一个参数,而非SQL指令来执行。

3.3MyBatis的$和#区别

  动态sql mybatis 的主要特性之一,在 mapper 中定义的参数传到 xml 中之后,在查询之前 mybatis 会对其进行动态解析。mybatis 为我们提供了两种支持动态 sql 的语法:#{} 以及 ${}

 

  #{} 和 ${} 在预编译中的处理是不一样的。#{} 在预处理时,会把参数部分用一个占位符 ? 代替,变成如下的 sql 语句:select * from user where name = ?;而 ${} 则只是简单的字符串替换,在动态解析阶段,该 sql 语句会被解析成select * from user where name = ‘zhangsan‘。以上,#{} 的参数替换是发生在 DBMS 中,而 ${} 则发生在动态解析过程中。

  那么,在使用过程中我们应该使用哪种方式呢?答案是,优先使用 #{}。因为 ${} 会导致 sql 注入的问题。

3.4MyBatis的注解使用

  Mybatis提供了增删改查注解、@select @delete @update

public interface UserTestMapper {
    @Select("select * from users where id = ${id};")
    public User getUser(@Param("id") String id);
}

  mybatis.xml配置文件中,添加<mapper class="com.stu.mapper.UserTestMapper" />。注意同一个Mapper接口不能同时添加注解版和非注解版。

<deleteid="delUser"parameterType="int">

      delete from users where id=#{id}

</delete>

以上是关于Mybatis的主要内容,如果未能解决你的问题,请参考以下文章

SSM-MyBatis-05:Mybatis中别名,sql片段和模糊查询加getMapper

mybatis动态sql片段与分页,排序,传参的使用

MyBatis动态SQL标签用法

MYBATIS05_ifwherechoosewhentrimsetforEach标签sql片段

mybatis动态sql之利用sql标签抽取可重用的sql片段

[mybatis]动态sql_sql_抽取可重用的sql片段