1、建库建表
CREATE DATABASE `mybatis-example`;USE `mybatis-example`;CREATE TABLE `t_emp`(emp_id INT AUTO_INCREMENT,emp_name CHAR(100),emp_salary DOUBLE(10,5),PRIMARY KEY(emp_id) );INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("tom",200.33); INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("jerry",666.66); INSERT INTO `t_emp`(emp_name,emp_salary) VALUES("andy",777.77);
2、pom.xml
<dependencies><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId></dependency><!-- MySQL驱动 mybatis底层依赖jdbc驱动实现,本次不需要导入连接池,mybatis自带! --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--junit5测试--><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies>
3、Employee.java(pojo)
package com.atguigu.mybatis.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor public class Employee {private Integer empId;private String empName;private Double empSalary; }
4、EmpMapper.java
package com.atguigu.mybatis.mapper; import com.atguigu.mybatis.pojo.Employee; import java.util.List; public interface EmpMapper {List<Employee> getEmployeeList();Employee getEmployeeById(Integer empId);Employee getEmployeeById2(Integer empId);List<Employee> getEmployeeListByName(String name);List<Employee> getEmployeeListByName2(String name);List<Employee> getEmployeeListByName3(String name);List<Employee> getEmployeeList2(String tableName);}
5、mybatis-config.xml(mybatis的总配置文件)
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration><!-- environments表示配置Mybatis的开发环境,可以配置多个环境,在众多具体环境中,使用default属性指定实际运行时使用的环境。default属性的取值是environment标签的id属性的值。 --><environments default="development"><!-- environment表示配置Mybatis的一个具体的环境 --><environment id="development"><!-- Mybatis的内置的事务管理器 --><transactionManager type="JDBC"/><!-- 配置数据源 --><dataSource type="POOLED"><!-- 建立数据库连接的具体信息 --><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mybatis-example"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment></environments><mappers><!-- Mapper注册:指定Mybatis映射文件的具体位置 --><!-- mapper标签:配置一个具体的Mapper映射文件 --><!-- resource属性:指定Mapper映射文件的实际存储位置,这里需要使用一个以类路径根目录为基准的相对路径 --><!-- 对Maven工程的目录结构来说,resources目录下的内容会直接放入类路径,所以这里我们可以以resources目录为基准 --><mapper resource="mapper/EmpMapper.xml"/></mappers></configuration>
6、EmpMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- namespace等于mapper接口类的全限定名,这样实现对应 --> <mapper namespace="com.atguigu.mybatis.mapper.EmpMapper"><!-- 查询使用 select标签id = 方法名resultType = 返回值类型标签内编写SQL语句--><select id="getEmployeeList" resultType="com.atguigu.mybatis.pojo.Employee"><!-- #{empId}代表动态传入的参数,并且进行赋值!后面详细讲解 -->selectemp_id empId,emp_name empName,emp_salary empSalaryfrom t_emp</select><select id="getEmployeeById" resultType="com.atguigu.mybatis.pojo.Employee">selectemp_id empId,emp_name empName,emp_salary empSalaryfrom t_empwhere emp_id = #{value}</select><!--演示 ${}的用法--><select id="getEmployeeById2" resultType="com.atguigu.mybatis.pojo.Employee">selectemp_id empId,emp_name empName,emp_salary empSalaryfrom t_empwhere emp_id = ${value}</select><select id="getEmployeeListByName" resultType="com.atguigu.mybatis.pojo.Employee">selectemp_id empId,emp_name empName,emp_salary empSalaryfrom t_empwhere emp_name like #{value}</select><select id="getEmployeeListByName2" resultType="com.atguigu.mybatis.pojo.Employee">selectemp_id empId,emp_name empName,emp_salary empSalaryfrom t_empwhere emp_name like ${value}</select><select id="getEmployeeListByName3" resultType="com.atguigu.mybatis.pojo.Employee">selectemp_id empId,emp_name empName,emp_salary empSalaryfrom t_empwhere emp_name like '${value}'</select><select id="getEmployeeList2" resultType="com.atguigu.mybatis.pojo.Employee">selectemp_id empId,emp_name empName,emp_salary empSalaryfrom ${table_name}</select></mapper>
7、MybatisTest.java
package com.atguigu.mybatis; import com.atguigu.mybatis.mapper.EmpMapper; 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 org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.io.IOException; import java.io.InputStream; public class MybatisTest {SqlSessionFactory sqlSessionFactory;SqlSession sqlSession;EmpMapper empMapper;@BeforeEachpublic void setup() throws IOException {// 获取资源流,读取"mybatis-config.xml"文件InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");// 使用资源流创建SqlSessionFactorysqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);// 使用SqlSessionFactory打开一个SessionsqlSession = sqlSessionFactory.openSession();// 使用Session获取EmpMapper的Mapper对象empMapper = sqlSession.getMapper(EmpMapper.class);}// 在每个测试用例之后执行的清理方法@AfterEachpublic void teardown() {sqlSession.close(); // 关闭SqlSession}@Testpublic void getEmployeeListTest() {empMapper.getEmployeeList().forEach(System.out::println);}//Employee(empId=1, empName=tom, empSalary=200.33)//Employee(empId=2, empName=jerry, empSalary=666.66)//Employee(empId=3, empName=andy, empSalary=777.77)@Testpublic void getEmployeeByIdTest() throws IOException {System.out.println(empMapper.getEmployeeById(1));//select emp_id empId, emp_name empName, emp_salary empSalary from t_emp where emp_id = ?}@Testpublic void getEmployeeByIdTest2() throws IOException {System.out.println(empMapper.getEmployeeById2(1));//select emp_id empId, emp_name empName, emp_salary empSalary from t_emp where emp_id = 1}@Testpublic void getEmployeeListByNameTest() throws IOException {System.out.println(empMapper.getEmployeeListByName("lina"));//select emp_id empId, emp_name empName, emp_salary empSalary from t_emp where emp_name like ?}@Testpublic void getEmployeeListByNameTest2() throws IOException {System.out.println(empMapper.getEmployeeListByName2("lina"));//select emp_id empId, emp_name empName, emp_salary empSalary from t_emp where emp_name like lina}@Testpublic void getEmployeeListByNameTest3() throws IOException {System.out.println(empMapper.getEmployeeListByName3("lina"));//select emp_id empId, emp_name empName, emp_salary empSalary from t_emp where emp_name like 'lina'}@Testpublic void getEmployeeListByNameTest4() throws IOException {System.out.println(empMapper.getEmployeeListByName3("lina 'or 1=1 or emp_name like ' "));//select emp_id empId, emp_name empName, emp_salary empSalary from t_emp where emp_name like 'lina 'or 1=1 or emp_name like ' '}@Testpublic void getEmployeeList2Test() throws IOException {System.out.println(empMapper.getEmployeeList2("t_emp"));//Preparing: select emp_id empId, emp_name empName, emp_salary empSalary from t_emp} }
8、总结
- #{} 相当于 之前的占位符 ”?“ PreparedStatement:执行预处理SQL命令
- ${} 是拼接 Statement:执行SQL命令,注入式漏洞 " lina ' or 1=1 or emp_name like ' "
- https://blog.csdn.net/m0_65152767/article/details/134057420
9、${} 的使用场景
在MyBatis中,
${}
形式传参的主要使用场景是当参数值是已知且不会改变的时候。这通常用于静态值,例如 数据库表名、列名 等。例如,假设你有一个用户表,表名为
user_${id}
,其中id
是一个动态参数。在MyBatis的SQL语句中,你可以使用${}
来引用这个表名。当你执行这个SQL语句时,MyBatis会将${}
替换为实际的参数值。<select id="selectUserById" resultType="User"> SELECT * FROM user_${id} WHERE id = #{id} </select>
在这个例子中,
user_${id}
会被替换为实际的表名,例如user_1
、user_2
等。然而,需要注意的是,由于
${}
形式的参数会被直接替换到SQL语句中,因此它可能会引起SQL注入的问题。因此,当你使用这种形式的参数时,必须确保参数值是安全的,特别是当参数值来自于用户输入或其他不可信的源时。在这种情况下,应该使用其他形式的参数替换或者进行适当的输入验证和清理。在这个例子中,${tableName}
会被替换为实际的表名,这个表名是根据程序运行时的某个参数动态决定的。
在MyBatis中,
${}
形式传参的主要使用场景包括:
- 直接传递数据库字段名或者表名:在SQL语句中,你可能需要引用数据库的字段名或者表名。如果这些名称是动态的,或者是根据其他参数来变化的,那么就可以使用
${}
来进行传递。例如:
SELECT * FROM ${tableName} WHERE id = #{id}
在这个例子中,
${tableName}
会被替换为实际的表名,这个表名是根据程序运行时的某个参数动态决定的。
- 动态SQL语句:在构建SQL语句时,可能需要根据一些条件来动态的生成SQL语句。在这些情况下,可以使用
${}
来插入动态的SQL片段。例如:
<if test="searchParam != null"> AND ${searchParam} </if>
在这个例子中,
${searchParam}
会被替换为实际的搜索参数,这个参数的值是在运行时决定的。然而需要注意的是,使用
${}
进行传参时需要特别小心,因为它可能会导致SQL注入的问题。你必须确保所有的参数都是安全的,不能由外部用户直接控制。如果可能的话,最好使用#{}来进行传参,因为MyBatis会对#{}
内的参数进行预编译和转义,从而防止SQL注入。