1.参数占位符:${} 和**#{}**
-
#{}
:占位符会将传入的值安全地转义,防止SQL注入攻击,它会在预编译阶段将占位符替换为一个问号?
,然后通过PreparedStatement设置参数值,从而确保安全性。适用于实际参数值作为参数传递给SQL语句的情况,如表名、字段名、条件值等。 -
${}
:占位符会直接替换为参数值,不提供SQL注入防护,因为它直接将传入的值嵌入到SQL语句中。适用于需要将动态内容(如列名、排序方式等)插入到SQL语句中的情况。
举例说明:
假设我们有一个查询方法,通过MyBatis传递参数:
sql
SELECT * FROM employee WHERE department = #{dept}
如果使用**#{}
**:
java
String department = "IT";
employeeMapper.getEmployeesByDepartment(department);
MyBatis会把这个参数转义处理,生成类似以下的SQL语句来避免SQL注入:
sql
SELECT * FROM employee WHERE department = ?
如果使用**${}
**:
java
String sortBy = "name";
employeeMapper.getAllEmployeesOrderedBy(${sortBy});
以${}
方式拼接SQL语句会将${sortBy}
替换为实际的参数值,可能导致SQL注入风险:
sql
SELECT * FROM employee ORDER BY name
因此,一般来说,为了避免SQL注入等安全问题,推荐优先使用#{}
占位符来传递参数值。
2.resultType的使用
resultType = "全限定符 | 别名 | 如果是返回集合类型,写范型类型即可"
1.全限定符
XML
<select id="xxx" resultType="com.example.pojo.Xxx">
xxx
</select>
2.别名为自定义类
方式一:在配置typeAlias标签中声明类
XML
<typeAlias type="com.example.pojo.Employee" alias="hahaha" />
<!-- 整个包下的类在使用时能直接使用 Bean 的首字母小写的非限定类名来作为它的别名-->
XML
<select id="xxx" resultType="hahaha" >
xxx
</select>
方式二:在配置typeAlias标签中声明包(更方便)
XML
<typeAliases>
<!-- 批量将包下的类给与别名,别名就是类的首字母小写! -->
<package name="com.example.pojo"/>
</typeAliases>
方式三:直接在类中注解
java
@Alias("author")
public class Author {
...
}
3.别名为常见的 Java 类型
XML
<select id="xxx" resultType="_double">
xxx
</select>
别名 | 映射的类型 |
---|---|
_byte | byte |
_char (since 3.5.10) | char |
_character (since 3.5.10) | char |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
首字母改为小写 | 其他 |
4.集合类型
1.有的情况下没有实体类可以使用接值的时候, 我们可以使用map接受数据!
key - > 查询的列
value -> 查询的值
XML
<select id="xxx" resultType="map">
xxx
</select>
2.返回值是集合。resultType不需要指定集合类型,只需要指定泛型即可
XML
//查询工资高于传入值的员工姓名们 200
List<String> queryNamesBySalary(Double salary);
<select id="queryNamesBySalary" resultType="string">
select emp_name from t_emp where emp_salary > #{ salary }
</select>
//查询全部员工信息
List<Employee> queryAll();
<select id="queryAll" resultType="employee">
select * from t_emp
</select>
3.自增长主键回显
有时我们想要数据库自动增强的主键值怎么做
XML
<insert id="insertEmp" useGeneratedKeys="true" keyColumn="emp_id" keyProperty="empId">
insert into t_emp (emp_name,emp_salary)
value(#{empName},#{empSalary});
</insert>
<!--例如员工插入时
int insertEmp(Employee employee);
useGeneratedKeys="true" 我们想要数据库自动增强的主键值
keyColumn="emp_id" 主键列的值!!!
keyProperty="empId" 接收主键列值的属性!!!-->
4.当非自增长的主键,如何交给mybatis帮助我们维护
1.自己维护主键
java
String id = UUID.randomUUID().toString().replaceAll("-", "")
employee.settId(id);
2.mybatis维护
XML
<insert id="insertxxx">
<!-- 插入之前,先指定一段sql语句,生成一个主键值!
order="before|after" sql语句是在插入语句之前还是之后执行!
resultType = 返回值类型
keyProperty = 查询结果给哪个属性赋值
-->
<selectKey order="BEFORE" resultType="string" keyProperty="tId">
SELECT REPLACE(UUID(),'-','');
</selectKey>
INSERT INTO teacher (t_id,t_name)
VALUE(#{tId},#{tName});
</insert>
5.实体类属性和数据库字段名对应问题
XML
<select id="queryByNameAndSalary" resultType="Employee">
select emp_id empId , emp_name empName , emp_salary empSalary
from t_emp where emp_name = #{param1} and emp_salary = #{param2}
</select>
能看出在查询时为了对应上实体类属性和数据库字段名,将查询结果列名映射为empId......了,那么还有其他办法吗?
方案一:开启驼峰式映射
在mybatis配置文件下添加settings属性,数据库字段自动映射为驼峰式empId。
XML
<settings>
<!--开启驼峰式自动映射 数据库 a_column->java aColumn -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
方案二:使用resultMap自定义映射代替resultType自动映射
XML
<resultMap id="employeeResultMap" type="Employee">
<!--id 为主键映射关系
result 为普通列的映射关系-->
<id column="emp_id" property="id" />
<result column="emp_name" property="name" />
<result column="emp_salary" property="salary" />
<!-- Other mappings -->
</resultMap>
<select id="getEmployeeById" resultMap="employeeResultMap">
SELECT emp_id, emp_name, emp_salary FROM employee WHERE emp_id = #{id}
</select>
6.让mybatis自动开启事务提交
在写插入语句时,要让sqlSession.commit()提交事务才能插入数据库。
java
//openSession自动开启事务,不会自动提交 !
//openSession(true)自动开启事务,自动提交事务! 不需要sqlSession.commit();
SqlSession session = sf.openSession(true);