【Java EE】Mybatis操作数据库

Mybatis操作数据库

### 文章目录

  • [Mybatis操作数据库](#{}和{}的区别 4.1 既然{}有SQL注入的风险,为什么还存在着这种方式呢 4.2 解决方式 五、模糊查询 六、数据库连接池)
  • [@[toc]](#{}和{}的区别 4.1 既然{}有SQL注入的风险,为什么还存在着这种方式呢 4.2 解决方式 五、模糊查询 六、数据库连接池)
  • [一、写在前面的规范](#{}和{}的区别 4.1 既然{}有SQL注入的风险,为什么还存在着这种方式呢 4.2 解决方式 五、模糊查询 六、数据库连接池)
  • [二、普通SQL](#{}和{}的区别 4.1 既然{}有SQL注入的风险,为什么还存在着这种方式呢 4.2 解决方式 五、模糊查询 六、数据库连接池)
  • [1. 注解形式](#{}和{}的区别 4.1 既然{}有SQL注入的风险,为什么还存在着这种方式呢 4.2 解决方式 五、模糊查询 六、数据库连接池)
  • [1.1 注意事项](#{}和{}的区别 4.1 既然{}有SQL注入的风险,为什么还存在着这种方式呢 4.2 解决方式 五、模糊查询 六、数据库连接池)
  • [1.2 如果数据库中的命名和Java中的命名不一致怎么映射?](#{}和{}的区别 4.1 既然{}有SQL注入的风险,为什么还存在着这种方式呢 4.2 解决方式 五、模糊查询 六、数据库连接池)
  • [2. XML形式](#{}和{}的区别 4.1 既然{}有SQL注入的风险,为什么还存在着这种方式呢 4.2 解决方式 五、模糊查询 六、数据库连接池)
  • [2.1 注意事项](#{}和{}的区别 4.1 既然{}有SQL注入的风险,为什么还存在着这种方式呢 4.2 解决方式 五、模糊查询 六、数据库连接池)
  • [1.2 如果数据库中的命名和Java中的命名不一致怎么映射?](#{}和{}的区别 4.1 既然{}有SQL注入的风险,为什么还存在着这种方式呢 4.2 解决方式 五、模糊查询 六、数据库连接池)
  • [三、动态SQL](#{}和{}的区别 4.1 既然{}有SQL注入的风险,为什么还存在着这种方式呢 4.2 解决方式 五、模糊查询 六、数据库连接池)
  • [3.1 XML形式](#{}和{}的区别 4.1 既然{}有SQL注入的风险,为什么还存在着这种方式呢 4.2 解决方式 五、模糊查询 六、数据库连接池)
  • [1. trim和if](#{}和{}的区别 4.1 既然{}有SQL注入的风险,为什么还存在着这种方式呢 4.2 解决方式 五、模糊查询 六、数据库连接池)
  • [2. where](#{}和{}的区别 4.1 既然{}有SQL注入的风险,为什么还存在着这种方式呢 4.2 解决方式 五、模糊查询 六、数据库连接池)
  • [3.set](#{}和{}的区别 4.1 既然{}有SQL注入的风险,为什么还存在着这种方式呢 4.2 解决方式 五、模糊查询 六、数据库连接池)
  • [四、#{}和{}的区别](#{}和{}的区别 4.1 既然${}有SQL注入的风险,为什么还存在着这种方式呢 4.2 解决方式 五、模糊查询 六、数据库连接池)
  • [4.1 既然{}有SQL注入的风险,为什么还存在着这种方式呢](#{}和{}的区别 4.1 既然${}有SQL注入的风险,为什么还存在着这种方式呢 4.2 解决方式 五、模糊查询 六、数据库连接池)
  • [4.2 解决方式](#{}和{}的区别 4.1 既然{}有SQL注入的风险,为什么还存在着这种方式呢 4.2 解决方式 五、模糊查询 六、数据库连接池)
  • [五、模糊查询](#{}和{}的区别 4.1 既然{}有SQL注入的风险,为什么还存在着这种方式呢 4.2 解决方式 五、模糊查询 六、数据库连接池)
  • [六、数据库连接池](#{}和{}的区别 4.1 既然{}有SQL注入的风险,为什么还存在着这种方式呢 4.2 解决方式 五、模糊查询 六、数据库连接池)

一、写在前面的规范

  1. 数据库命名: 蛇形。如:user_name。

  2. Java命名: 小驼峰。如:userName。

  3. 使用映射器(也即@Mapper)对于数据库和Java程序做链接🔗。

二、普通SQL

1. 注解形式

使用四个注解。

  1. @Select("")
  2. @Insert("")
  3. @Delete("")
  4. @Update("")

在括号中写的SQL语句和普通的没有区别。

java 复制代码
	@Select("select * from userinfo")
    List<UserInfo> getUserInfoAll4();

    // 获取自增ID
    @Options(useGeneratedKeys = true, keyProperty = "id")
    @Insert("insert into userinfo(userName,password,age,gender,phone) " +
            "values (#{userName},#{password},#{age},#{gender},#{phone})")
    Integer insertUserInfoByUser(UserInfo userInfo);

    @Delete("delete from userinfo where userName = #{userName}")
    Integer deleteUserInfoByName(String userName);

    @Update("update userinfo set password = #{password}, age = #{age}, gender = #{gender} where id = #{id}")
    Integer updateUserInfoByUser(UserInfo userInfo);
1.1 注意事项
  1. 接口中需要写上@Mapper注解
1.2 如果数据库中的命名和Java中的命名不一致怎么映射?
  1. 修改SQL语句,为数据库中的字段起别名

  2. 添加配置信息,使得驼峰命名和蛇形命名能够互相转换

    java 复制代码
    map-underscore-to-camel-case: true #配置驼峰⾃动转换
  3. 编写映射关系,主要使用@Result@Results

    java 复制代码
    // 3.映射关系
     @Results({
             @Result(column = "delete_flag", property = "deleteFlag"),
             @Result(column = "create_time", property = "createTime"),
             @Result(column = "update_time", property = "updateTime")
     })
     @Select("select * from userinfo")
     List<UserInfo> getUserInfoAll3();

2. XML形式

使用4个标签。

  1. <select>
  2. <insert>
  3. <delete>
  4. <update>
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.example.springmybatis.mapper.UserInfoXMLMapper">
    
    <insert id="insert">
        insert into userinfo(username, password, age, gender, phone)
        values (#{userName},#{password},#{age},#{gender},#{phone})
    </insert>
    
    <update id="update">
        update userinfo set username=#{userName}, password=#{password}, age=#{age}, gender=#{gender}, phone=#{phone}
        where id=#{id}
    </update>
        
    <delete id="delete">
        delete from userinfo where id=#{id}
    </delete>
        
    <select id="selectAllUsers" resultType="com.example.springmybatis.model.UserInfo">
        select * from userinfo
    </select>
        
</mapper>
2.1 注意事项
  1. 标签是接口的实现,具体的接口定义和注解形式的一样
  2. 标签的xml文件中,
    1. 配置文件中的namespace需要和接口文件的全限定路径保持一致
    2. 标签(<select id=''>)中,id需要和方法名称保持一致
  3. 接口中需要写上@Mapper注解
  4. select语句需要写上resultType,因为select返回的可能是数字(影响行数),也可能是一个或多个对象(这时就需要写上对象的全限定路径)。
1.2 如果数据库中的命名和Java中的命名不一致怎么映射?
  1. 修改SQL语句,为数据库中的字段起别名

  2. 添加配置信息,使得驼峰命名和蛇形命名能够互相转换

    java 复制代码
    map-underscore-to-camel-case: true #配置驼峰⾃动转换
  3. 编写映射关系

    xml 复制代码
    <resultMap id="BaseMap" type="com.example.springmybatis.model.UserInfo">
            <id column="id" property="id"></id>
            <result column="username" property="userName"></result>
            <result column="password" property="password"></result>
            <result column="age" property="age"></result>
            <result column="gender" property="gender"></result>
            <result column="phone" property="phone"></result>
            <result column="delete_flag" property="deleteFlag"></result>
            <result column="create_time" property="createTime"></result>
            <result column="update_time" property="updateTime"></result>
        </resultMap>
        
        // resultMap使用自己定义的id
        <select id="selectAllUsers" resultType="com.example.springmybatis.model.UserInfo" resultMap="BaseMap">
            select * from userinfo
        </select>

    注意resultMap的id就相当于自定义的映射关系的名字,在select标签上需要写上使用的是哪个映射关系。

三、动态SQL

3.1 XML形式

1. trim和if
xml 复制代码
<!--    动态SQL-->
    <insert id="insert2">
        insert into userinfo
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="userName!=null">
                username,
            </if>
            password, age, gender, phone
        </trim>
        values
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="userName!=null">
                #{userName},
            </if>
            #{password},#{age},#{gender},#{phone}
        </trim>
    </insert>
  1. prefix是被包裹的代码段的前面需要去掉的符号
  2. suffixOverrides是被<if>包裹的代码段,需要后面去掉的符号
  3. 这两个都有相对应的前(后)面的另一个属性
2. where
xml 复制代码
 <select id="selectAllUsers2" resultType="com.example.springmybatis.model.UserInfo">
        select * from userinfo
        <where>
            <if test="userName!=null">
                userName=#{userName}
            </if>
            <if test="age!=null">
                and age=#{age}
            </if>
            <if test="id!=null">
                and id=#{id}
            </if>
        </where>
    </select>
  1. where可以给SQL加上where关键字
  2. 可以去掉没用到的and关键字
  3. 如果一个条件都没有,可以不生成where关键字
3.set
xml 复制代码
<update id="update2">
        update userinfo
        <set>
            <if test="userName!=null">
                userName=#{userName},
            </if>
            <if test="age!=null">
                age=#{age},
            </if>
            <if test="id!=null">
                id=#{id},
            </if>
        </set>
        where id=#{id}
    </update>
  1. set可以去掉逗号
  2. 生成set关键字

四、#{}和${}的区别

  1. ${}是直接将字符串替换,存在SQL注入的风险
  2. #{}是将字符串加上单引号后,生成SQL语句
  3. ${}生成的是即时SQL,#{}生成的是预编译SQL(有?的占位符)

4.1 既然${}有SQL注入的风险,为什么还存在着这种方式呢

使用的场景是:SQL语句中不需要使用单引号就能完成,但是还是一个参数的情况。

  1. 排序,需要根据哪个字段进行排序
  2. 要查哪张表,根据表名进行SQL

比如:

sql 复制代码
select * from userinfo order by age

这里的age就不需要添加引号。

但是存在SQL注入的风险,先将上一句话结束,然后写上drop database等,存在风险。

4.2 解决方式

  1. 可以加上参数判断

    判断传进来的string是否是字段中的任意一个

  2. 或者直接封装成方法

    方法名就叫:queryAllUsersByAge

五、模糊查询

因为存在两个"%",这两个%又不能由用户传入,所以需要使用${}。

虽然${}能够完成需求,但是有专门的拼接函数concat()

xml 复制代码
	<select id="queryAllUserByLike" resultType="com.example.springmybatis.model.UserInfo">
        select * from userinfo where userName like concat('%',#{key},'%');
    </select>

六、数据库连接池

需要更换直接在配置中更换。

像线程池一样,可以减少开销。可以使多个程序使用同一个已经连接上的数据库,而不是再去建立连接。

跟换阿里Durid数据库:

xml 复制代码
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.17</version>
</dependency>
相关推荐
科技小花4 小时前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸4 小时前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql
凯尔萨厮4 小时前
创建SpringWeb项目(Spring2.0)
spring·mvc·mybatis
D4c-lovetrain4 小时前
linux个人心得22 (mysql)
数据库·mysql
阿里小阿希4 小时前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql
荒川之神4 小时前
Oracle 数据仓库雪花模型设计(完整实战方案)
数据库·数据仓库·oracle
做个文艺程序员4 小时前
MySQL安全加固十大硬核操作
数据库·mysql·安全
不吃香菜学java5 小时前
Redis简单应用
数据库·spring boot·tomcat·maven
一个天蝎座 白勺 程序猿5 小时前
Apache IoTDB(15):IoTDB查询写回(INTO子句)深度解析——从语法到实战的ETL全链路指南
数据库·apache·etl·iotdb
洛_尘5 小时前
Java EE进阶:Linux的基本使用
java·java-ee