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);
相关推荐
一点媛艺7 分钟前
Kotlin函数由易到难
开发语言·python·kotlin
姑苏风11 分钟前
《Kotlin实战》-附录
android·开发语言·kotlin
奋斗的小花生1 小时前
c++ 多态性
开发语言·c++
魔道不误砍柴功1 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2341 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨1 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
老猿讲编程2 小时前
一个例子来说明Ada语言的实时性支持
开发语言·ada
Chrikk3 小时前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*3 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue3 小时前
go语言连续监控事件并回调处理
开发语言·后端·golang