MyBatis细节注意

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);
相关推荐
我要学编程(ಥ_ಥ)1 小时前
滑动窗口算法专题(1)
java·数据结构·算法·leetcode
niceffking1 小时前
JVM 一个对象是否已经死亡?
java·jvm·算法
薛文旺1 小时前
c++可视化打印树
开发语言·c++
计算机学姐1 小时前
基于python+django+vue的旅游网站系统
开发语言·vue.js·python·mysql·django·旅游·web3.py
真的很上进1 小时前
【Git必看系列】—— Git巨好用的神器之git stash篇
java·前端·javascript·数据结构·git·react.js
qq_278063711 小时前
css scrollbar-width: none 隐藏默认滚动条
开发语言·前端·javascript
Beginner_bml1 小时前
结构体---C语言
c语言·开发语言·数据结构
程序员小羊!1 小时前
Python语言基础教程(下)4.0
开发语言·python
vczxh1 小时前
c++ templates常用函数
开发语言·c++
科研小白_d.s1 小时前
intellij-idea创建html项目
java·html·intellij-idea