<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.joda</groupId>
<artifactId>joda-money</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
create table t_coffee (
id bigint not null auto_increment,
name varchar(255),
price bigint not null,
create_time timestamp,
update_time timestamp,
primary key (id)
);
mybatis.type-handlers-package=me.zhongmingmao.mybatis.handler mybatis.configuration.map-underscore-to-camel-case=true
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Coffee {
private Long id;
private String name;
private Money price;
private Date createTime;
private Date updateTime;
}
package me.zhongmingmao.mybatis.handler;
/**
* 在 Money 与 Long 之间转换的 TypeHandler,处理 CNY 人民币
*/
public class MoneyTypeHandler extends BaseTypeHandler<Money> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Money parameter, JdbcType jdbcType) throws SQLException {
ps.setLong(i, parameter.getAmountMinorLong());
}
@Override
public Money getNullableResult(ResultSet rs, String columnName) throws SQLException {
return parseMoney(rs.getLong(columnName));
}
@Override
public Money getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return parseMoney(rs.getLong(columnIndex));
}
@Override
public Money getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return parseMoney(cs.getLong(columnIndex));
}
private Money parseMoney(Long value) {
// return Money.ofMinor(CurrencyUnit.of("CNY"), value);
return Money.of(CurrencyUnit.of("CNY"), value / 100.0);
}
}
package me.zhongmingmao.mybatis.mapper;
@Mapper
public interface CoffeeMapper {
@Insert("insert into t_coffee (name, price, create_time, update_time) values (#{name}, #{price}, now(), now())")
@Options(useGeneratedKeys = true)
int save(Coffee coffee);
@Select("select * from t_coffee where id = #{id}")
@Results({
@Result(id = true, column = "id", property = "id"),
@Result(column = "create_time", property = "createTime"),
// map-underscore-to-camel-case = true 可以实现一样的效果
// @Result(column = "update_time", property = "updateTime"),
})
Coffee findById(@Param("id") Long id);
}
@Slf4j
@MapperScan("me.zhongmingmao.mybatis.mapper")
@SpringBootApplication
public class MybatisApplication implements ApplicationRunner {
@Autowired
private CoffeeMapper coffeeMapper;
public static void main(String[] args) {
SpringApplication.run(MybatisApplication.class, args);
}
@Override
public void run(ApplicationArguments args) throws Exception {
Coffee coffee = Coffee.builder().name("espresso").price(Money.of(CurrencyUnit.of("CNY"), 20.0)).build();
int count = coffeeMapper.save(coffee);
log.info("Save {} Coffee: {}", count, coffee);
coffee = Coffee.builder().name("latte").price(Money.of(CurrencyUnit.of("CNY"), 25.0)).build();
count = coffeeMapper.save(coffee);
log.info("Save {} Coffee: {}", count, coffee);
coffee = coffeeMapper.findById(coffee.getId());
log.info("Find Coffee: {}", coffee);
}
}
Save 1 Coffee: Coffee(id=1, name=espresso, price=CNY 20.00, createTime=null, updateTime=null) Save 1 Coffee: Coffee(id=2, name=latte, price=CNY 25.00, createTime=null, updateTime=null) Find Coffee: Coffee(id=2, name=latte, price=CNY 25.00, createTime=Sun Sep 15 13:50:32 CST 2019, updateTime=Sun Sep 15 13:50:32 CST 2019)
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.7</version>
</dependency>
<dependency>
<groupId>org.joda</groupId>
<artifactId>joda-money</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<generatorConfiguration>
<context id="H2Tables" targetRuntime="MyBatis3">
<plugin type="org.mybatis.generator.plugins.FluentBuilderMethodsPlugin"/>
<plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>
<plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>
<plugin type="org.mybatis.generator.plugins.RowBoundsPlugin"/>
<jdbcConnection driverClass="org.h2.Driver"
connectionURL="jdbc:h2:mem:testdb"
userId="sa"
password="">
</jdbcConnection>
<javaModelGenerator targetPackage="me.zhongmingmao.mybatis.generator.model"
targetProject="./src/main/java">
<property name="enableSubPackages" value="true"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<sqlMapGenerator targetPackage="me.zhongmingmao.mybatis.generator.mapper"
targetProject="./src/main/resources/mapper">
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>
<!-- 混合模式 -->
<javaClientGenerator type="MIXEDMAPPER"
targetPackage="me.zhongmingmao.mybatis.generator.mapper"
targetProject="./src/main/java">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator>
<table tableName="t_coffee" domainObjectName="Coffee">
<generatedKey column="id" sqlStatement="CALL IDENTITY()" identity="true"/>
<columnOverride column="price" javaType="org.joda.money.Money" jdbcType="BIGINT"
typeHandler="me.zhongmingmao.mybatis.generator.handler.MoneyTypeHandler"/>
</table>
</context>
</generatorConfiguration>
src/main
├── java
│ └── me
│ └── zhongmingmao
│ └── mybatis
│ └── generator
│ ├── MybatisGeneratorApplication.java
│ └── handler
│ └── MoneyTypeHandler.java
└── resources
├── application.properties
├── generatorConfig.xml
├── mapper
└── schema.sql
List<String> warnings = new ArrayList<>();
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(getClass().getResourceAsStream("/generatorConfig.xml"));
DefaultShellCallback callback = new DefaultShellCallback(true);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
src/main
├── java
│ └── me
│ └── zhongmingmao
│ └── mybatis
│ └── generator
│ ├── MybatisGeneratorApplication.java
│ ├── handler
│ │ └── MoneyTypeHandler.java
│ ├── mapper
│ │ └── CoffeeMapper.java
│ └── model
│ ├── Coffee.java
│ └── CoffeeExample.java
└── resources
├── application.properties
├── generatorConfig.xml
├── mapper
│ └── me
│ └── zhongmingmao
│ └── mybatis
│ └── generator
│ └── mapper
│ └── CoffeeMapper.xml
└── schema.sql
mybatis.mapper-locations=classpath*:/mapper/**/*.xml mybatis.type-aliases-package=me.zhongmingmao.mybatis.generator.model mybatis.type-handlers-package=me.zhongmingmao.mybatis.generator.handler mybatis.configuration.map-underscore-to-camel-case=true
Coffee espresso = new Coffee()
.withName("espresso")
.withPrice(Money.of(CurrencyUnit.of("CNY"), 20.0))
.withCreateTime(new Date())
.withUpdateTime(new Date());
coffeeMapper.insert(espresso);
Coffee latte = new Coffee()
.withName("latte")
.withPrice(Money.of(CurrencyUnit.of("CNY"), 30.0))
.withCreateTime(new Date())
.withUpdateTime(new Date());
coffeeMapper.insert(latte);
// 简单查询
Coffee s = coffeeMapper.selectByPrimaryKey(1L);
log.info("Coffee {}", s);
// 复杂查询
CoffeeExample example = new CoffeeExample();
example.createCriteria().andNameEqualTo("latte");
example.setOrderByClause("id desc");
List<Coffee> list = coffeeMapper.selectByExample(example);
list.forEach(e -> log.info("selectByExample: {}", e));
Coffee Coffee [Hash = 981159997, id=1, name=espresso, price=CNY 20.00, createTime=Sun Sep 15 15:32:52 CST 2019, updateTime=Sun Sep 15 15:32:52 CST 2019] selectByExample: Coffee [Hash = 653345773, id=2, name=latte, price=CNY 30.00, createTime=Sun Sep 15 15:32:52 CST 2019, updateTime=Sun Sep 15 15:32:52 CST 2019]
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.12</version>
</dependency>
<dependency>
<groupId>org.joda</groupId>
<artifactId>joda-money</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
insert into t_coffee (name, price, create_time, update_time) values ('espresso', 2000, now(), now());
insert into t_coffee (name, price, create_time, update_time) values ('latte', 2500, now(), now());
insert into t_coffee (name, price, create_time, update_time) values ('capuccino', 2500, now(), now());
insert into t_coffee (name, price, create_time, update_time) values ('mocha', 3000, now(), now());
insert into t_coffee (name, price, create_time, update_time) values ('macchiato', 3000, now(), now());
@Mapper
public interface CoffeeMapper {
@Select("select * from t_coffee order by id")
List<Coffee> findAllWithRowBounds(RowBounds rowBounds);
@Select("select * from t_coffee order by id")
List<Coffee> findAllWithParam(@Param("pageNum") int pageNum, @Param("pageSize") int pageSize);
}
# mybatis mybatis.type-handlers-package=me.zhongmingmao.mybatis.pagehelper.handler mybatis.configuration.map-underscore-to-camel-case=true # pagehelper pagehelper.offset-as-page-num=true pagehelper.reasonable=true pagehelper.page-size-zero=true pagehelper.support-methods-arguments=true
coffeeMapper.findAllWithRowBounds(new RowBounds(1, 3))
.forEach(coffee -> log.info("Page(1) Coffee {}", coffee));
coffeeMapper.findAllWithRowBounds(new RowBounds(2, 3))
.forEach(coffee -> log.info("Page(2) Coffee {}", coffee));
log.info("==============");
// 获取所有记录
coffeeMapper.findAllWithRowBounds(new RowBounds(1, 0))
.forEach(coffee -> log.info("Page(1) Coffee {}", coffee));
coffeeMapper.findAllWithParam(1, 3)
.forEach(coffee -> log.info("Page(1) Coffee {}", coffee));
List<Coffee> list = coffeeMapper.findAllWithParam(2, 3);
PageInfo<Coffee> pageInfo = new PageInfo<>(list);
log.info("PageInfo: {}", pageInfo);
Page(1) Coffee Coffee(id=1, name=espresso, price=CNY 20.00, createTime=Sun Sep 15 16:12:50 CST 2019, updateTime=Sun Sep 15 16:12:50 CST 2019)
Page(1) Coffee Coffee(id=2, name=latte, price=CNY 25.00, createTime=Sun Sep 15 16:12:50 CST 2019, updateTime=Sun Sep 15 16:12:50 CST 2019)
Page(1) Coffee Coffee(id=3, name=capuccino, price=CNY 25.00, createTime=Sun Sep 15 16:12:50 CST 2019, updateTime=Sun Sep 15 16:12:50 CST 2019)
Page(2) Coffee Coffee(id=4, name=mocha, price=CNY 30.00, createTime=Sun Sep 15 16:12:50 CST 2019, updateTime=Sun Sep 15 16:12:50 CST 2019)
Page(2) Coffee Coffee(id=5, name=macchiato, price=CNY 30.00, createTime=Sun Sep 15 16:12:50 CST 2019, updateTime=Sun Sep 15 16:12:50 CST 2019)
==============
Page(1) Coffee Coffee(id=1, name=espresso, price=CNY 20.00, createTime=Sun Sep 15 16:12:50 CST 2019, updateTime=Sun Sep 15 16:12:50 CST 2019)
Page(1) Coffee Coffee(id=2, name=latte, price=CNY 25.00, createTime=Sun Sep 15 16:12:50 CST 2019, updateTime=Sun Sep 15 16:12:50 CST 2019)
Page(1) Coffee Coffee(id=3, name=capuccino, price=CNY 25.00, createTime=Sun Sep 15 16:12:50 CST 2019, updateTime=Sun Sep 15 16:12:50 CST 2019)
Page(1) Coffee Coffee(id=4, name=mocha, price=CNY 30.00, createTime=Sun Sep 15 16:12:50 CST 2019, updateTime=Sun Sep 15 16:12:50 CST 2019)
Page(1) Coffee Coffee(id=5, name=macchiato, price=CNY 30.00, createTime=Sun Sep 15 16:12:50 CST 2019, updateTime=Sun Sep 15 16:12:50 CST 2019)
Page(1) Coffee Coffee(id=1, name=espresso, price=CNY 20.00, createTime=Sun Sep 15 16:12:50 CST 2019, updateTime=Sun Sep 15 16:12:50 CST 2019)
Page(1) Coffee Coffee(id=2, name=latte, price=CNY 25.00, createTime=Sun Sep 15 16:12:50 CST 2019, updateTime=Sun Sep 15 16:12:50 CST 2019)
Page(1) Coffee Coffee(id=3, name=capuccino, price=CNY 25.00, createTime=Sun Sep 15 16:12:50 CST 2019, updateTime=Sun Sep 15 16:12:50 CST 2019)
PageInfo: PageInfo{pageNum=2, pageSize=3, size=2, startRow=4, endRow=5, total=5, pages=2, list=Page{count=true, pageNum=2, pageSize=3, startRow=3, endRow=6, total=5, pages=2, reasonable=true, pageSizeZero=true}[Coffee(id=4, name=mocha, price=CNY 30.00, createTime=Sun Sep 15 16:12:50 CST 2019, updateTime=Sun Sep 15 16:12:50 CST 2019), Coffee(id=5, name=macchiato, price=CNY 30.00, createTime=Sun Sep 15 16:12:50 CST 2019, updateTime=Sun Sep 15 16:12:50 CST 2019)], prePage=1, nextPage=0, isFirstPage=false, isLastPage=true, hasPreviousPage=true, hasNextPage=false, navigatePages=8, navigateFirstPage=1, navigateLastPage=2, navigatepageNums=[1, 2]}