一、目标

Mybatis介绍

Mybatis增删改查

SQL注入问题介绍

Mybatis xml与注解实现

Mybatis分页

二、Mybatis快速入门

2.1 Mybatis介绍

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

2.2 Mybatis环境搭建

2.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建表

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添加mybatis配置文件

<?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定义表的实体类

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定义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表的sql映射文件userMapper.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.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文件中加载配置文件

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

2.2.8mybatis测试方法

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); }
}

三、sql注入案例

3.1创建表+测试数据

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

3.2 jdbc进行加载

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将username的值设置为

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

因为--表示SQL注释,因此后面语句忽略;

因为1=1恒成立,因此 username='' OR 1=1  恒成立,因此SQL语句等同于:

SELECT id,username FROM user_table

3.4sql注入解决办法

第一步:编译sql

第二步:执行sql

优点:能预编译sql语句

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);
}
} }

3.4 mybatis中#与$区别

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

在下面的语句中,如果 username 的值为 zhangsan,则两种方式无任何区别:

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

其解析之后的结果均为

select * from user where name = 'zhangsan';

但是 #{} 和 ${} 在预编译中的处理是不一样的。#{} 在预处理时,会把参数部分用一个占位符 ? 代替,变成如下的 sql 语句:

select * from user where name = ?;

而 ${} 则只是简单的字符串替换,在动态解析阶段,该 sql 语句会被解析成

select * from user where name = 'zhangsan';

以上,#{} 的参数替换是发生在 DBMS 中,而 ${} 则发生在动态解析过程中。

那么,在使用过程中我们应该使用哪种方式呢?

答案是,优先使用 #{}。因为 ${} 会导致 sql 注入的问题。看下面的例子:

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

在这个例子中,如果表名为

user; delete user; --

  则动态解析之后 sql 如下:

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

  --之后的语句被注释掉,而原本查询用户的语句变成了查询所有用户信息+删除用户表的语句,会对数据库造成重大损伤,极大可能导致服务器宕机。

但是表名用参数传递进来的时候,只能使用 ${} ,具体原因可以自己做个猜测,去验证。这也提醒我们在这种用法中要小心sql注入的问题。

3.4.1创建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创建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文件中加载配置文件

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

3.4.5 测试SQL注入

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
{ String resource = "mybatis.xml";
// 读取配置文件
Reader reader = Resources.getResourceAsReader(resource);
// 获取会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession openSession = sqlSessionFactory.openSession();
// 查询
String sql = "com.hongmoshui.mybatis.mapper.UserTableMapper.login";
// 调用api查询
UserTable userTable = 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 总结

优先使用 #{}。因为 ${} 会导致 sql 注入的问题

一、Mybatis 注解使用

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

4.1 建立注解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 加入mybatis.xml

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

4.3 运行测试

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";
// 读取配置文件
Reader reader = Resources.getResourceAsReader(resource);
// 获取会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession openSession = sqlSessionFactory.openSession();
// 调用api查询
UserTestMapper userTestMapper = openSession.getMapper(UserTestMapper.class);
System.out.println(userTestMapper.getUser(2));
}
}

【学习】017 Mybatis框架的更多相关文章

  1. Mybatis框架学习总结-Mybatis框架搭建和使用

    Mybatis介绍 Mybatis是一个支持普通SQL查询,存储过程,和高级映射的优秀持久层框架.Mybatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.Mybatis可以使 ...

  2. 框架学习系列 mybatis mapper映射文件之输出映射

    1: mapper映射文件输出映射(输入类型) 2:resultType的使用 3:resultMap的使用 3:总结&下节预告 本文是<凯哥陪你学系列-框架学习之mybatis框架学习 ...

  3. Mybatis框架-update节点元素的使用

    今天我们学习一下mybatis框架中的update节点元素的使用 需求:修改用户表中的一条数据记录,修改编号为21的用户的密码 UserMapper.xml UserMapper.java 编写测试方 ...

  4. Spring MVC 学习总结(十)——Spring+Spring MVC+MyBatis框架集成(IntelliJ IDEA SSM集成)

    与SSH(Struts/Spring/Hibernate/)一样,Spring+SpringMVC+MyBatis也有一个简称SSM,Spring实现业务对象管理,Spring MVC负责请求的转发和 ...

  5. 【MyBatis学习01】宏观上把握MyBatis框架

    今天开始学习mybatis框架,博客主要记录学习过程中的一些总结,如有错误之处,欢迎留言指正~先用mybatis的鸟鸟来镇个楼,咳咳~~ mybatis框架是一个持久层框架,是Apache下的顶级项目 ...

  6. (转)MyBatis框架的学习(七)——MyBatis逆向工程自动生成代码

    http://blog.csdn.net/yerenyuan_pku/article/details/71909325 什么是逆向工程 MyBatis的一个主要的特点就是需要程序员自己编写sql,那么 ...

  7. (转)MyBatis框架的学习(六)——MyBatis整合Spring

    http://blog.csdn.net/yerenyuan_pku/article/details/71904315 本文将手把手教你如何使用MyBatis整合Spring,这儿,我本人使用的MyB ...

  8. (转)MyBatis框架的学习(五)——一对一关联映射和一对多关联映射

    http://blog.csdn.net/yerenyuan_pku/article/details/71894172 在实际开发中我们不可能只是对单表进行操作,必然要操作多表,本文就来讲解多表操作中 ...

  9. (转)MyBatis框架的学习(四)——Mapper.xml文件中的输入和输出映射以及动态sql

    http://blog.csdn.net/yerenyuan_pku/article/details/71893689 前面对MyBatis框架的学习中,我们对Mapper.xml映射文件多少有些了解 ...

随机推荐

  1. centos下面配置key登录

    centos下需要配置使用key登录,并且要禁止root登录 下面的操作都是用root来设置的 1.添加新用户 例如用户名leisiyuan useradd leisiyuan 2.设置密码 pass ...

  2. tensorflow源码分析——CTC

    CTC是2006年的论文Connectionist Temporal Classification: Labelling Unsegmented Sequence Data with Recurren ...

  3. python调用c++/c 共享库,开发板上编译的一些坑!

    1.对于python,ctypes只能load动态库,但现在我的对象是一个静态库,而且我没有源代码,静态库在编译过程中没有加--fPIC参数,所以我也没办法将其编译为动态库,有没有什么方法在pytho ...

  4. DB2创建视图并授权给其他用户

    创建视图并授权给其他用户 可以在操作系统界面.或者DB2交互界面下进行数据库操作 查看数据库节点[db2inst1@ELONEHR-DB ~]$ db2 list db directory Syste ...

  5. 安装ubuntu双系统

    今天在win7下安装ubuntu14.1双系统,别折磨了一个下午.主要是开机系统引导问题. 引导程序是位于硬盘最前面的一段程序,由于扇区大部分是引导程序,故也成引导扇区.此外包含有硬盘的分区信息,共6 ...

  6. Spring Cloud的几个组件

    在微服务架构中,需要几个基础的服务治理组件,包括服务注册与发现.服务消费.负载均衡.断路器.智能路由.配置管理等,由这几个基础组件相互协作,共同组建了一个简单的微服务系统.一个简答的微服务系统如下图: ...

  7. C++拷贝构造函数心得

    C++Primer作者提到拷贝构造函数调用的三种时机: 1. 当用一个类对象去初始化另外一个类对象(类似于 AClass aInstance = bInstance),这里不是调用赋值构造函数(也叫赋 ...

  8. 3D聚类

    1 3D聚类和普通的二维聚类实质一样,只不过维数太高了,用三维图来表示了. 下面将官网的改成只生成一个图了 #!/usr/bin/python # -*- coding:utf-8 -*- print ...

  9. 32 位bitmap 内存存储 顺序 bgra 前3位 与23位一致。 都是 bgr 呵呵 与rgb 相反

    32 位bitmap     内存存储 顺序   bgra       前3位 与23位一致.   都是 bgr  呵呵 与rgb 相反

  10. IIS安全狗问题

    1.没有安装以前网站运行正常,安装IIS全狗以后,ajaxpro2出现,找不到任何问题,卸载安全狗以后正常. 2.很久以前遇到的一个问题,有一款NET的cms系统,也是安装了安全狗以后不正常,忘记了c ...