MyBatis基础

MyBatis介绍

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

简单来说,MyBatis 是一款持久层框架,底层很好的封装了JDBC的一系列操作,使用XML或注解的方式配置,使接口和POJO建立映射。

MyBatis环境

基于Maven项目,使用Maven坐标的方式。前往Maven仓库,可以找到你需要的大多数的资源。

当然如果你是传统的web项目使用MyBatis,需要创建并配置MyBatis.xml文件(该文件主要是数据库的dataSource数据源信息),并且在MyBatis.xml文件中为每一个xxxMapper.xml文件配置<Mapping>标签让Mybatis知道如何寻找。

MyBatis使用步骤

下面的示范,基于传统的web项目举例。

  1. 引入Maven坐标
  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>
    <!--环境配置,连接的数据库,这里使用的是MySQL-->
    <environments default="mysql">
        <environment id="mysql">
            <!--指定事务管理的类型,这里简单使用Java的JDBC的提交和回滚设置-->
            <transactionManager type="JDBC"></transactionManager>
            <!--dataSource 指连接源配置,POOLED是JDBC连接对象的数据源连接池的实现-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"></property>
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/test"></property>
                <property name="username" value="root"></property>
                <property name="password" value="root"></property>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--这是告诉Mybatis区哪找持久化类的映射文件,对于在src下的文件直接写文件名,
            如果在某包下,则要写明路径,如:com/mybatistest/config/User.xml-->
        <mapper resource="mapper/userMapper.xml"></mapper>
    </mappers>
</configuration>
  1. 创建实体类
public class User {
	private int id;
	private String name;
	private int age;
    //get/set方法省略
}

  1. 创建对应的xxxMapper接口
public interface UserMapper {
	public User getUser(int id);
}

  1. 创建sql映射文件(xxxMapper.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.darian.mapper.UserMapper">
	<select id="getUser" parameterType="int" resultType="com.darian.entity.User">
		SELECT * FROM users where id =#{id}
	</select>
</mapper>

  1. 检查MyBatis配置文件中是否配置了加载文件描述标签<mappers>,一个Mapper.xml一个<mapper>标签
<mappers>
	<mapper resource="mapper/userMapper.xml" />
</mappers>

  1. 自己测试(或Main方法测试)
public class Test {
	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.darian.mapper.UserMapper.getUser";
		User user = openSession.selectOne(sql, 1);
		System.out.println(user.toString());
	}
}

MyBatis之SQL注入

MyBatis的SQL注入,核心就是Mybatis在以:拼接核心参数的方式生成的SQL进行攻击。
比如一条传统的SQL语句是查询username,而有人通过sql注入将username=的值填写' OR 1=1 --的方式,即:username=' OR 1=1 --那么SQL就被注入攻击了。

因为–表示SQL注释,因此后面语句忽略;
因为1=1恒成立,因此 username=’’ OR 1=1 永恒成立。

解决SQL注入

在传统项目解决SQL注入问题:
采用?号占位符方式+API对象PreparedStatement,使得SQL预编译。核心示范步骤:

String sql = "SELECT name,pwd FROM user_table WHERE name=? AND pwd=?";

PreparedStatement st = con.prepareStatement(sql);
		st.setString(1, name);
		st.setString(2, pwd);

Mybatis中动态SQL中的#{}与${}区别

如果你不想知道其内部的思想,你只需要知道:优先使用 #{}。因为 ${} 会导致 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注入的问题。

MyBatis注解

MyBatis的API提供了注解方式,使得我们不用创建Mappe.xml文件,得已在xxxMapper接口中的方法上使用注解和Mapper.xml文件的方式达到一样的效果,但是我并不推荐,首先sql的复杂和长度,其次是sql的统一管理在xml文件相比更加的清晰。

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

MyBatis 逆向工程,Generator

关于Generator,有非常多的方式,可以上网百度,适合自己的一种。

MyBatis的其他特性和玩法

MyBatis中文网,推荐阅读文档来了解框架是比较好的方式之一,关于Mybatis的相关问题都可以在官网找到答复。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值