MyBatis操作--初阶

 博主主页: 码农派大星.

    数据结构专栏:Java数据结构

 数据库专栏:MySQL数据库

JavaEE专栏:JavaEE

软件测试专栏:软件测试

关注博主带你了解更多知识

目录

 1. MyBatis概念

2. MyBatis⼊⻔ 

2.1 Navicat 安装 

2.2 数据准备 

2.3 配置数据库连接

2.4 完善持久层代码 

2.5 测试

1.自己书写测试代码

 2. 使⽤Idea⾃动⽣成测试

​编辑

3. MyBatis的基础操作 

3.1 打印⽇志

3.2 参数传递 

未加@Param 

加@Param 

 查多个参数:

​编辑 总结: ​编辑

3.3 增(Insert) 

如果设置了@Param属性,#{...}需要使⽤参数.属性来获取 

自增Id

 3.4 删(Delete)

3.5 改(Update) 

​编辑 3.6 查(Select)

1 起别名

2 结果映射 

 3 配置驼峰⾃动转换

​编辑

4. MyBatis XML配置⽂件

4.1 配置数据库连接字符串和MyBatis

4.2 写持久层代码

1 添加mapper接⼝

2 添加UserInfoXMLMapper.xml

3 单元测试

4.3 查(Select) 

4.4 增

4.5 改 

4.6 删

5 多表查询 

6. #{} 和 ${} 

6.1 #{} 和${}区别 

7. 排序功能

8. like查询

9. 数据库连接池 

使用


 1. MyBatis概念

MyBatis是⼀款优秀的持久层框架,⽤于简化JDBC的开发

持久层:指的就是持久化操作的层,通常指数据访问层(dao),是⽤来操作数据库的

MyBatis是更简单完成程序和数据库交互的框架,也就是更简单的操作和读取数据库⼯具

2. MyBatis⼊⻔ 

Mybatis操作数据库的步骤:

1. 准备⼯作(创建springboot⼯程、数据库表准备、实体类)

2. 引⼊Mybatis的相关依赖,配置Mybatis(数据库连接信息)

3. 编写SQL语句(注解/XML)

4. 测试 

2.1 Navicat 安装 

这里我们会用到操作数据库的工具, 比如说Navigate ,小编为大家找好了,也感谢贡献者酷酷的洛克

Navigate 破解版 在这: 文件文件大小:95.9 M|icon-default.png?t=O83Ahttps://kkdaj.lanzouq.com/iCJfT04o3pkh

教程: Navicat Premium 16 永久破解激活 - 酷酷的洛克 - 博客园文件

2.2 数据准备 

安装完 Navicat 打开连接数据库就行

创建⽤⼾表

创建对应的实体类UserInfo 

2.3 配置数据库连接

Mybatis中要连接数据库,需要数据库相关参数配置

MySQL驱动类登录名密码数据库连接字符串

application.yml⽂件,配置内容如下:

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
    username: root
    password: '123456'
    driver-class-name: com.mysql.cj.jdbc.Driver

2.4 完善持久层代码 

在项⽬中,创建持久层接⼝UserInfoMapper

@Mapper
public interface UserInfoMapper {

    @Select("select * from user_info")
    List<UserInfo> queryUserInfos();
}

2.5 测试

1.自己书写测试代码


@RequestMapping("/user")
@RestController
public class UserController {
    @Autowired
    private UserService userService;

    @RequestMapping("/queryUserInfos")
    public List<UserInfo> queryUserInfos(){

        return userService.queryUserInfos();

    }
}
@Service
public class UserService {
    @Autowired
    private UserInfoMapper userInfoMapper;

    public List<UserInfo> queryUserInfos(){

        return userInfoMapper.queryUserInfos();

    }
}

测试结果: 成功查询出数据

 2. 使⽤Idea⾃动⽣成测试

@SpringBootTest
class UserInfoMapperTest {

    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void queryUserInfos() {
        userInfoMapper.queryUserInfos().forEach(System.out::println);

    }

}

运行成功: 

3. MyBatis的基础操作 

3.1 打印⽇志

打印日志需要先配置文件

application.yml, 配置内容如下:

mybatis:
  configuration: # 配置打印 MyBatis 执行的 SQL
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

重启程序运行: 

3.2 参数传递 

如果mapper接⼝⽅法形参只有⼀个普通类型的参数,#{…}⾥⾯的属性名可以随便写,如:#{id}、# {value}。建议和参数名保持⼀致

可以通过 @Param ,设置参数的别名,如果使⽤ @Param 设置,#{...}⾥⾯的属性名必须和@Param 设置的⼀样

  @Select("select * from user_info where id = #{id}")
    UserInfo queryUserInfo(Integer id);
 @Select("select * from user_info where id = #{id}")
    UserInfo queryUserInfo(@Param("id") Integer id);
未加@Param 

加@Param 

测试:

 @Test
    void queryUserInfo() {
        System.out.println(userInfoMapper.queryUserInfo(1));
    }

结果:

 查多个参数:

@Select("select * from user_info where id = #{id} and username = #{username}")
    UserInfo queryUserInfoByIdAndName(Integer id, String username);

 使用@Param重命名会报错

 总结: 

3.3 增(Insert) 

@Insert("insert into user_info (username, password,age,gender,phone) " +
            "values(#{username},#{password},#{age},#{gender},#{phone})")
    Integer insert(UserInfo userInfo);

  @Test
    void insert() {
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("cxkun");
        userInfo.setPassword("cxkun");
        userInfo.setAge(33);
        userInfo.setGender(2);
        userInfo.setPhone("10086");
        Integer result = userInfoMapper.insert(userInfo);
        System.out.println("添加数据: "+ result);

    }

 

测试结果:

如果设置了@Param属性,#{...}需要使⽤参数.属性来获取 

 @Insert("insert into user_info (username, password,age,gender,phone) " +
            "values(#{userInfo.username},#{userInfo.password},#{userInfo.age},#{userInfo.gender},#{userInfo.phone})")
    Integer insert2(@Param("userInfo") UserInfo userInfo);

 测试结果:

自增Id

如果想要拿到⾃增id,需要在Mapper接⼝的⽅法上添加⼀个Options的注解

@Options(useGeneratedKeys = true,keyProperty = "id")
    @Insert("insert into user_info (username, password,age,gender,phone) " +
            "values(#{username},#{password},#{age},#{gender},#{phone})")
    Integer insert(UserInfo userInfo);

 

 3.4 删(Delete)

  @Delete("delete from user_info where id = #{id}" )
    Integer delete(Integer id);

3.5 改(Update) 

 @Update("update user_info set password =#{password} where id = #{id}")
    Integer update(UserInfo userInfo);

 3.6 查(Select)

1 起别名

 @Select("select id,username,password,age,gender,phone," +
            "delete_flag as deleteFlag,create_time as createTime,update_time as updateTime from user_info" )
    List<UserInfo> queryUserInfos2();

2 结果映射 

 @Results({
            @Result(column = "delete_flag",property = "deleteflag"),
            @Result(column = "create_time",property = "createtime"),
            @Result(column = "update_time",property = "updatetime")
    })
    @Select("select * from user_info" )
    List<UserInfo> queryUserInfos3();

 并且还可实现复用:

 3 配置驼峰⾃动转换

4. MyBatis XML配置⽂件

Mybatis的开发有两种⽅式:

1. 注解  2. XML

使⽤Mybatis的注解⽅式,主要是来完成⼀些简单的增删改查功能.如果需要实现复杂的SQL功能,建 议使⽤XML来配置映射语句,也就是将SQL语句写在XML配置⽂件中

步骤:

4.1 配置数据库连接字符串和MyBatis

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
    username: root
    password: '123456'
    driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
  mapper-locations: classpath:mapper/*.xml

4.2 写持久层代码

持久层代码分两部分 1. ⽅法定义Interface 2. ⽅法实现:XXX.xml

1 添加mapper接⼝

import com.mybatis.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface UserInfoXmlMapper {

    List<UserInfo> queryUserInfos();
}

2 添加UserInfoXMLMapper.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.mybatis.mapper.UserInfoXmlMapper">

    <select id="queryUserInfos" resultType="com.mybatis.model.UserInfo">
        select * from user_info;
    </select>
</mapper>

检查好配置: 

3 单元测试

@SpringBootTest
class UserInfoXmlMapperTest {
    @Autowired
    private UserInfoXmlMapper userInfoXmlMapper;

    @Test
    void queryUserInfos() {
        userInfoXmlMapper.queryUserInfos().forEach(System.out::println);

    }
}

测试成功: 

4.3 查(Select) 

1. 起别名 2. 结果映射 3. 开启驼峰命名

起别名和驼峰转换方法与注释一样,不在多说,接下来说结果映射

  <resultMap id="XMLBaseMap" type="com.mybatis.model.UserInfo">
        <id column="id" property="id"></id>

        <result column="delete_flag" property="deleteFlag"></result>
        <result column="create_time" property="createTime"></result>
        <result column="update_time" property="updateTime"></result>
    </resultMap>

    <select id="queryUserInfos2" resultMap="XMLBaseMap">
        select * from user_info;
    </select>

 测试:

 @Test
    void queryUserInfos2() {
        userInfoXmlMapper.queryUserInfos2().forEach(System.out::println);
    }

测试成功: 

4.4 增

UserInfoXmlMapper接⼝:

 Integer insertUserInfo(UserInfo userInfo);

UserInfoMapper.xml实现:

 <insert id="insertUserInfo">
        insert into user_info (username, password, age,gender, phone)
        values (#{username},#{password}, #{age},#{gender},#{phone})

    </insert>
UserInfoXmlMapperTest测试:
 @Test
    void insertUserInfo() {
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("cxk");
        userInfo.setPassword("cxk");
        userInfo.setGender(1);
        userInfo.setAge(18);
        userInfo.setPhone("13124124334");
        userInfoXmlMapper.insertUserInfo(userInfo);
    }

测试成功: 

刷新数据库有新增的信息:

4.5 改 

UserInfoXmlMapper接⼝:

 Integer updateUserInfo(UserInfo userInfo);

UserInfoMapper.xml实现:

 <update id="updateUserInfo">
        update user_info set phone = #{phone} where id = #{id}
    </update>

UserInfoXmlMapperTest测试:

 @Test
    void updateUserInfo() {
        UserInfo userInfo = new UserInfo();
        userInfo.setPhone("12344444444");
        userInfo.setId(13);
        userInfoXmlMapper.updateUserInfo(userInfo);
    }

测试成功: 

4.6 删

UserInfoXmlMapper接⼝:

 Integer deleteUserInfo(Integer id);

 UserInfoMapper.xml实现:

 <delete id="deleteUserInfo">

        delete from user_info where id = #{id}

    </delete>

UserInfoXmlMapperTest测试:

 @Test
    void deleteUserInfo() {
        userInfoXmlMapper.deleteUserInfo(14);


    }

测试成功:

5 多表查询 

使用两张表进⾏多表关联查询

⽂章表的uid,对应⽤⼾表的id 

补充实体类: 

public class ArticleInfo {
    private Integer id;
    private String title;
    private String content;
    private Integer uid;
    private String username;
    private Integer age;
    private Integer deleteFlag;
    private Date createTime;
    private Date updateTime;
}

根据uid查询作者的名称等相关信息

@Mapper
public interface ArticleInfoMapper {

    @Select("select ta.*, tb.username, tb.age from articleinfo ta" +
            " left join user_info tb on ta.uid=tb.id" +
            " where ta.id = #{articleId}")
    ArticleInfo queryArticleInfo(Integer articleId);
}

测试

@SpringBootTest
class ArticleInfoMapperTest {

    @Autowired
    private ArticleInfoMapper articleInfoMapper;


    @Test
    void queryArticleInfo() {
        articleInfoMapper.queryArticleInfo(1);

    }
}

查询成功: 

6. #{} 和 ${} 

 @Select("select * from user_info where username = #{username}")
    UserInfo queryUserInfoByName(String username);
 @Select("select * from user_info where username = ${username}")
    UserInfo queryUserInfoByName(String username);

6.1 #{} 和${}区别 

#{} 和${} 的区别就是预编译SQL和即时SQL的区别

当客⼾发送⼀条SQL语句给服务器后,它的流程应该为:先解析语法和语义,校验SQL语句是否正确再优化SQL语句,制定执⾏计划最后 执⾏并返回结果

$是即时SQL(参数直接拼接),#是预编译SQL(参数通过占位的方式)

${} 允许直接将变量的值替换到 SQL 语句中(参数直接拼接的方式)。这种方式可能会导致 SQL 注入攻击,因为它直接将变量值拼接到 SQL 语句中,没有进行任何处理

#{}:用于安全地插入参数(参数通过站位的方式),MyBatis 会为这些参数创建预处理语句,从而防止 SQL 注入攻击。

预编译SQL,编译⼀次之后会将编译后的SQL语句缓存起来,后⾯再次执⾏这条语句时,不会再次编译 (只是输⼊的参数不同),省去了解析优化等过程,以此来提⾼效率

SQL注⼊:是通过操作输⼊的数据来修改事先定义好的SQL语句,以达到执⾏代码对服务器进⾏攻击的⽅法

7. 排序功能

使⽤ ${} 可以实现排序查询,⽽使⽤ #{} 就不能实现排序查询了,SQL语句中,排序规则是不需要加引号,所以此时的${} 也不加引号

使⽤ #{} 查询时,desc前后⾃动给加了引号,导致sql错误

#{} 会根据参数类型判断是否拼接引号,如果参数类型为String就会加引号

改为${} 再试:

 //排序
    @Select("select * from user_info order by id ${order}")
    List<UserInfo> queryUserInfoByOrder(String order);

测试成功: 

除此之外,还有表名作为参数时,也只能使⽤ ${} 

8. like查询

like 使⽤#{}报错

${}可以正确查出来,但是${}存在SQL注⼊的问题,所以不能直接使⽤${},使⽤mysql的内置函数concat()来处理

 @Select("select * from user_info where username like CONCAT('%',#{name},'%')")
    List<UserInfo> queryUserInfoByLike(String name);

测试成功: 

9. 数据库连接池 

数据库连接池技术,避免频繁的创建连接,销毁连接

数据库连接池负责分配、管理和释放数据库连接,它允许应⽤程序重复使⽤⼀个现有的数据库连接, ⽽不是再重新建⽴⼀个

没有使⽤数据库连接池的情况:每次执⾏SQL语句,要先创建⼀个新的连接对象,然后执⾏SQL语句,SQL 语句执⾏完,再关闭连接对象释放资源.这种重复的创建连接,销毁连接⽐较消耗资源 

使⽤数据库连接池的情况:程序启动时,会在数据库连接池中创建⼀定数量的Connection对象,当客⼾ 请求数据库连接池,会从数据库连接池中获取Connection对象,然后执⾏SQL,SQL语句执⾏完,再把 Connection归还给连接池 

优点: 1. 减少了⽹络开销 2. 资源重⽤ 3. 提升了系统的性能

使用

1. Hikari : SpringBoot默认使⽤的数据库连接池

2. Druid

把默认的数据库连接池切换为Druid数据库连接池,只需要引⼊相关依赖

 <dependency>
 <groupId>com.alibaba</groupId>
 <artifactId>druid-spring-boot-starter</artifactId>
 <version>1.1.17</version>
 </dependency>

评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值