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
<?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.stu.mapper.UserMapper"> <select id="getUser" parameterType="int" resultType="com.stu.entity.User"> SELECT * FROM users where id =#{id} </select> </mapper>
2.7mybatis的配置文件mybatis.xml添加加载配置
<!-- 定义mybatis配置要加载的mapper文件 --> <mappers> <mapper resource="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添加
<insert id="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文件添加
<delete id="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添加
<insert id="updateUser" 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> |