第8章 使用注解的方式整合MyBatis 入门详解

目录

注解方式和配置文件方式的优缺点

使用注解方式整合MyBatis

添加依赖

配置application.properties文件

在启动类上添加apperScan注解

创建mapper接口和实体类目录

添加实体类

测试验证

添加参数

直接传参

使用Param注解

使用Map和POJO

​分页查询

物理分页的实现核心


注解方式和配置文件方式的优缺点

 MyBatis不仅提供了通过配置文件方式操作数据库的方法,同时也提供了使用注解方式操作数据库的方式。相对使用配置文件整合MyBatis的方式,使用注解整合MyBatis的方式有自己的优缺点:

优点有:使用注解形式开发效率相对较高,在代码中直接判断拼接比较简单方便。

缺点有:使用注解形式代码维护麻烦,SQL和代码混合修改SQL需要重新编译打包,同时代码阅读起来相对困难。

注解形式适合简单快速的开发模式例如,使用微服务架构的项目,而大型传统架构的项目使用配置文件的模式可以将SQl和代码分开,维护方便。

使用注解方式整合MyBatis

添加依赖

接下来我们实践一下如何使用注解方式整合MyBatis。和前面的章节一样,首先添加MyBatis核心依赖

<dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
</dependency>
由于我们使用的是MySQL数据库,添加数据库连接相关依赖
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
如果初始化创建项目时已经添加了可以跳过这一步。

配置application.properties文件

注意配置MyBatis.type-aliases-package,指明Java实体类的路径

spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_demo?useSSL=true&useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=itJMF-4RObQ2
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

MyBatis.mapper-locations=classpath:/mapper/*.xml
MyBatis.type-aliases-package=com.cjl.chapter8.model

在启动类上添加apperScan注解

在启动类中,本例是Chapter8Application类上添加MapperScan注解,告诉MyBatis mapper接口 文件扫描路径

@SpringBootApplication
@MapperScan("com.cjl.chapter8.mapper")
public class Chapter8Application {

    public static void main(String[] args) {
        SpringApplication.run(Chapter8Application.class, args);
    }

}

创建mapper接口和实体类目录

在com.cjl.chapter8目录(包)下创建mapper和model目录,分别用于存放mapper接口文件和Java实体类。注意这里的路径需要和前面的配置内容一致

添加实体类

在model目录下添加User.java,创建构造函数和基本的setter/getter方法

public class User {
    private long id;
    private String name;
    private int age;
    private int city_id;

    public User() {

    }

    public User(String name, int age, int city_id) {
        this.name = name;
        this.age = age;
        this.city_id = city_id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getCityId() {
        return city_id;
    }

    public void setCityId(int city_id) {
        this.city_id = city_id;
    }
}
 

在mapper目录下添加UserMapper接口,注意这里添加了Component注解,以便Spring boot扫描。同时使用了 Select注解,添加了一条select * from user的SQL语句

@Component
public interface UserMapper {
    @Select("select * from user")
    List<User> selectAllUser();
}

完成以上操作之后,我们就完成了一条最基本的select语句。接下来我们测试一下,看注解形式是否生效。

测试验证

在测试类中添加测试代码,注意这里给userMapper添加了Autowired注解,使得Spring boot扫描到

    @Autowired
    UserMapper userMapper;

    @Test
    void contextLoads() {
    }

    @Test
    public void testSelectAllUser() {
        List<User> users =  userMapper.selectAllUser();
        for(User user : users) {
            System.out.println(" user name: " + user.getName()
            + " age: " + user.getAge());
        }
    }
执行测试程序

成功输出查询结果,说明使用注解形式整合的MyBatis已经生效。

添加参数

直接传参

前面的例子SQL语句是固定的,没有参数。现在我们尝试传递一些参数试试,我们写一个按id查询User

@Select("select * from user where id=#{id}") User selectUserById(Long id);

可以看到这里参数的语法和XML配置文件是一致的。

添加测试用例

    @Test
    public void testSelectUserById() {
        User  user = userMapper.selectUserById(1L);
        System.out.println(" user name: " + user.getName()
                + " age: " + user.getAge());

    }
 

运行输出

这里要注意使用#{xx}语法传入变量参数,定义的参数名必须和方法中的参数名保持一致,另外#{xx}语法支持传入多个参数。

但是有的时候参数名和数据库字段名并不一致,这个时候怎么办呢?

使用Param注解

使用Param注解,Param注解可以为参数取个别名,先上例子

    @Select("select * from user where name=#{name} and age=#{age}")
    User selectUserByParam(@Param("name") String realName, @Param ("age") Integer realAge);
 

解释一下 @Param(“name”)相当于在给了参数realname一个别名,并且在传递给SQL时会转换为#{name}语法,这样就完成了参数名和字段的映射。

编写测试程序并且运行

    @Test
    public void testSelectUserByParam() {
        User user = userMapper.selectUserByParam("张华",28);
        System.out.println(" user name: " + user.getName()
                + " age: " + user.getAge());
    }
 

使用Map和POJO

有时候传递会觉得传递多个参数较为繁琐,而且有时多个传递的参数是一个相对紧密的集合,那可以考虑使用哈希Map传递参数

    @Select("select * from user where name=#{name} and age = #{age}")
    User selectUserByMap(Map<String, Object> map);
 

将SQL语句需要的参数通过map类型传入,key为参数名,value为参数值。MyBatis会自动匹配对应的映射中的参数值。注意这里Map的Value对应类型是Object,因为Value值的类型可能有多种多样。

@Test
    public void testSelectUserByMap() {
        Map<String, Object> param = new HashMap<>();
        param.put("name", "陈雨");
        param.put("age", 22);
        User user = userMapper.selectUserByMap(param);
        System.out.println(" user name: " + user.getName()
                + " age: " + user.getAge());
    }
执行结果

​对于insert、update等参数较多的方法,可以使用pojo对象传参。需要注意的是,参数的名字和类型必须和pojo对象的属性保持一致

    @Insert({
            "insert into user (name, age, city_id) values ( " +
                    "#{name, jdbcType=VARCHAR}, " +
                    "#{age, jdbcType=INTEGER}, " +
                    "#{city_id, jdbcType=INTEGER} )"
    })
    void inset(User user);
编辑测试用例
    @Test
    public void testInsertUser() {
        User usr = new User("测试", 20, 1);
        userMapper.inset(usr);
        testSelectAllUser();
    }
执行输出如下

​分页查询

首先我们说一下为什么要有分页查询,假如有一个数据库存储了很多数据例如上亿条,那如果没有使用分页查询的话,会存在两个问题:

查询的客户端例如小程序、APP或者浏览器的单次加载数据过多,容易导致应用崩溃

查询数据库的数据量过大,数据库传输大量的数据,导致查询的很长

对于这两个问题一般是通过分页解决,对于分页来说主要有两类逻辑分页和物联分页。

逻辑分页:本身后台还是一次性将所有数据查询出来,保存到集合中如List,后续如果有分页请求,再对List集合进行拆分,这种做法优点是减少了操作数据库的次数,但它并没有减少单次查询数据库的数据总量,单次查询数据库的时间还是会很长

物理分页:不是一次性将所有数据全部查询出来而是按当前的需要按页进行查询,例如每页需要展示.查询第一页:发送一条查询20条的SQL语句.查询下 一页数据:又发送一条查询后20条的SQL语句.有点单词查询数据库的时间非常短,但操作数据库的次数增加。

由于在一般的数据查询应用场景,用户都没有必要一次性查看所有数据,因此经常采用物理分页的方法

物理分页的实现核心

一般实现物理分页是采用select 命令的limit关键字实现,limit关键字有两个参数,第一个参数指定要返回的第一行的偏移量,第二个参数指定要返回的最大行数,注意初始行的偏移量是0,不是1。

SELECT * FROM tbl LIMIT 5,10; # 假设有16行则剩余6-15行

在数据展示的一侧只要知道每页展示多少,当前需要展示第几页,然后发送对应的参数到数据库进行查询即可。在实际应用中我们通常是通过插件实现自动分页的,例如MyBatis框架下也有很多插件可以实现分页功能,其中使用比较多的就是pageHelper。pageHelper提供了针对Spring Boot框架的依赖库pagehelper-spring-boot-starter,对于Spring Boot项目可以使用pagehelper-spring-boot-starter组件。

首先添加pom文件依赖

        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.4.3</version>
        </dependency>

然后 在application.properties文件中对插件进行配置,当然也支持用注解的形式进行配置

pagehelper.helper-dialect=mysql
pagehelper.reasonable=true
pagehelper.support-methods-arguments=true
pagehelper.params=count=countSql

helper-dialect:指定要处理的数据库类型,目前高版本的pageHelper也可以不配置,pageHelper插件会自动检测数据库的类型。

reasonable:显示优化参数,默认为false,设置为true时,当pageNum≤0时,默认显示第一页,当pageNum超过pageSize时,显示最后一页。

support-methods-arguments:分页插件会根据查询方法的参数,自动在params配置的字段中取值,找到合适的值会自动分页。

params:用于从对象中根据属性名取值,可以配置pageNum、pageSize,count不用配置映射的默认值。

配置完毕,我们来编写测试函数

    @Test
    public void testSelectListPaged() {
        PageHelper.startPage(1, 2);
        List<User> users = userMapper.selectAllUser();
        PageInfo<User> pageInfo = new PageInfo<User>(users);
        System.out.println("总页数:"+pageInfo.getPages()+", 总条数:" +pageInfo.getTotal()+",当前页号:"+pageInfo.getPageNum() );
        for (User user : users) {
            System.out.println("name:" + user.getName()+", age: " + user.getAge());
        }
    }
}

执行测试程序

 说明插件生效了

项目源码

可以访问:GitHub - qwdzq/springboot: spring boot 入门

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈小房

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值