MyBatis入门——MyBatis的基础操作(2)

简介: MyBatis入门——MyBatis的基础操作(2)

准备工作:

       存在的表如下:(表名:userInfo)

       代码如下:

       

       实体类UserInfo类:

@Data
public class UserInfo {
    private Integer id;
    private String username;
    private String password;
    private Integer age;
    private Integer gender;
    private String phone;
    private Integer deleteFlag;
    private Date createTime;
    private Date updateTime;
}

       UserController类:

@RequestMapping("/user")
@RestController
public class UserController {
    @Autowired
    private UserService userService;
    @RequestMapping("/getUserAll")
    public List<UserInfo> getUserAll() {
        return userService.getUserAll();
    }
}

       UserServer类:

@Service
public class UserService {
    @Autowired
    private UserInfoMapper userInfoMapper;
    public List<UserInfo> getUserAll() {
        return userInfoMapper.getUserInfoAll();
    }
}

       UserInfoMapper接口:

@Mapper
public interface UserInfoMapper {
    @Select("select * from userinfo")
    List<UserInfo> getUserInfoAll();
    
}


一、打印日志


       在MyBatis当中,我们可以借助日志,查看SQL语句的执行、执行传递的参数以及执行结果,只需在配置文件中进行配置即可,配置内容如下:

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

       如果是application.properties,配置内容如下:

#指定mybatis输出⽇志的位置, 输出控制台
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

       测试类代码如下:

@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void getUserInfoAll() {
        System.out.println(userInfoMapper.getUserInfoAll());
    }
}

       运行测试类,控制台比之前多出了一些内容,如下图:


二、参数传递


       需求:查找id=4的用户,对应的SQL就是:select * from userinfo where id=4;

       UserInfoMapper接口代码:

@Mapper
public interface UserInfoMapper {
    @Select("select * from userinfo where id=4")
    List<UserInfo> queryById();
}

       测试类代码如下:

@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void queryById() {
        System.out.println(userInfoMapper.queryById());
    }
}

       但代码也可以写成其他样子:传递参数的方式,代码如下:

@Mapper
public interface UserInfoMapper {
    @Select("select * from userinfo")
    List<UserInfo> getUserInfoAll();
    @Select("select * from userinfo where id=#{id}")
    List<UserInfo> queryById(Integer id);
}
@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void queryById() {
        System.out.println(userInfoMapper.queryById(4));
    }
}

       执行代码,结果如下:

       也可以通过@Param设置参数的别名,如果使用@Param设置别名,#{....}里的属性名必须和@Param设置的一样,代码如下:

@Mapper
public interface UserInfoMapper {
    @Select("select * from userinfo where id=#{userid}")
    List<UserInfo> queryById2(@Param("userid") Integer id);
}

       如果不设置别名,最好传递的参数要和SQL语句里的属性名一样。

常见错误:使用对象接受

       现在表的数据如下:

       我们查询gender=2的数据。

       UserInfoMapper接口代码如下:

@Mapper
public interface UserInfoMapper {
    @Select("select * from userinfo where gender=#{gender}")
    UserInfo queryById3(Integer gender);
}

       测试代码如下:

@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void queryById3() {
        userInfoMapper.queryById3(2);
    }
}

       运行测试代码,执行结果如下:

       现在更改一下数据,gender=2的数据只有一个了,如图:

       在运行测试代码,没有报错,结果如下:

小结:

       对于只有一个返回结果,可以使用对象或集合接收对于有多个返回结果,只能使用集合接收


三、增(Insert)


       SQL语句:

insert into userinfo(username, password, age, gender, phone) values("zhaoliu","zhaoliu",19,1,"18700001234");

       UserInfoMapper接口代码如下:

没有使用@Param注解:

@Mapper
public interface UserInfoMapper {
    @Insert("insert into userinfo(username, password, age, gender) " +
            "values(#{username}, #{password}, #{age}, #{gender})")
    Integer insert(UserInfo userInfo);
}

使用@Param注解:

@Mapper
public interface UserInfoMapper {
    @Insert("insert into userinfo(username, password, age, gender) " +
            "values(#{userInfo.username}, #{userInfo.password}, #{userInfo.age}, #{userInfo.gender})")
    Integer insert(@Param("userInfo") UserInfo userInfo);
}

       测试类代码如下:

@SpringBootTest
class UserInfoMapperTest {
    @Test
    void insert() {
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("zhaoliu");
        userInfo.setPassword("123456");
        userInfo.setAge(66);
        userInfo.setGender(2);
        userInfoMapper.insert(userInfo);
    }
}

       运行测试类,控制台打印内容如下:

       查看userInfo表

       确实多了一行,id没衔接上是因为之前我测试了一下,添加了几行数据,后面又删除了。

返回主键

       想要添加主键,再加个@Options注解就好了。

       UserInfoMapper接口代码:

@Mapper
public interface UserInfoMapper {
    @Options(useGeneratedKeys = true, keyProperty = "id")
    @Insert("insert into userinfo(username, password, age, gender) " +
            "values(#{username}, #{password}, #{age}, #{gender})")
    Integer insert2(UserInfo userInfo);
}

       注解内的属性解释:

useGeneratedKeys这会令MyBatis使用JDBC的getGeneratedKeys方法来取出由数据库内部生成的主键(比如:像 MySQL 和 SQL Server 这样的关系型数据库管理系统的自动递增字段),默认值:false

keyProperty指定能够唯一识别对象的属性,MyBatis会使用getGeneratedKeys的返回值或Insert语句的selectKey子元素设置它的值默认值:未设置(unset)

       测试类代码:

@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    @Test
    void insert2() {
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("zhaoliu");
        userInfo.setPassword("123456");
        userInfo.setAge(66);
        userInfo.setGender(2);
        Integer count = userInfoMapper.insert2(userInfo);
        System.out.println("添加数据数:" + count + "数据ID:" + userInfo.getId());
    }
}

       运行测试类,运行结果如下:

注意设置 useGeneratedKeys=true之后,方法返回值依然是受影响的行数,自增id会设置在上述keyProperty指定的属性中


四、删(Delete)


       SQL:

delete from userinfo where id = 11

       UserInfoMapper接口代码:

@Mapper
public interface UserInfoMapper {
    @Delete("delete from userinfo where id = #{id}")
    Integer delete(Integer id);
}

       测试类代码:

@SpringBootTest
class UserInfoMapperTest {
    @Test
    void delete() {
        System.out.println(userInfoMapper.delete(11));
    }
}

       运行测试类前:

       运行测试类,结果如下:

       可以看到,id为11的数据被删除了。


五、改(Update)


       USerInfoMapper接口类代码:

@Mapper
public interface UserInfoMapper {
    @Update("update userinfo set username = #{username} where id = #{id}")
    Integer upadate(String username ,Integer id);
}

       测试类代码:

@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void upadate() {
        userInfoMapper.upadate("zhouba", 10);
    }
}

       运行测试类前表的数据:

       运行测试类,结果如下:

       可以看到,修改成功了。


六、查(Select)


       USerInfoMapper接口代码:

@Mapper
public interface UserInfoMapper {
    @Select("select id, username, `password`, age, gender, phone, delete_flag, create_time, update_time from userinfo")
    List<UserInfo> queryAllUser();
}

       测试类代码:

@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void queryAllUser() {
        System.out.println(userInfoMapper.queryAllUser());
    }
}

       运行测试类代码,结果如下:

       可以看到,有三个属性都是没有值的,为null原因数据库表的列名和实体类的属性名不一样,如图:

       也就是说自动映射查询结果时,MyBatis会获取结果中返回的列名并在Java类中查找相同名字的属性(忽略大小写)这意味着如果发现 ID列 和 id属性 对应时,MyBatis会把 ID列 的值赋给id属性

       因为数据库里面的表的列名 命名规范 和 Java的属性命名规范不一样,从而导致双方给同一个对象命名的名称不同,也就不能自动给它映射了解决办法有三种1、起别名  2、结果映射  3、开启驼峰命名

1、起别名

       USerInfoMapper接口类:

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

       测试类:

@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void queryAllUser2() {
        System.out.println(userInfoMapper.queryAllUser2());
    }
}

       运行测试类代码,结果如下:

       可以看到,现在的deleteFlag、createTime、updateTime 都不是null了。

2、结果映射

       使用@Results和@Result注解,USerInfoMapper类代码如下:

@Mapper
public interface UserInfoMapper {
    @Results({
            @Result(column = "delete_flag", property = "deleteFlag"),
            @Result(column = "create_time", property = "createTime"),
            @Result(column = "update_time", property = "updateTime")
    })
    @Select("select id, username, `password`, age, gender, phone, delete_flag, create_time, update_time from userinfo")
    List<UserInfo> queryAllUser3();
}

       测试类代码如下:

@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void queryAllUser3() {
        System.out.println(userInfoMapper.queryAllUser3());
    }
}

       运行测试类代码,结果如下:

       如果希望其他SQL也可以使用该映射就给@Results注释多加个id属性,其他SQL想使用,就加@ResultMap注解使用,代码如下:

@Mapper
public interface UserInfoMapper {
    @Results(id = "resultMap" , value = {
            @Result(column = "delete_flag", property = "deleteFlag"),
            @Result(column = "create_time", property = "createTime"),
            @Result(column = "update_time", property = "updateTime")
    })
    @Select("select id, username, `password`, age, gender, phone, delete_flag, create_time, update_time from userinfo")
    List<UserInfo> queryAllUser4();
 
    @ResultMap(value = "resultMap")
    @Select("select id, username, `password`, age, gender, phone, delete_flag, create_time, update_time from userinfo")
    List<UserInfo> queryAllUser5();
}

       使用id属性给该Results定义别名,使用@ResultMap注释来复用其他定义的ResultMap。如图:

3、开启驼峰命名(推荐)

       通常数据库列使用蛇形命名发进行命名(下划线分割各个单词),而Java属性一般遵循驼峰命名法约定为了在这两种命名方式之间启用自动映射,需要将 mapUnderscoreToCamelCase  设置为true。xml文件内容如下:

mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #配置打印 MyBatis⽇志
    map-underscore-to-camel-case: true  #自动驼峰转换

       驼峰命名规则abc_xyz => abcXyz表中字段名abc_xyz类中属性名abcXyz

       现在重新使用下面代码测试,USerInfoMapper接口代码如下:

@Mapper
public interface UserInfoMapper {
    @Select("select id, username, password, age, gender, phone, delete_flag, create_time, update_time from userinfo")
    List<UserInfo> queryAllUser();
}

       测试类代码:

@SpringBootTest
class UserInfoMapperTest {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Test
    void queryAllUser() {
        System.out.println(userInfoMapper.queryAllUser());
    }
}

       运行测试类代码,结果如下:

       可以看到,deleteFlag、createTime、updateTime这三个属性的值不为null全都被赋值了

相关文章
|
1月前
|
SQL Java 数据库连接
MyBatis 框架入门理论与实践
MyBatis 框架入门理论与实践
42 6
|
18天前
|
XML Java 数据库连接
MyBatis入门——MyBatis XML配置文件(3)
MyBatis入门——MyBatis XML配置文件(3)
24 5
|
18天前
|
Java 关系型数据库 数据库连接
MyBatis入门(1)
MyBatis入门(1)
18 1
|
2天前
|
SQL 存储 Java
基于MyBatis的增删改查的基础操作
基于MyBatis的增删改查的基础操作
11 0
|
1月前
|
Java 数据库连接 测试技术
MyBatis-Plus入门
MyBatis-Plus入门
|
17天前
|
Java 数据库连接 数据库
Spring日志完结篇,MyBatis操作数据库(入门)
Spring日志完结篇,MyBatis操作数据库(入门)
|
1天前
|
SQL Java 数据库连接
Mybatis Plus入门
Mybatis Plus入门
|
4天前
|
SQL Java 数据库连接
JavaWeb基础第三章(MyBatis的应用,基础操作与动态SQL)
JavaWeb基础第三章(MyBatis的应用,基础操作与动态SQL)
|
1月前
|
SQL 监控 数据库
MybatisPlus入门(下)
MybatisPlus入门教程中介绍了如何使用拦截器和性能分析插件。配置拦截器只需添加`PaginationInterceptor`,测试分页查询显示底层使用了`limit`。逻辑删除功能通过`TableLogic`注解和`LogicSqlInjector`实现,性能分析插件`PerformanceInterceptor`用于监控SQL执行时间,超过设定值会抛出异常。条件构造器如`QueryWrapper`提供便捷的查询条件设置,支持多种比较操作。
|
1月前
|
数据库