下载APP
登录
关闭
讲堂
算法训练营
Python 进阶训练营
企业服务
极客商城
客户端下载
兑换中心
渠道合作
推荐作者
当前播放: 20 | 通过MyBatis操作数据库
00:00 / 00:00
标清
  • 标清
1.0x
  • 2.0x
  • 1.5x
  • 1.25x
  • 1.0x
  • 0.5x
网页全屏
全屏
00:00
付费课程,可试看

玩转Spring全家桶

共123讲 · 123课时,1300分钟
24721
免费
01 | Spring课程介绍
免费
02 | 一起认识Spring家族的主要...
免费
03 | 跟着Spring了解技术趋势
免费
04 | 编写你的第一个Spring程序
免费
05 | 如何配置单数据源
免费
06 | 如何配置多数据源
07 | 那些好用的连接池们:Hika...
08 | 那些好用的连接池们:Alib...
09 | 如何通过Spring JDBC访问...
10 | 什么是Spring的事务抽象(...
11 | 什么是Spring的事务抽象(...
免费
12 | 了解Spring的JDBC异常抽象
13 | 课程答疑(上)
14 | 课程答疑(下)
15 | 认识Spring Data JPA
16 | 定义JPA的实体对象
17 | 开始我们的线上咖啡馆实战...
18 | 通过Spring Data JPA操...
19 | Spring Data JPA的Repos...
20 | 通过MyBatis操作数据库
21 | 让MyBatis更好用的那些工...
22 | 让MyBatis更好用的那些工...
23 | SpringBucks实战项目进度...
24 | 通过Docker辅助开发
25 | 在Spring中访问MongoDB
26 | 在Spring中访问Redis
27 | Redis的哨兵与集群模式
28 | 了解Spring的缓存抽象
29 | Redis在Spring中的其他用...
30 | SpringBucks实战项目进度...
31 | Project Reactor介绍(上...
32 | Project Reactor介绍(下...
33 | 通过Reactive的方式访问Re...
34 | 通过Reactive的方式访问Mo...
35 | 通过Reactive的方式访问RD...
36 | 通过AOP打印数据访问层的...
37 | 通过AOP打印数据访问层的...
38 | SpringBucks实战项目进度...
39 | 编写第一个Spring MVC C...
40 | 理解Spring的应用上下文
41 | 理解请求的处理机制
42 | 如何定义处理方法(上)
43 | 如何定义处理方法(下)
44 | Spring MVC中的视图解析...
45 | Spring MVC中的视图解析...
46 | Spring MVC中的常用视图...
47 | Spring MVC中的常用视图...
48 | 静态资源与缓存
49 | Spring MVC中的异常处理...
50 | 了解Spring MVC的切入点
51 | SpringBucks实战项目进度...
52 | 课程答疑
53 | 通过RestTemplate访问Web...
54 | RestTemplate的高阶用法
55 | 简单定制RestTemplate
56 | 通过WebClient访问Web资源
57 | SpringBucks实战项目进度...
58 | 设计好的RESTful Web Se...
59 | 设计好的RESTful Web Se...
60 | 什么是HATEOAS
61 | 使用Spring Data REST实...
62 | 使用Spring Data REST实...
63 | 分布式环境中如何解决Sess...
64 | 使用WebFlux代替Spring M...
65 | 使用WebFlux代替Spring M...
66 | SpringBucks实战项目进度...
67 | 认识Spring Boot的组成部...
68 | 了解自动配置的实现原理
69 | 动手实现自己的自动配置
70 | 如何在低版本Spring中快速...
71 | 了解起步依赖及其实现原理
72 | 定制自己的起步依赖
73 | 深挖Spring Boot的配置加...
74 | 理解配置背后的PropertyS...
75 | 认识Spring Boot的各类Ac...
76 | 动手定制自己的Health In...
77 | 通过Micrometer获取运行数...
78 | 通过Spring Boot Admin...
79 | 如何定制Web容器的运行参...
80 | 如何配置容器支持HTTP/2...
81 | 如何配置容器支持HTTP/2...
82 | 如何编写命令行运行的程序
83 | 了解可执行Jar背后的秘密
84 | 如何将Spring Boot应用打...
85 | SpringBucks实战项目进度...
86 | 简单理解微服务
87 | 如何理解云原生(Cloud N...
88 | 12-Factor App(上)
89 | 12-Factor App(下)
90 | 认识Spring Cloud的组成...
91 | 使用Eureka作为服务注册中...
92 | 使用Spring Cloud Loadb...
93 | 使用Feign访问服务
94 | 深入理解服务发现背后的Di...
95 | 使用Zookeeper作为服务注...
96 | 使用Consul作为服务注册中...
97 | 使用Nacos作为服务注册中...
98 | 如何定制自己的Discovery...
99 | SpringBucks实战项目进度...
100 | 使用Hystrix实现服务熔...
101 | 使用Hystrix实现服务熔...
102 | 如何观察服务熔断
103 | 使用Resilience4j实现服...
104 | 使用Resilience4j实现服...
105 | 使用Resilience4j实现服...
106 | SpringBucks实战项目进度...
107 | 基于Git的配置中心(上)
108 | 基于Git的配置中心(下)
109 | 基于Zookeeper的配置中心
110 | 深入理解Spring Cloud的...
111 | 基于Consul的配置中心
112 | 基于Nacos的配置中心
113 | SpringBucks实战项目进度...
114 | 认识Spring Cloud Stre...
115 | 通过Spring Cloud Stre...
116 | 通过Spring Cloud Stre...
117 | SpringBucks实战项目进度...
118 | 通过Dapper理解链路治理
119 | 使用Spring Cloud Sleu...
120 | 如何追踪消息链路
121 | 除了链路还要治理什么
122 | SpringBucks实战项目进度...
123 | 结束语
本节摘要

PDF 课件和源代码下载地址:

https://github.com/geektime-geekbang/geektime-spring-family

猜你喜欢

unpreviewunpreview

展开

精选留言(45)

  • 2019-05-04
    在CoffeeMapper.save(Coffee c) 方法的Options 注解需要添加keyColumn="id", keyProperty="id". 才会在插入后自动注入Coffee 的id
    1
    12
  • 2019-02-23
    使用Mybaits不能像jpa一样通过打注解来自动建表吗?
    2
    6
  • 2019-05-12
    mybatis 2.0.1版本Mapper要这样配置 @Options(useGeneratedKeys = true, keyProperty = "id") ,插入时才能自动填充id
    5
  • 2019-02-23
    回复Francis_Lee:

    可以在mapping映射文件中如下定义,userColumns和userJoins就是可以重用的了:

     <sql id="userColumns">
            a.id,
            a.company_id AS "company.id",
            a.office_id AS "office.id",
            a.login_name,
            a.password,
            a.name,
            c.name AS "company.name",
            c.parent_id AS "company.parent.id",
            c.parent_ids AS "company.parentIds",
            ca.id AS "company.area.id",
            ca.name AS "company.area.name",
            ca.parent_id AS "company.area.parent.id",
            ca.parent_ids AS "company.area.parentIds",
            o.name AS "office.name",
            o.parent_id AS "office.parent.id",
            o.parent_ids AS "office.parentIds",
            oa.id AS "office.area.id",
            oa.name AS "office.area.name",
            oa.parent_id AS "office.area.parent.id",
            oa.parent_ids AS "office.area.parentIds",
            cu.id AS "company.primaryPerson.id",
            cu.name AS "company.primaryPerson.name",
            cu2.id AS "company.deputyPerson.id",
            cu2.name AS "company.deputyPerson.name",
            ou.id AS "office.primaryPerson.id",
            ou.name AS "office.primaryPerson.name",
            ou2.id AS "office.deputyPerson.id",
            ou2.name AS "office.deputyPerson.name"
        </sql>
        
        <sql id="userJoins">
            LEFT JOIN sys_office c ON c.id = a.company_id
            LEFT JOIN sys_area ca ON ca.id = c.area_id
            LEFT JOIN sys_office o ON o.id = a.office_id
        </sql>
        
        <select id="get" resultType="User">
            SELECT
                <include refid="userColumns"/>
            FROM sys_user a
            <include refid="userJoins"/>
            WHERE a.id = #{id}
        </select>

    官方解释:

    sql 这个元素可以被用来定义可重用的 SQL 代码段,可以包含在其他语句中。它可以被静态地(在加载参数) 参数化. 不同的属性值通过包含的实例变化.
    展开

    作者回复: 就希望看到同学们互相帮助,互相成长,我也会跟着大家一起学习。

    5
  • 2019-03-04
    老师,我这一直报找不到mapper,但是我比对了好几遍,注解路径都没错,网上说的也不清楚,您知道怎么解决吗?
    1
    4
  • 2019-02-23
    mybatis麻烦的地方在于inser,update里要把所有字段都写一遍,有没有好的方式,能够在mybatis里面像jpa那样操作实体?

    作者回复: 后面会讲到MyBatis Generator,都帮你生成了。

    4
  • 2019-03-29
    老师,useGeneratedKeys = true
    应该就是指定生成的主键回填到入参的coffee的id中吧,我验证了一下,我用的是mysql8,在没指定keyProperty="id",keyColumn="id"时,貌似也不会回填,不知道是不是数据库的问题呢,还是因为我用了druid的数据源?
    然后那个save方法的返回值,应该不是id吧,而是操作的记录数,所以我看到有同学评论一直放回1,我也验证过,应该是数量吧,update和delete时返回参数Long对应也是记录操作数?
    是这样吗?
    展开

    作者回复: 你好,感谢你的提醒。我也去翻了下MyBatis的文档,这里的确是我把Insert的返回搞错了。
    根据官方文档和我自己的验证,@Insert返回的是变动记录的条数,int也是可以的。我知道Update和Delete返回的是条数,但平时不太关心Insert的结果,结果这里就弄错了。
    我已经重新写了示例代码,也重新录制了本节相关内容,极客时间的同学在制作完之后会更新上去。
    再次感谢你能指出我的问题:-)

    3
  • 2019-04-17
    save方法不能返回整个对象吗?这样会带上id

    作者回复: MyBatis的这个save()方法可以回填id到传入的对象里的, @Options里useGeneratedKeys=true,再设置keyProperty 和 keyColumn 。

    2
  • 2019-02-25
    看过丁老师翻译的两本书:《Spring Boot实战》《MongoDB实战》
    2
  • 2019-11-21
    老师,mybatis的缓存机制用得多吗?我没看到课程有提起到,是用的比较少吗?

    作者回复: 从我遇到的情况来看,似乎是比较少,一般我们会用JVM内部缓存或者Redis缓存更多一点。MyBatis更多的还是ORM操作数据库,数据取出来之后,怎么做缓存是我们来处理的,而非让MyBatis来处理。

    1
  • 丁老师,请教一下,为啥我的接口没有添加@Mapper注解,接口也实例化了,能够执行

    public interface UserMapper {
        
        @Select("select * from user_info where id = #{id}")
        User getUserById(@Param("id") int id);
    }

    @PropertySource(value = {"classpath:config/db.properties"})
    @Configuration
    public class MyBatisConfig {
        
        @Value("${jdbc.driver}")
        private String driver;
        @Value("${jdbc.url}")
        private String url;
        @Value("${jdbc.username}")
        private String username;
        @Value("${jdbc.password}")
        private String password;
        
        @Bean
        public DriverManagerDataSource dataSource() {
            DriverManagerDataSource dataSource = new DriverManagerDataSource();
            dataSource.setDriverClassName(driver);
            dataSource.setUrl(url);
            dataSource.setUsername(username);
            dataSource.setPassword(password);
            return dataSource;
        }
        
        @Bean
        public SqlSessionFactory sqlSessionFactory() throws Exception {
            SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
            factoryBean.setDataSource(dataSource());
            return factoryBean.getObject();
        }
        
        @Bean
        public MapperFactoryBean<UserMapper> userMapper() throws Exception {
            MapperFactoryBean<UserMapper> factoryBean = new MapperFactoryBean<>(UserMapper.class);
            factoryBean.setSqlSessionFactory(sqlSessionFactory());
            return factoryBean;
        }

    }

    @ContextConfiguration(classes = {MyBatisConfig.class})
    @Slf4j
    public class UserTest extends AbstractTestNGSpringContextTests {
        
        @Resource
        private UserMapper userMapper;
        
        @Test(description = "测试MyBatis")
        public void myBatisTest() {
            log.info(userMapper.getUserById(1).toString());
        }
    }
    展开

    作者回复: 因为你配置了MapperFactoryBean<UserMapper>,这个Bean会帮你返回一个UserMapper的

    1
    1
  • 2019-11-05
    对于金额,使用JDK自带的BigDecimal不是更好吗?也不需要多引入一个JAR包,而且对精度的处理也非常好。

    作者回复: BigDecimal只是处理精度而已,对于货币而言,还有货币种类、货币单位、货币转换等很多东西需要考虑的。比如元转分,分转元这些Money都提供了支持。

    1
    1
  • 2019-05-26

    针对intellij IDE private CoffeeMapper coffeeMapper 报红警告的问题 安装mybatis-plugin插件就好了。葱同学的禁用警告有点风险。
    2
    1
  • 2019-05-12
    mybatis 版本配置为1.3.2时可以正常的插入,版本配置为2.0.1后插入时没有自动填充id跟时间;
    1
  • 2019-05-10
    老师你好,请问一下,
    1.项目运行报了java.lang.IllegalStateException: Type handler was null on parameter mapping for property 'price'. It was either not specified and/or could not be found for the javaType (org.joda.money.Money) : jdbcType (null) combination.
    我在网上查找了说应该在typehandler加上javatype和jdbctype,但是加了还是报错,请问这是为什么呢?
    2.Mapper没有注入进来,但是MapperScann已经配置了
    具体代码:
    (1)MybatisDemoApplication .java
    @SpringBootApplication
    @Slf4j
    @MapperScan("ack.mybatisdemo.mapper")
    public class MybatisDemoApplication implements ApplicationRunner {

        @Autowired
        private CoffeeMapper coffeeMapper;

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

        @Override
        public void run(ApplicationArguments args) throws Exception {
            Coffee c = Coffee.builder().name("espresso")
                    .price(Money.of(CurrencyUnit.of("CNY"), 20.0)).build();
            int count = coffeeMapper.insert(c);//返回存入条数
            log.info("save coffee-count:{}",count);
            Coffee coffee1 = coffeeMapper.findById(c.getId());
            log.info("coffee,{}",coffee1.toString());
        }
    }
    (2)handler上面加了
    @MappedJdbcTypes(value = JdbcType.BIGINT,includeNullJdbcType = true)
    @MappedTypes(Money.class)
    (3)mapper类
    ack.mybatisdemo.mapper.CoffeeMapper
    展开

    作者回复: 你是不是在application.proeprties里没有配置mybatis.type-handlers-package,让MyBatis到指定包里去找Handler,我们的MoneyTypeHandler你可以看看,也很简单。建议完整比对一下我们Github上的Chapter 3/mybatis-demo

    1
  • 2019-03-20
    Mapper 报红只需要在Inspections(点击红色💡->Inspection "Autowiring for Bean Class" options->edit inspection profile setting)里面找到spring->spring core->code->Autowiring for Bean Class的Serverity由Error改成Warining就可以了。 实际上是有这个bean的.....
    1
  • 2019-03-19
    师傅领进门,修行在个人.老师讲的内容,起到给我拓展知识面的作用,提升我的广度.但是深度还得靠自己.
    JPA自己去官网看看手册.结合老师的例子,希望能有提升.
     https://docs.spring.io/spring-data/jpa/docs/2.1.5.RELEASE/reference/html/

    当然,作为小白,也希望老师能讲的细一点 :-) ,很多内容希望不要默认我会啊,简单提一下啊,也许会让我醍醐灌顶..
    1
  • 2019-03-07
    想再请教两个问题,
    1,实体的listener的问题,老师能不能讲一下。就是对实体的增删改的listener。
    2,个人在接触了SpringDataJpa和MyBatis之后,深感Jpa的便利程度,而且Jpa也是支持手写Sql的,既然如此,为什么还要用MyBatis呢?直接用Jpa+jpa对手写Sql的支持不就好了嘛。

    作者回复: 上面那个问题,我们课程应该不会涉及,只能靠你自己查了。
    下面那个问题,JPA在处理简单的情况下相对便利一些,但到了复杂的情况下,对SQL的定制多了,就和MyBatis差不多了。一些公司里DBA会对SQL做很多优化,需要对SQL有一定的把控度,这时JPA自动生成的SQL对这些优化并不友好,既然都要手写了,那还不如用MyBatis了。

    1
  • 2019-02-23
    mybatis 有很多开源的增强比如:
    tk.mapper https://github.com/abel533/Mapper
    mybatis-plus https://mp.baomidou.com/
    1
  • 2019-02-23
    MyBatis-Spring-Boot-Starter 会自动扫描带有@Mapper注解的映射器,所以可以不用在MybatisDemoApplication类上添加@MapperScan注解,也可以实现相同效果。除非Mapper接口上未添加@Mapper注解,就需要添加@MapperScan在MybatisDemoApplication类上进行扫描了。

    作者回复: 你说的这个逻辑在MybatisAutoConfiguration中,另外,@MapperScan还可以指定要扫描的package。

    1