前言

之前写了《SpringBoot | 第九章:Mybatis-plus的集成和使用》一文,只是简单的使用条件构造器列举了一些通用的CURD操作。本人也想写一篇通用的关于mybatis-plus的使用示例,一方面也让自己更加了解mybatismybatis-plus,另一方面,也因为很多新人刚入职公司时,对这块不是很熟悉,会有一些疑惑。所以,总的来说还是作为一份资产,可供人查阅,这样也能减少了很多的沟通成本。


所以本章节,就主要来讲解下关于Mybatis-plus的不同场景的用法,目前主要想到的是以下几个知识点,也是很常用的知识点了,后面有补充的会再启章节来记录的。另外,官网的文档已经很详尽了,大家可认真查阅下。

  1. 代码生成器
  2. 通用的CURD
  3. 条件构造器
  4. 自定义SQL语句
  5. 分页插件、性能分析插件
  6. 公共字段自动填充

工程准备

这里还是以user表为例子,数据库为mysql

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` bigint(20) DEFAULT NULL COMMENT '唯一标示',
`code` varchar(20) DEFAULT NULL COMMENT '编码',
`name` varchar(64) DEFAULT NULL COMMENT '名称',
`status` char(1) DEFAULT '1' COMMENT '状态 1启用 0 停用',
`gmt_create` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

关于SpringBootMybatis-plus的集成,这里就不阐述了,这个不是今天的重点。不熟悉的同学,可移步:http://blog.lqdev.cn/2018/07/21/springboot/chapter-nine/进行查看了解。

代码生成器

Mybatis-Plus已经提供了大量的自定义设置,生成的代码完全能够满足各类型的需求,基本覆盖了大部分的配置了。这里贴一个比较完整的代码生成器类,大家可根据实际情况进行修改。

MysqlGenerator.java:

//省略了import
public class MysqlGenerator { /**
* 包名
*/
private static final String PACKAGE_NAME = "cn.lqdev.learning.mybatisplus.samples";
/**
* 模块名称
*/
private static final String MODULE_NAME = "biz";
/**
* 输出文件的路径
*/
private static final String OUT_PATH = "D:\\develop\\code";
/**
* 代码生成者
*/
private static final String AUTHOR = "oKong"; /**
* JDBC相关配置
*/
private static final String DRIVER = "com.mysql.jdbc.Driver";
private static final String URL = "jdbc:mysql://127.0.0.1:3306/learning?useUnicode=true&characterEncoding=UTF-8";
private static final String USER_NAME = "root";
private static final String PASSWORD = "bs"; /**
* <p>
* MySQL 生成演示
* </p>
*/
public static void main(String[] args) {
// 自定义需要填充的字段
List<TableFill> tableFillList = new ArrayList<TableFill>();
//如 每张表都有一个创建时间、修改时间
//而且这基本上就是通用的了,新增时,创建时间和修改时间同时修改
//修改时,修改时间会修改,
//虽然像Mysql数据库有自动更新几只,但像ORACLE的数据库就没有了,
//使用公共字段填充功能,就可以实现,自动按场景更新了。
//如下是配置
TableFill createField = new TableFill("gmt_create", FieldFill.INSERT);
TableFill modifiedField = new TableFill("gmt_modified", FieldFill.INSERT_UPDATE);
tableFillList.add(createField);
tableFillList.add(modifiedField); // 代码生成器
AutoGenerator mpg = new AutoGenerator().setGlobalConfig(
// 全局配置
new GlobalConfig().setOutputDir(OUT_PATH)// 输出目录
.setFileOverride(true)// 是否覆盖文件
.setActiveRecord(true)// 开启 activeRecord 模式
.setEnableCache(false)// XML 二级缓存
.setBaseResultMap(false)// XML ResultMap
.setBaseColumnList(true)// XML columList
.setAuthor(AUTHOR)
// 自定义文件命名,注意 %s 会自动填充表实体属性!
.setXmlName("%sMapper").setMapperName("%sDao")
// .setServiceName("MP%sService")
// .setServiceImplName("%sServiceDiy")
// .setControllerName("%sAction")
).setDataSource(
// 数据源配置
new DataSourceConfig().setDbType(DbType.MYSQL)// 数据库类型
.setTypeConvert(new MySqlTypeConvert() {
// 自定义数据库表字段类型转换【可选】
@Override
public DbColumnType processTypeConvert(String fieldType) {
System.out.println("转换类型:" + fieldType);
// if ( fieldType.toLowerCase().contains( "tinyint" ) ) {
// return DbColumnType.BOOLEAN;
// }
return super.processTypeConvert(fieldType);
}
}).setDriverName(DRIVER).setUsername(USER_NAME).setPassword(PASSWORD).setUrl(URL))
.setStrategy(
// 策略配置
new StrategyConfig()
// .setCapitalMode(true)// 全局大写命名
.setDbColumnUnderline(true)// 全局下划线命名
// .setTablePrefix(new String[]{"unionpay_"})// 此处可以修改为您的表前缀
.setNaming(NamingStrategy.underline_to_camel)// 表名生成策略
// .setInclude(new String[] {"user"}) // 需要生成的表
// .setExclude(new String[]{"test"}) // 排除生成的表
// 自定义实体,公共字段
// .setSuperEntityColumns(new String[]{"test_id"})
.setTableFillList(tableFillList)
// 自定义实体父类
// .setSuperEntityClass("com.baomidou.demo.base.BsBaseEntity")
// // 自定义 mapper 父类
// .setSuperMapperClass("com.baomidou.demo.base.BsBaseMapper")
// // 自定义 service 父类
// .setSuperServiceClass("com.baomidou.demo.base.BsBaseService")
// // 自定义 service 实现类父类
// .setSuperServiceImplClass("com.baomidou.demo.base.BsBaseServiceImpl")
// 自定义 controller 父类
// .setSuperControllerClass("com.baomidou.demo.TestController")
// 【实体】是否生成字段常量(默认 false)
// public static final String ID = "test_id";
.setEntityColumnConstant(true)
// 【实体】是否为构建者模型(默认 false)
// public User setName(String name) {this.name = name; return this;}
.setEntityBuilderModel(true)
// 【实体】是否为lombok模型(默认 false)<a href="https://projectlombok.org/">document</a>
.setEntityLombokModel(true)
// Boolean类型字段是否移除is前缀处理
// .setEntityBooleanColumnRemoveIsPrefix(true)
// .setRestControllerStyle(true)
// .setControllerMappingHyphenStyle(true)
).setPackageInfo(
// 包配置
new PackageConfig().setModuleName(MODULE_NAME).setParent(PACKAGE_NAME)// 自定义包路径
.setController("controller")// 这里是控制器包名,默认 web
.setXml("mapper").setMapper("dao") ).setCfg(
// 注入自定义配置,可以在 VM 中使用 cfg.abc 设置的值
new InjectionConfig() {
@Override
public void initMap() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp");
this.setMap(map);
}
}.setFileOutConfigList(
Collections.<FileOutConfig>singletonList(new FileOutConfig("/templates/mapper.xml.vm") {
// 自定义输出文件目录
@Override
public String outputFile(TableInfo tableInfo) {
return OUT_PATH + "/xml/" + tableInfo.getEntityName() + "Mapper.xml";
}
})))
.setTemplate(
// 关闭默认 xml 生成,调整生成 至 根目录
new TemplateConfig().setXml(null)
// 自定义模板配置,模板可以参考源码 /mybatis-plus/src/main/resources/template 使用 copy
// 至您项目 src/main/resources/template 目录下,模板名称也可自定义如下配置:
// .setController("...");
// .setEntity("...");
// .setMapper("...");
// .setXml("...");
// .setService("...");
// .setServiceImpl("...");
); // 执行生成
mpg.execute();
} }

按以上代码生成器,生成的目录结构如下(依赖中需要加入velocity-engine-core包,是利用模版引擎来生成的)

对应mapper.xml

对于需要自定义模版时,大家可查看官方的mybatis-plus-generate包,默认的官方模版都放在此包下。

有了代码生成器,省了很多机械性的复制黏贴操作,还不会出错,写错了再执行一次就好了!

通用的CURD

MP提供了ActiveRecord的支持,所以实体类只需继承 Model 类即可实现基本 CRUD 操作。

这里以编写测试类的形式,进行通用CURD操作,代码类有相应的注释说明。

GeneralTest.java:

/**
* 通用CURD示例
* @author oKong
*
*/
@RunWith(SpringRunner.class)
//SpringBootTest 是springboot 用于测试的注解,可指定启动类或者测试环境等,这里直接默认。
@SpringBootTest
@Slf4j
public class GeneralTest { @Autowired
IUserService userService; @Test
public void testInsert() {
User user = new User();
user.setCode("001");
user.setName("okong-insert");
//默认的插入策略为:FieldStrategy.NOT_NULL,即:判断 null
//对应在mapper.xml时写法为:<if test="field!=null">
//这个可以修改的,设置字段的@TableField(strategy=FieldStrategy.NOT_EMPTY)
//所以这个时候,为null的字段是不会更新的,也可以开启性能插件,查看sql语句就可以知道
userService.insert(user); //新增所有字段,
userService.insertAllColumn(user);
log.info("新增结束");
} @Test
public void testUpdate() { User user = new User();
user.setCode("101");
user.setName("oKong-insert");
//这就是ActiveRecord的功能
user.insert();
//也可以直接 userService.insert(user); //更新
User updUser = new User();
updUser.setId(user.getId());
updUser.setName("okong-upd"); updUser.updateById();
log.info("更新结束");
} @Test
public void testDelete() {
User user = new User();
user.setCode("101");
user.setName("oKong-delete"); user.insert(); //删除
user.deleteById();
log.info("删除结束"); } @Test
public void testSelect() {
User user = new User();
user.setCode("201");
user.setName("oKong-selecdt"); user.insert(); log.info("查询:{}",user.selectById());
}
}

以上就列举了常用的,官方提供了很多的通用方法:

注意控制台的sql输出,对比下就知道各方法之间的区别了。


对于通用代码如何注入的,可查看com.baomidou.mybatisplus.mapper.AutoSqlInjector类,这个就是注入通用的CURD方法的类。


条件构造器

在通用的CURD无法满足时,这个时候 强大的条件构造器就排上用场了。主要提供了实体包装器,用于处理 sql 拼接,排序,实体参数查询等!

这里需要注意:使用的是数据库字段,不是Java属性!,原来使用另一款通用mapper时记得使用的是JAVA属性。

sql条件拼接

这也是条件构造器最灵活的地方了。

ConditionTest.java

@RunWith(SpringRunner.class)
//SpringBootTest 是springboot 用于测试的注解,可指定启动类或者测试环境等,这里直接默认。
@SpringBootTest
@Slf4j
public class ConditionTest { @Autowired
IUserService userService; @Test
public void testOne() {
User user = new User();
user.setCode("701");
user.setName("okong-condition");
user.insert(); EntityWrapper<User> qryWrapper = new EntityWrapper<>(); qryWrapper.eq(User.CODE, user.getCode());
qryWrapper.eq(User.NAME, user.getName()); //也可以直接
// qryWrapper.setEntity(user); //打印sql语句
System.out.println(qryWrapper.getSqlSegment()); //设置select 字段 即:select code,name from
qryWrapper.setSqlSelect(User.CODE,User.NAME);
System.out.println(qryWrapper.getSqlSelect()); //查询
User qryUser = userService.selectOne(qryWrapper);
System.out.println(qryUser);
log.info("拼接一结束");
} @Test
public void testTwo() {
User user = new User();
user.setCode("702");
user.setName("okong-condition");
user.insert(); EntityWrapper<User> qryWrapper = new EntityWrapper<>();
qryWrapper.where("code = {0}", user.getCode())
.and("name = {0}",user.getName())
.andNew("status = 0");
System.out.println(qryWrapper.getSqlSegment());
//等等很复杂的。
//复杂的建议直接写在xml里面了,要是非动态的话 比较xml一眼看得懂呀
//查询
User qryUser = userService.selectOne(qryWrapper);
System.out.println(qryUser);
log.info("拼接二结束");
} }

com.baomidou.mybatisplus.mapper.Wrapper<T>类还有很多的方法,大家可以试试。

条件参数说明

查询方式 说明
setSqlSelect 设置 SELECT 查询字段
where WHERE 语句,拼接 + WHERE 条件
and AND 语句,拼接 + AND 字段=值
andNew AND 语句,拼接 + AND (字段=值)
or OR 语句,拼接 + OR 字段=值
orNew OR 语句,拼接 + OR (字段=值)
eq 等于=
allEq 基于 map 内容等于=
ne 不等于<>
gt 大于>
ge 大于等于>=
lt 小于<
le 小于等于<=
like 模糊查询 LIKE
notLike 模糊查询 NOT LIKE
in IN 查询
notIn NOT IN 查询
isNull NULL 值查询
isNotNull IS NOT NULL
groupBy 分组 GROUP BY
having HAVING 关键词
orderBy 排序 ORDER BY
orderAsc ASC 排序 ORDER BY
orderDesc DESC 排序 ORDER BY
exists EXISTS 条件语句
notExists NOT EXISTS 条件语句
between BETWEEN 条件语句
notBetween NOT BETWEEN 条件语句
addFilter 自由拼接 SQL
last 拼接在最后,例如:last("LIMIT 1")

自定义SQL使用条件构造器

UserDao.java加入接口方法:

/**
*
* @param rowBounds 分页对象 直接传入page即可
* @param wrapper 条件构造器
* @return
*/
List<User> selectUserWrapper(RowBounds rowBounds, @Param("ew") Wrapper<User> wrapper);

UserMapper.xml加入对应的xml节点:

    <!-- 条件构造器形式 -->
<select id="selectUserWrapper" resultType="user">
SELECT
<include refid="Base_Column_List" />
FROM USER
<where>
${ew.sqlSegment}
</where>
</select>

测试类:

@Test
public void testCustomSql() {
User user = new User();
user.setCode("703");
user.setName("okong-condition");
user.insert(); EntityWrapper<User> qryWrapper = new EntityWrapper<>();
qryWrapper.eq(User.CODE, user.getCode()); Page<User> pageUser = new Page<>();
pageUser.setCurrent(1);
pageUser.setSize(10); List<User> userlist = userDao.selectUserWrapper(pageUser, qryWrapper);
System.out.println(userlist.get(0));
log.info("自定义sql结束");
}

xml形式使用wrapper

UserDao.java

/**
*
* @param rowBounds 分页对象 直接传入page即可
* @param wrapper 条件构造器
* @return
*/
List<User> selectUserWrapper(RowBounds rowBounds, @Param("ew") Wrapper<User> wrapper);

对应的UserMapper.xml:


<!-- 条件构造器形式 -->
<select id="selectUserWrapper" resultType="user">
SELECT
<include refid="Base_Column_List" />
FROM USER
<where>
${ew.sqlSegment}
</where>
</select>

自定义SQL语句

在一些需要多表关联时,条件构造器和通用CURD都无法满足时,还可以自行手写sql语句进行扩展。注意:这都是mybatis的用法。

以下两种方式都是改造UserDao接口。

注解形式

@Select("SELECT * FROM USER WHERE CODE = #{userCode}")
List<User> selectUserCustomParamsByAnno(@Param("userCode")String userCode);

xml形式

List<User> selectUserCustomParamsByXml(@Param("userCode")String userCode);

同时,UserMapper.xml新增一个节点:

    <!-- 由于设置了别名:typeAliasesPackage=cn.lqdev.learning.mybatisplus.samples.biz.entity,所以resultType可以不写全路径了。 -->
<select id="selectUserCustomParamsByXml" resultType="user">
SELECT
<include refid="Base_Column_List"/>
FROM USER
WHERE CODE = #{userCode}
</select>

测试类CustomSqlTest.java

@RunWith(SpringRunner.class)
//SpringBootTest 是springboot 用于测试的注解,可指定启动类或者测试环境等,这里直接默认。
@SpringBootTest
@Slf4j
public class CustomSqlTest { @Autowired
UserDao userDao; @Test
public void testCustomAnno() {
User user = new User();
user.setCode("901");
user.setName("okong-sql");
user.insert();
List<User> userlist = userDao.selectUserCustomParamsByAnno(user.getCode());
//由于新增的 肯定不为null 故不判断了。
System.out.println(userlist.get(0).toString());
log.info("注解形式结束------");
} @Test
public void testCustomXml() {
User user = new User();
user.setCode("902");
user.setName("okong-sql");
user.insert();
List<User> userlist = userDao.selectUserCustomParamsByXml(user.getCode());
//由于新增的 肯定不为null 故不判断了。
System.out.println(userlist.get(0).toString());
log.info("xml形式结束------");
} }

注意事项

在使用spring-boot-maven-plugin插件打包成springboot运行jar时,需要注意下,由于springboot的jar扫描路径方式问题,会导致别名的包未扫描到,所以这个只需要把mybatis默认的扫描设置为SpringbootVFS实现。

直接修改spring-mybatis.xml文件:

  <!--mybatis-->
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!-- 自动扫描mapper.xml文件,支持通配符 -->
<property name="mapperLocations" value="classpath:mapper/**/*.xml"/>
<!-- 配置文件,比如参数配置(是否启动驼峰等)、插件配置等 -->
<property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/>
<!-- 启用别名,这样就无需写全路径类名了,具体可自行查阅资料 -->
<property name="typeAliasesPackage" value="cn.lqdev.learning.mybatisplus.samples.biz.entity"/>
<!-- MP 全局配置注入 -->
<property name="globalConfig" ref="globalConfig"/>
<!-- 设置vfs实现,避免路径扫描问题 -->
<property name="vfs" value="com.baomidou.mybatisplus.spring.boot.starter.SpringBootVFS"></property>
</bean>

分页插件、性能分析插件

mybatis的插件机制使用起来是很简单的,只需要注册即可。

mybatis-config.xml

    <plugins>
<!-- SQL 执行性能分析,开发环境使用,线上不推荐。 -->
<plugin interceptor="com.baomidou.mybatisplus.plugins.PerformanceInterceptor"></plugin>
<!-- 分页插件配置 -->
<plugin interceptor="com.baomidou.mybatisplus.plugins.PaginationInterceptor"></plugin>
</plugins>

分页测试类(性能分析,配置后可以输出sql及取数时间):

@RunWith(SpringRunner.class)
//SpringBootTest 是springboot 用于测试的注解,可指定启动类或者测试环境等,这里直接默认。
@SpringBootTest
@Slf4j
public class PluginTest { @Autowired
IUserService userService; @Test
public void testPagination() {
Page<User> page = new Page<>();
//每页数
page.setSize(10);
//当前页码
page.setCurrent(1); //无条件时
Page<User> pageList = userService.selectPage(page);
System.out.println(pageList.getRecords().get(0)); //新增数据 避免查询不到数据
User user = new User();
user.setCode("801");
user.setName("okong-Pagination");
user.insert();
//加入条件构造器
EntityWrapper<User> qryWapper = new EntityWrapper<>();
//这里也能直接设置 entity 这是条件就是entity的非空字段值了
// qryWapper.setEntity(user);
//这里建议直接用 常量
// qryWapper.eq(User.CODE, user.getCode());
pageList = userService.selectPage(page, qryWapper);
System.out.println(pageList.getRecords().get(0));
log.info("分页结束");
} }

性能插件体现,控制台输出:

 Time:4 ms - ID:cn.lqdev.learning.mybatisplus.samples.biz.dao.UserDao.selectPage
Execute SQL: SELECT id AS id,code,`name`,`status`,gmt_create AS gmtCreate,gmt_modified AS gmtModified FROM user WHERE id=1026120705692434433 AND code='801' AND `name`='okong-Pagination' LIMIT 0,10

公共字段自动填充

通常,每个公司都有自己的表定义,在《阿里巴巴_Java_开发手册》中,就强制规定表必备三字段:id, gmt_create, gmt_modified。所以通常我们都会写个公共的拦截器去实现自动填充比如创建时间和更新时间的,无需开发人员手动设置。而在MP中就提供了这么一个公共字段自动填充功能

设置填充字段的填充类型

User.java

    /**
* 创建时间
*/
@TableField(fill=FieldFill.INSERT)
private Date gmtCreate;
/**
* 修改时间
*/
@TableField(fill=FieldFill.INSERT_UPDATE)
private Date gmtModified;

注意这里是可以在代码生成器里面配置规则的,可自动配置,详见代码生成器类。

定义处理类

MybatisObjectHandler.java

public class MybatisObjectHandler extends MetaObjectHandler{

    @Override
public void insertFill(MetaObject metaObject) {
//新增时填充的字段
setFieldValByName("gmtCreate", new Date(), metaObject);
setFieldValByName("gmtModified", new Date(), metaObject); } @Override
public void updateFill(MetaObject metaObject) {
//更新时 需要填充字段
setFieldValByName("gmtModified", new Date(), metaObject);
}
}

同时修改springb-mybatis.xml文件,加入此配置:

    <bean id="globalConfig" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
<!--
AUTO->`0`("数据库ID自增")QW
INPUT->`1`(用户输入ID")
ID_WORKER->`2`("全局唯一ID")
UUID->`3`("全局唯一ID")
-->
<property name="idType" value="2" />
<property name="metaObjectHandler" ref="mybatisObjectHandler"></property>
</bean> <bean id="mybatisObjectHandler" class="cn.lqdev.learning.mybatisplus.samples.config.MybatisObjectHandler"/>

这个时候再新增或者修改,对应时间就会进行更新了。

 Time:31 ms - ID:cn.lqdev.learning.mybatisplus.samples.biz.dao.UserDao.insert
Execute SQL: INSERT INTO user ( id, code, `name`, gmt_create,gmt_modified ) VALUES ( 1026135016838037506, '702', 'okong-condition', '2018-08-05 23:57:07.344','2018-08-05 23:57:07.344' )

相关资料

  1. MP官网:http://mp.baomidou.com

总结

本文主要列举了开发过程中常用的操作数据库的方法及相关配置。应该可以应付百分之八十以上的需求了吧。之后有时间,会进行补充的,比如自定义插件、大批量数据的写法等。

最后

若文中有错误或者遗漏之处,还望指出,共同进步!

老生常谈

  • 个人QQ:499452441
  • 微信公众号:lqdevOps

个人博客:http://blog.lqdev.cn

完整示例:https://gitee.com/oKong/mybatis-plus-samples

原文地址:http://blog.lqdev.cn/2018/08/06/%E6%97%A5%E5%B8%B8%E7%A7%AF%E7%B4%AF/mybatis-plus-guide-one/

Mybatis-Plus使用全解的更多相关文章

  1. Mybatis系列全解(八):Mybatis的9大动态SQL标签你知道几个?提前致女神!

    封面:洛小汐 作者:潘潘 2021年,仰望天空,脚踏实地. 这算是春节后首篇 Mybatis 文了~ 跨了个年感觉写了有半个世纪 ... 借着女神节 ヾ(◍°∇°◍)ノ゙ 提前祝男神女神们越靓越富越嗨 ...

  2. Mybatis系列全解(七):全息视角看Dao层两种实现方式之传统方式与代理方式

    封面:洛小汐 作者:潘潘 一直以来 他们都说为了生活 便追求所谓成功 顶级薪水.名牌包包 还有学区房 · 不过 总有人丢了生活 仍一无所获 · 我比较随遇而安 有些事懒得明白 平日里问心无愧 感兴趣的 ...

  3. Mybatis系列全解(六):Mybatis最硬核的API你知道几个?

    封面:洛小汐 作者:潘潘 2020 年的大疫情,把世界撕成几片. 时至今日,依旧人心惶惶. 很庆幸,身处这安稳国, 兼得一份安稳工. · 东家常讲的一个词:深秋心态 . 大势时,不跟风.起哄, 萧条时 ...

  4. Mybatis系列全解(五):全网最全!详解Mybatis的Mapper映射文件

    封面:洛小汐 作者:潘潘 若不是生活所迫,谁愿意背负一身才华. 前言 上节我们介绍了 < Mybatis系列全解(四):全网最全!Mybatis配置文件 XML 全貌详解 >,内容很详细( ...

  5. Mybatis系列全解(四):全网最全!Mybatis配置文件XML全貌详解

    封面:洛小汐 作者:潘潘 做大事和做小事的难度是一样的.两者都会消耗你的时间和精力,所以如果决心做事,就要做大事,要确保你的梦想值得追求,未来的收获可以配得上你的努力. 前言 上一篇文章 <My ...

  6. Mybatis系列全解(三):Mybatis简单CRUD使用介绍

    封面:洛小汐 作者:潘潘 在理解中执行,在执行中理解,学习技术也循此道. 前言 上一篇文章 <Mybatis系列全解(二):Mybatis简介与环境搭建> ,我们对 Mybatis 做了初 ...

  7. Mybatis系列全解(二):Mybatis简介与环境搭建

    封面:洛小汐 作者:潘潘 Mybatis 是一套持久层框架,灵活易用,特别流行. 前言 Mybatis系列全解,我们预计准备10+篇文章,让我们了解到 Mybatis 的基本全貌,真正从入门到上手,从 ...

  8. mybatis代码生成器配置文件详解

    mybatis代码生成器配置文件详解 更多详见 http://generator.sturgeon.mopaas.com/index.html http://generator.sturgeon.mo ...

  9. Springboot整合log4j2日志全解

    目录 常用日志框架 日志门面slf4j 为什么选用log4j2 整合步骤 引入Jar包 配置文件 配置文件模版 配置参数简介 Log4j2配置详解 简单使用 使用lombok工具简化创建Logger类 ...

  10. Mybatis案例超详解(上)

    Mybatis案例超详解(上) 前言: 本来是想像之前一样继续跟新Mybatis,但由于种种原因,迟迟没有更新,快开学了,学了一个暑假,博客也更新了不少,我觉得我得缓缓,先整合一些案例练练,等我再成熟 ...

随机推荐

  1. 十二:JAVA I/O

     输入模式                                                          输出模式 ⑴字节输入流:InputStream ⑵字节输出流:Output ...

  2. 数组排序----Demo

    //选择排序,分为简单选择排序.树形选择排序(锦标赛排序).堆排序 此算法为简单选择排序 public static void selectSort(int[] a){ for(int i=0;i&l ...

  3. Python命令模块argparse学习笔记(四)

    默认参数 ArgumentParser.set_defaults(**kwargs) set_defaults()可以设置一些参数的默认值 >>> parser = argparse ...

  4. redis持久化  发布消息与订阅

    vi /usr/local/redis/etc/redis.conf  快照方式:     save 900 1     save 300 10     save 60 10000 aof方式: ap ...

  5. free查看内存情况

    free命令可以显示当前系统未使用的和已使用的内存数目,还可以显示被内核使用的内存缓冲区. free [option]     -b:以Byte为单位显示内存使用情况:      -k:以KB为单位显 ...

  6. [hdu4734]F(x)数位dp

    题意:求0~f(b)中,有几个小于等于 f(a)的. 解题关键:数位dp #include<bits/stdc++.h> using namespace std; typedef long ...

  7. Struts2学习第三课 访问Web资源

    1.什么是WEB资源? HttpServletRequest,HttpSession,ServletContext等原生的Servlet API. 2.为什么访问WEB资源? B/S的应用的Contr ...

  8. TCP三次握手四次挥手原理

    转自http://www.cnblogs.com/liuxiaoming/archive/2013/04/27/3047803.html TCP协议三次握手原理: 首先,给张图片,建立TCP三次握手的 ...

  9. 【转】‘svn’不是内部或外部命令,也不是可运行的程序

    解决方法:windows安装svn的时候默认是不安装 svn command line这个东西的,重新打开svn的安装exe,选择modify,将“command line client tools” ...

  10. [CentOS7] ssh免密登录 scp免密传输

    我们采用RSA非对称加密算法,原理: 如果,A要和B通讯,则: (1). A通过RSA算法生成公钥(.pub)和私钥(公钥用于加密,私钥用于解密) (2). B将A的公钥文件(.pub)内容加入到au ...