Spring学习 -- MyBatis 操作数据库-1

23 篇文章 0 订阅

在这里插入图片描述

T04BF

👋专栏: 算法|JAVA|MySQL|C语言

🫵 今天你敲代码了吗

MyBatis

MyBatis是一款优秀的 持久化 框架,用于简化JDBC的开发,就是更加简单的完成程序与数据库之间交互的框架

1. Mybatis基础操作

1.1打印日志

在Mybatis中,我们可以借助日志,查看到sql语句的执行,执行传递的参数以及执行结果
只需要在配置文件中进行配置即可:

mybatis:
  configuration: # 配置打印 MyBatis⽇志
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

我们尝试运行一个测试用例:

  • 如果没有配置日志:

image.png

  • 配置了日志:

image.png
分别表示:执行的sql语句,参数的传递,以及sql执行的结果

1.2参数传递

如果我们要查一个id为4的用户信息:

@Mapper
public interface UserInfoMapper {
    @Select("select * from userinfo where id = 4")
    public UserInfo queryUserById();
}
@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;


    @Test
    void queryUserById() {
        UserInfo userInfo = userInfoMapper.queryUserById();
        System.out.println(userInfo);
    }
}

执行结果:
image.png
但是这样的话,貌似sql语句就写死了,因此sql语句里面的id不应该是固定数值
解决方法: 使用 #{}的方式获取方法中的参数

@Select("select * from userinfo where id = #{id}")
public UserInfo queryUserById(int id);


//测试代码
    @Test
    void queryUserById() {
        UserInfo userInfo = userInfoMapper.queryUserById(4);
        System.out.println(userInfo);
    }

执行结果:
image.png
也可以通过@Param 设置参数的别名

@Select("select * from userinfo where id = #{id}")
public UserInfo queryUserById(@Param("id") int id);

那么就会出现以下几种情况:
(1). 只有一个参数

@Select("select * from userinfo where id = #{param}")
public UserInfo queryUserById(int id);

执行结果:
image.png
结论:只有一个参数的时候,即使是参数名不一致,也不用指定
(2). 有多个参数

@Select("select * from userinfo where id = #{param} and username = #{name}")
public UserInfo queryUserById(int id,String username);


//测试用例:
    @Test
    void queryUserById() {
        UserInfo userInfo = userInfoMapper.queryUserById(4,"wangwu");
        System.out.println(userInfo);
    }

执行结果
image.png
报错提示:在参数id,param1,username,param2里面没有找到param
此时我们就能知道,实际上方法会自动帮我们生成几个参数:id,param1,username,param2
那么我们改动一下:

@Select("select * from userinfo where id = #{id} and username = #{username}")
public UserInfo queryUserById(int id,String username);

image.png
执行结果就是正确的
(3)多个参数加上@Param

@Select("select * from userinfo where id = #{id1} and username = #{username1}")
public UserInfo queryUserById(@Param("id") int id1,@Param("username") String username1);

执行结果:
image.png
报错提示:在参数id,param1,username,param2里面没有找到id1
此时我们就能知道,实际上方法会自动帮我们生成几个参数:id,param1,username,param2,其中 id 和 username 是 @Param注解里面的值
这样才是对的:

@Select("select * from userinfo where id = #{id} and username = #{username}")
public UserInfo queryUserById(@Param("id") int id1,@Param("username") String username1);

无论如何,如果有多个参数,sql里面的变量一定要和方法生成的参数名保持一致

1.3 INSERT

假设sql语句为:
insert into userinfo (username,password,age,gender,phone) values ("zhaoliu","zhaoliu",19,1,"15912412311");
需要将sql语句里面的常量替换成动态的参数

@Insert("insert into userinfo (username,`password`,age,gender,phone) " +
        "values (#{username},#{password},#{age},#{gender},#{phone});")
public int insertUser(UserInfo userInfo);

测试用例:

@Test
void insertUser() {
    UserInfo userInfo = new UserInfo();
    userInfo.setUsername("zhaoliu");
    userInfo.setPassword("zhaoliu");
    userInfo.setAge(18);
    userInfo.setGender(1);
    userInfo.setPhone("110");
    System.out.println(userInfoMapper.insertUser(userInfo));
}

执行结果:
image.png

** 返回主键**
通常情况下,我们需要增加数据后得到数据的主键,以供后续操作
想要拿到自增的ID,需要在Mapper接口的方法上添加一个Options的注解

@Options(useGeneratedKeys = true,keyProperty = "id")
@Insert("insert into userinfo (username,`password`,age,gender,phone) " +
        "values (#{username},#{password},#{age},#{gender},#{phone});")
public int insertUser(UserInfo userInfo);
  • useGeneratedKeys:会让MyBatis使用JDBC的getGeneratedKeys来得到由数据库内部生成的默认的主键(例如自增主键)
  • keyProperty:指定能够唯一识别对象的属性

测试用例:

@Test
void insertUser() {
    UserInfo userInfo = new UserInfo();
    userInfo.setUsername("zhaoliu");
    userInfo.setPassword("zhaoliu");
    userInfo.setAge(18);
    userInfo.setGender(1);
    userInfo.setPhone("110");
    System.out.println(userInfoMapper.insertUser(userInfo) + "  得到主键" + userInfo.getId());
}

执行结果
image.png

1.4 DELETE

    @Delete("delete from userinfo where id = #{id}")
    public int deleteUserById(@Param("id") int id);

测试用例:

@Test
void deleteUserById() {
    userInfoMapper.deleteUserById(5);
}

执行结果:
image.png

1.5 UPDATE

@Update("update userinfo set `password` = #{password} where id = #{id}")
public int updatePasswordById(UserInfo userInfo);

测试用例:

@Test
void updatePasswordById() {
    UserInfo userInfo = new UserInfo();
    userInfo.setPassword("123456");
    userInfo.setId(1);
    userInfoMapper.updatePasswordById(userInfo);
}

执行结果:
image.png

1.6 SELECT

我们在最开始查询的时候,发现其中有几个值是null
image.png但是明明数据库返回的值是有数值的
实际上,当自动映射查询结果时,Mybatis会获取结果中返回的列名并在java类中查找相同名字的属性(忽略大小写)
但是由于在数据库里面的列名是类似于"delete_flag" 这样的格式,而在java里面是类似于 "deleteFlag"的格式,匹配不上,就无法赋值
解决方法如下:

起别名

在sql语句中给列名起别名,保持列名和实体类属性名一致

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

测试用例:

@Test
void queryAllUser1() {
    List<UserInfo> userInfos = userInfoMapper.queryAllUser1();
    System.out.println(userInfos);
}

执行结果:
image.png

结果映射
@Select("select id,username,`password`,age,gender,phone,delete_flag,create_time from userinfo")
@Results({
    @Result(column = "delete_flag",property = "deleteFlag"),
    @Result(column = "create_time",property = "createTime"),
    @Result(column = "update_time",property = "updateTime")
})
List<UserInfo> queryAllUser2();

测试用例:

@Test
void queryAllUser2() {
    List<UserInfo> userInfos = userInfoMapper.queryAllUser2();
    System.out.println(userInfos);
}

代码:
image.png

如果其他的SQL也希望使用这个映射关系,可以使用能id给这个@Results定义别名,使用@ResultMap 注解来复用
image.png

开启驼峰命名

通常数据库列名命名是使用下划线分割各个单词的命名方式,而java属性名一般遵循驼峰命名法.
我们可以在配置文件里面将mapUnderscoreToCamelCase设置为true
image.png
此时即使是最之前,我们不做任何处理的java代码也能得到完整结果
image.png

感谢您的访问!!期待您的关注!!!

在这里插入图片描述

T04BF

🫵 今天记得敲代码
  • 7
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值