[Learning] 017 Mybatis framework

I. Objectives

Mybatis Introduction

Mybatis CRUD

SQL injection problems introduced

Mybatis xml and achieve comment

Mybatis page

Two, Mybatis Quick Start

Introduction 2.1 Mybatis

MyBatis supports common SQL queries , stored procedures and advanced mapping class persistence framework. MyBatis eliminates almost all of the code and to manually set parameters JDBC package and retrieve the result set. MyBatis can use simple XML or Annotations for configuration and map primitives, Map interfaces and Java POJO (Plain Old Java Objects, ordinary Java objects) is mapped to the number of records in the database. JDBC -> MyBatis

2.2 Mybatis environment to build

Add Maven 2.2.1 dependent

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

Table 2.2.2 build

CREATE TABLE users(id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20), age INT);
INSERT INTO users(name, age) VALUES('Tom', 12);
INSERT INTO users(name, age) VALUES('Jack', 11);

2.2.3 Adding mybatis profile

<?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:23306/mydatabase" />
                <property name="username" value="root" />
                <property name="password" value="master" />
            </dataSource>
        </environment>
    </environments>
</configuration>

2.2.4 entity class definition table

package com.hongmoshui.mybatis.entity;

public class User
{
    private int id;

    private String name;

    private int age;

    public int getId()
    {
        return id;
    }

    public void setId(int id)
    {
        this.id = id;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public int getAge()
    {
        return age;
    }

    public void setAge(int age)
    {
        this.age = age;
    }

}

2.2.5 Interface definitions userMapper

package com.hongmoshui.mybatis.mapper;

import com.hongmoshui.mybatis.entity.User;

public interface UserMapper
{
    public User getUser(int id);

    public Integer addUser(String name, int age);

    public Integer delUser(int id);
}

2.2.6 users define the operation table mapping file userMapper.xml sql

<?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">
<mapper namespace="com.hongmoshui.mybatis.mapper.UserMapper">
    <select id="getUser" parameterType="int"
        resultType="com.hongmoshui.mybatis.entity.User">
        SELECT * FROM users where id =#{id}
    </select>
    <insert id="addUser"
        parameterType="com.hongmoshui.mybatis.entity.User">
        INSERT INTO users(name, age) VALUES(#{name}, #{age});
    </insert>
    <delete id="delUser" parameterType="int">
        delete from users where id=#{id}
    </delete>

</mapper>

2.2.7mybatis.xml file to load the configuration file

    <mappers>
        <mapper resource="mapper/userMapper.xml" />
    </mappers>

2.2.8mybatis test methods

package com.hongmoshui.mybatis;

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.hongmoshui.mybatis.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();
        addUser(openSession);
        delUser(openSession);
        getUser(openSession);
    }

    private static void getUser(SqlSession openSession)
    {
        // 查询
        String sql = "com.hongmoshui.mybatis.mapper.UserMapper.getUser";
        // 参数id
        int id = 1;
        // 调用api查询
        User user = openSession.selectOne(sql, id);
        System.out.println(user.toString());
    }

    private static void addUser(SqlSession openSession)
    {
        // 新增SQL
        String sql = "com.hongmoshui.mybatis.mapper.UserMapper.addUser";
        // 调用api查询
        User user = new User();
        user.setAge(19);
        user.setName("hongmoshui");
        int reuslt = openSession.insert(sql, user);
        openSession.commit();
        System.out.println(reuslt);

    }

    private static void delUser(SqlSession openSession)
    {
        // 删除SQL
        String sql = "com.hongmoshui.mybatis.mapper.UserMapper.delUser";
        // 调用api查询
        int id = 2;
        int reuslt = openSession.insert(sql, id);
        openSession.commit();
        System.out.println(reuslt);

    }
}

Three, sql injection case

3.1 + Create a table of test data

create table user_table(  
    id      int Primary key,  
    username    varchar(30),  
    password    varchar(30)  
);  
insert into user_table values(1,'hongmoshui-1','12345');  
insert into user_table values(2,'hongmoshui-2','12345');  

3.2 jdbc loaded

package com.hongmoshui.mybatis;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class TestSQL
{
    public static void main(String[] args) throws ClassNotFoundException, SQLException
    {
        String username = "hongmoshui-1";
        String password = "12345";
        String sql = "SELECT id,username FROM user_table WHERE " + "username='" + username + "'AND " + "password='" + password + "'";
        Class.forName("com.mysql.jdbc.Driver");
        Connection con = DriverManager.getConnection("jdbc:mysql://localhost:23306/mydatabase", "root", "master");
        PreparedStatement stat = con.prepareStatement(sql);
        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);
        }
    }
    
}

3.3 Set the value for the username

username='  OR 1=1 -- 或者username or 1='1

Because - SQL comments indicate, therefore behind the statement is ignored;

Since the establishment of the constant 1 = 1, so username = '' OR 1 = 1 constant established, so SQL statement is equivalent to:

SELECT id,username FROM user_table

3.4sql injection solution

Step One: Compile sql 

The second step: the implementation of sql

Advantages: can be precompiled sql statement

package com.hongmoshui.mybatis;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class TestSQL
{
    public static void main(String[] args) throws ClassNotFoundException, SQLException
    {
        Class.forName("com.mysql.jdbc.Driver");
        Connection con = DriverManager.getConnection("jdbc:mysql://localhost:23306/mydatabase", "root", "master");
        // 无注入情况
        String username1 = "hongmoshui-1";
        String password1 = "12345";
        String sql1 = "SELECT id,username FROM user_table WHERE " + "username='" + username1 + "'AND " + "password='" + password1 + "'";
        selectNoInjection(con, username1, password1, sql1);
        // 注入,但是有预编译
        String username2 = "username='  OR 1=1 -- ";
        String password2 = "12345";
        String sql2 = "SELECT id,username FROM user_table WHERE username=? AND password=?";
        selectInjection(con, username2, password2, sql2);

    }

    private static void selectInjection(Connection con, String username, String password, String sql) throws SQLException
    {
        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);
        }
    }

    private static void selectNoInjection(Connection con, String username, String password, String sql) throws ClassNotFoundException, SQLException
    {
        PreparedStatement stat = con.prepareStatement(sql);
        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);
        }
    }

}

And $ 3.4 mybatis difference in #

Dynamic sql is one of the main characteristics mybatis, after which the parameters defined in the mapper xml passed in, before the query mybatis will be dynamic resolution. mybatis provides two support our dynamic sql syntax: # {} and $ {}.

In the following statement, if the value of username zhangsan, is no different in two ways:

select * from user where name = #{name};
select * from user where name = ${name};

The results are then parsed

select  *  from  user  where name =  ' zhangsan ' ;

But $ # {} and {} is processed in the pre-compiler is not the same. ? # {} While pretreatment parameters will partially replaced by a placeholder, into the sql statement as follows:

select * from user where name = ?;

And $ {} string is simply replaced, the dynamic resolution phase, the sql statement is parsed into

select  *  from  user  where name =  ' zhangsan ' ;

Above, parameter # {} replacement occurs in the DBMS, and {} $ occurs in the dynamic resolution process.

Then, in the course of which way should we use it?

The answer is that the priority use # {}. {Because} $ sql injection can cause problems. See the examples below:

 select * from ${tableName} where name = #{name}

In this example, if the table is named

 user; delete user; -- 

  After parsing the dynamic sql follows:

select * from user; delete user; -- where name = ?;

  - After the statement is commented out, and the original user query statements into a query statement to delete all user information + user table, the database will cause significant damage, most likely resulting in server downtime.

But when the table name passed in parameter, you can only use $ {}, the specific reasons may be their own guess, to verify. It also reminds us to be careful in this usage problems sql injection.

3.4.1 Creating UserTable

package com.hongmoshui.mybatis;

public class UserTable
{
    private int id;

    private String userName;

    private String passWord;

    public int getId()
    {
        return id;
    }

    public void setId(int id)
    {
        this.id = id;
    }

    public String getUserName()
    {
        return userName;
    }

    public void setUserName(String userName)
    {
        this.userName = userName;
    }

    public String getPassWord()
    {
        return passWord;
    }

    public void setPassWord(String passWord)
    {
        this.passWord = passWord;
    }

}

3.4.2 Creating UserTableMapper

package com.hongmoshui.mybatis.mapper;

import com.hongmoshui.mybatis.UserTable;

public interface UserTableMapper
{
    public UserTable login(UserTable userTable);
}

3.4.3userTableMapper.xml

<?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">
<mapper namespace="com.hongmoshui.mybatis.mapper.UserTableMapper">
    <select id="login"
        parameterType="com.hongmoshui.mybatis.UserTable"
        resultType="com.hongmoshui.mybatis.UserTable">
        SELECT id ,username as userName FROM user_table WHERE
        username=${userName} AND password=${passWord}
    </select>

</mapper>

3.4.4 mybatis.xml file to load the configuration file

    <mappers>
        <!-- <mapper resource="mapper/userMapper.xml" /> -->
        <mapper resource="mapper/userTableMapper.xml" />
    </mappers>

3.4.5 Test SQL Injection

package com.hongmoshui.mybatis;

import java.io.IOException;
import java.io.Reader;
import java.sql.SQLException;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class TestLoginMybatis3
{

    public static void main(String[] args) throws IOException, SQLException, ClassNotFoundException
    {

        Resource String = "mybatis.xml" ;
         // reads the configuration file 
        Reader Reader = Resources.getResourceAsReader (Resource);
         // get the session factory 
        SqlSessionFactory SqlSessionFactory = new new the SqlSessionFactoryBuilder () Build (Reader);. 
        SqlSession openSession = sqlSessionFactory.openSession ( );
         // query 
        String SQL = "com.hongmoshui.mybatis.mapper.UserTableMapper.login" ;
         // call api query 
        userTable userTable = new new userTable (); 
        userTable.setUserName ( " '' OR 1 = 1 -" ) ;
        userTable.setPassWord("12345");
        List<UserTable> listUserTable = openSession.selectList(sql, userTable);
        for (UserTable ub : listUserTable)
        {
            System.out.println(ub.getUserName());
        }
    }
}

3.4.6 summary

Priority use#{}. Because $ {} sql injection causes problems of

A, Mybatis use annotations

Mybatis provides CRUD annotation, @ select @delete @update

4.1 Establish comment Mapper

package com.hongmoshui.mybatis.mapper;

import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import com.hongmoshui.mybatis.UserTable;

public interface UserTestMapper {
    @Select("select * from user_table where id = ${id};")
    public UserTable getUser(@Param("id") int id);
}

4.2 added mybatis.xml

    <mappers>
        <!-- <mapper resource="mapper/userMapper.xml" />
        <mapper resource="mapper/userTableMapper.xml" /> -->
        <mapper class="com.hongmoshui.mybatis.mapper.UserTestMapper" />
    </mappers>

4.3 Test run

package com.hongmoshui.mybatis;
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.hongmoshui.mybatis.mapper.UserTestMapper;

public class TestMybatis3
{
    public static void main(String[] args) throws IOException
    {
        String resource = "mybatis.xml";
        // reads the configuration file 
        Reader Reader = Resources.getResourceAsReader (Resource);
         // get the session factory 
        SqlSessionFactory SqlSessionFactory = new new the SqlSessionFactoryBuilder () Build (Reader);. 
        SqlSession openSession = sqlSessionFactory.openSession ();
         // call api query 
        UserTestMapper userTestMapper openSession.getMapper = (UserTestMapper. class ); 
        System.out.println (userTestMapper.getUser ( 2 )); 
    } 
}

 

Guess you like

Origin www.cnblogs.com/hongmoshui/p/10988838.html
017