首页 > 其他分享 >MyBatis操作--初阶

MyBatis操作--初阶

时间:2024-11-14 17:47:57浏览次数:3  
标签:username 初阶 -- 数据库 userInfo SQL MyBatis id user

 博主主页: 码农派大星.

    数据结构专栏: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>

标签:username,初阶,--,数据库,userInfo,SQL,MyBatis,id,user
From: https://blog.csdn.net/jj666mhhh/article/details/143591277

相关文章

  • Spring Boot编程训练系统:核心特性与实现策略
    3系统分析3.1可行性分析通过对本编程训练系统实行的目的初步调查和分析,提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。3.1.1技术可行性本编程训练系统采用SSM框架,JAVA作为开发语言,是基于WEB平台的B/S架构系统......
  • Spring Boot编程训练系统:从概念到实现
    2相关技术2.1MYSQL数据库MySQL是一个真正的多用户、多线程SQL数据库服务器。是基于SQL的客户/服务器模式的关系数据库管理系统,它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等,非常适用于Web站点或者其他......
  • 企业工位管理:Spring Boot的力量
    1系统概述1.1研究背景随着计算机技术的发展以及计算机网络的逐渐普及,互联网成为人们查找信息的重要场所,二十一世纪是信息的时代,所以信息的管理显得特别重要。因此,使用计算机来管理企业级工位管理系统的相关信息成为必然。开发合适的企业级工位管理系统,可以方便管理人员对......
  • 2024年秋国开电大《建筑结构试验》形考任务1-4
    形考作业一1.下列选项中,()项不属于科学研究性试验。答案:检验结构的质量,说明工程的可靠性2.下列各项,()项不属于工程鉴定性试验。答案:验证结构计算理论的假定3.按试验目的进行分类,可将结构试验分成()。答案:工程鉴定性试验和科学研究性试验4.按试验对象进行分类,可将结构试验分成()......
  • (算法)买卖股票的最佳时机————<贪心算法>
    1.题⽬链接:121.买卖股票的最佳时机2.题⽬描述:3.解法(贪⼼):贪⼼策略:由于只能交易⼀次,所以对于某⼀个位置i,要想获得最⼤利润,仅需知道前⾯所有元素的最⼩值。然后在最⼩值的位置「买⼊」股票,在当前位置「卖出」股票即可。C++算法代码: classSolution{public:......
  • Rust ?(Rust错误传播运算符?)(用于简化错误处理,自动将错误从函数中返回)(可恢复错误Result<T
    文章目录Rust错误传播运算符:深入理解与应用1.错误处理的基础1.1`Result`枚举1.2`Option`枚举2.错误传播运算符(`?`)2.1基本语法2.2工作原理1.检查返回值2.提取`Ok`值2.3错误传播示例3.错误传播与自定义错误类型(没仔细看)3.1定义自定义错误类型3.2自定义......
  • 关于变量的声明和定义、内部函数和外部函数
    关于变量的声明和定义一个函数一般由两部分组成:声明部分和执行语句。声明部分的作用:是对有关的标识符(如变量、函数、结构体、共用体等)的属性进行声明。对于函数而言,声明和定义的区别是明显的,函数的声明是函数的原型,而函数的定义是对函数功能的定义。对被调用函数的声明是放在主调......
  • Rust泛型系统类型推导原理(Rust类型推导、泛型类型推导、泛型推导)为什么在某些情况必须
    文章目录示例代码疑问:代码不是能知道我要打印的是`&[i32]`吗?为啥非得要我加了`:std::fmt::Debug`它才能编译通过?答1.**Rust泛型系统的类型推导**2.**为什么要加`T:std::fmt::Debug`**3.**编译器如何处理泛型和trait约束**4.**Rust为什么需要这种明确的约束**5......
  • 校园交友系统的设计与实现(开源版+三端交付+搭建+售后)
    系统基础架构采用UniApp进行开发,UniApp是一个使用Vue.js开发所有前端应用的框架,它支持编译为H5、小程序、App等多个平台。使用PHP作为后端开发语言,PHP是一种广泛使用的开源脚本语言,尤其适用于Web开发,并可高效地与数据库进行交互。多端账号同步实现方式前后端数据交互:前端通......
  • 2024/11/14
    修改数组(蓝桥杯)分数20作者liudan单位石家庄铁道大学给定一个长度为N的数组A=[A1,A2,⋅⋅⋅AN],数组中有可能有重复出现的整数。现在小明要按以下方法将其修改为没有重复整数的数组。小明会依次修改A2,A3,⋅⋅⋅,AN。当修改Ai时,小明会检查Ai是否在A1∼Ai−1中出......