最近有个项目的数据库使用postgresql,使用原生态的mybatis操作数据,原生态的没什么不好,只不过国内有个tk.mybatis的工具帮助我们做了很多实用的事情,大多数情况下我们需要在原生态mybatis上加工的想法它基本上都已经有很好的实现,这篇将分享安装postgresql,配置tk.mybatis的详细步骤以及在这过程中可能遇到的一些小问题。

  • 安装postgresql,执行下面的命令就可以安装了:
apt-get update && apt-get install postgresql

服务端安装好之后我们还需要一个图形界面的客户端pdAdmin,我安装的是Windows版本的postgresql自带的,可以到这个地址找对应的版本。安装成功后默认会创建一个系统用户,一个数据库用户,名称以及密码都是postgres,我们可以新创建用户也可以直接使用这个帐号,反正我这只是测试。安装完成之后,可能会遇到远程访问问题:

远程连接问题,默认情况下只允许本地连接,要想允许其它客户端连接,我们可以修改它的配置文件,这个文件的目录位于/etc/postgresql/9.5/main,这个目录下有两个文件:
  1:postgresql.conf,这个是服务器相关,里面有一个listen_address的地址,默认只监听本地,我们可以修改它。


  2:pg_hba.cof,这个是用户权限相关,里面有一个与连接相关的配置,可以配置成网关模式

成功连接之后,大概是这个样子,我们可以创建数据库,表等对象。

  • mybatis代码生成器,数据库与Model的映射,这类机械的工作应该交给机器来完成,详细使用参考这里
  • 通用mapper,单表的CRUD操作可以抽像出一个公共接口,tk.mybatis提供的通用mapper可以帮助我们解决这类问题。
    • mapper.xml,足够小(只包含字段映射)
<mapper namespace="com.jim.logstashmvc.dao.generated.mapper.ProductMapper">
<resultMap id="BaseResultMap" type="com.jim.logstashmvc.dao.generated.entity.Product">
<!--
WARNING - @mbggenerated
-->
<id column="id" jdbcType="BIGINT" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
</resultMap>
</mapper>
    • mapper,足够简单(只需要继承通过mapper接口)
public interface ProductMapper extends Mapper<Product> {
}
  • 插件,这里有分页插件,SQL性能分析插件等,与mybatis集成非常容易。

如何与spring集成?

  • 生成器的集成,可以采用maven方式来运行代码生成器
    • 依赖的包
<!-- MyBatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency> <!-- Spring集成 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis.spring.version}</version>
</dependency> <!-- MBG -->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>${MBG.version}</version>
<scope>compile</scope>
<optional>true</optional>
</dependency> <!-- 分页 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>${pagehelper.version}</version>
</dependency> <!-- 通用Mapper -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>${mapper.version}</version>
</dependency> <!-- TkMybatis 会使用到JPA的注解 -->
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
</dependency> <dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.3-1102-jdbc41</version>
</dependency>
    • 配置生成器插件,指定配置文件路径,配置依赖:一个是数据库驱动,一个是通用mapper
<!--MBG-->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>${MBG.version}</version>
<configuration>
<configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile>
<overwrite>true</overwrite>
<verbose>true</verbose>
</configuration>
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.3-1102-jdbc41</version>
</dependency> <dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>${mapper.version}</version>
</dependency> </dependencies>
</plugin>
  • 生成器配置文件

    • 配置数据库连接
    • 配置生成的model,mapper以及mapper.xml的存放路径
    • 配置需要生成的表信息

注意下targetRuntime,这里采用的是MyBatis3Simple,它的默认选项是MyBatis3。如果采用通用mapper,我们在spring扫描接口时可以这样写。

 <bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="jimSqlSessionFactory"/>
<property name="basePackage" value="com.jim.logstashmvc.dao.generated.mapper"/>
</bean>

如果是MyBatis3,生成的mapper.xml格式会复杂很多,我之前遇到过这样的问题:使用MyBatis3生成的mapper.xml然后错误 的配置了MapperScannerConfigurer为下面通用mapper模式,提示我的错误如下,原因可以认定是配置问题(不是某个mapper.xml中的id重复问题) ,后续再研究下非通用mapper的配置。

Caused by: java.lang.IllegalArgumentException: Mapped Statements collection already contains value for com.jim.logstashmvc.dao.generated.mapper.ProductMapper.selectByExample
at org.apache.ibatis.session.Configuration$StrictMap.put(Configuration.java:837)
at org.apache.ibatis.session.Configuration$StrictMap.put(Configuration.java:809)

上面的报错信息已经找到,原因是因为采用了MyBatis3方式生成Mapper,但同时在配置文件中错误的增加了通用Mapper的插件,它会在Mapper接口上增加一个Mapper<T>的继承,而一旦继承了这个通过接口,它里面包含的方法Id与MyBatis3生成的方法Id正好重复,导致了在编译时提示上面的错误。

使用了通用Mapper之后,有个缺点就是使用Example时没有强类型的方法了,比如不能这样:

        ProductExample example =new ProductExample();
ProductExample.Criteria criteria=example.createCriteria();
if (product.getId() != null) {
criteria.andIdEqualTo(product.getId());
}

而只能这样写,字段名称需要以字符串的形式进行指定。这种方式非常适合于动态构建查询,比如:列表页的动态条件搜索

        Example example = new Example(Product.class);
Example.Criteria criteria = example.createCriteria();
if (product.getId() != null) {
criteria.andEqualTo("id", product.getId());
}

我们之前的项目为了能够使用动态条件构建,又想使用强类型的Example进行简单的查询,我们扩展了targetRuntime,让其生成的Mapper即继承自Map<T>又生成了具体的方法,只不过生成的具体方法在名称上做了调整,在名称中间增加了一个独有的占有符,默认MBG生成的查询方法名称是selectByExample,这里我们另外生成一个selectByConcreteExample。这样做也是有代价的,生成的mapper.xml也不再只包含实体映射,mapper接口也不再只是继承的近似空接口了,具体怎么用仁者见仁吧。

public interface ImageMapper extends PartyInterface, RowBoundsMapper<Image>, BaseMapper<Image>, ExampleMapper<Image> {
int countByConcreteExample(ImageExample example); int deleteByConcreteExample(ImageExample example); List<Image> selectByConcreteExample(ImageExample example); int updateByConcreteExampleSelective(@Param("record") Image record, @Param("example") ImageExample example); int updateByConcreteExample(@Param("record") Image record, @Param("example") ImageExample example);
}

生成器的配置详细如下:

<generatorConfiguration>
<properties resource="config.properties"/>
<context id="jim" targetRuntime="MyBatis3Simple" defaultModelType="flat">
<property name="beginningDelimiter" value="`"/>
<property name="endingDelimiter" value="`"/>
<plugin type="${mapper.plugin}">
<property name="mappers" value="${mapper.Mapper}"/>
</plugin>
<jdbcConnection driverClass="${jdbc.driverClass}"
connectionURL="${jdbc.url}"
userId="${jdbc.username}"
password="${jdbc.password}">
</jdbcConnection>
<javaModelGenerator targetPackage="${targetModelPackage}"
targetProject="${targetJavaProject}"/>
<sqlMapGenerator targetPackage="mapper" targetProject="${targetResourcesProject}"/>
<javaClientGenerator targetPackage="${targetMapperPackage}"
targetProject="${targetJavaProject}"
type="XMLMAPPER">
</javaClientGenerator>
<table tableName="product" domainObjectName="Product"></table>
</context>
</generatorConfiguration>
  • 配置maven运行参数,如下图所示即可。

  • mybatis的集成,主要是配置连接池信息,插件,mapper扫描等信息。
<bean id="jimDataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClass}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/> <property name="initialSize" value="5"/>
<property name="minIdle" value="10"/>
<property name="maxWait" value="60000"/>
<property name="timeBetweenEvictionRunsMillis" value="60000"/>
<property name="minEvictableIdleTimeMillis" value="3600000"/>
<property name="validationQuery" value="SELECT 1"/>
<property name="testWhileIdle" value="true"/>
<property name="testOnBorrow" value="false"/>
<property name="testOnReturn" value="false"/>
</bean> <bean id="jimSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="jimDataSource"/>
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
<property name="typeAliasesPackage" value="com.jim.logstashmvc.dao.generated.entity"/>
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageHelper">
<property name="properties">
<value>
dialect=postgresql
reasonable=true
supportMethodsArguments=true
returnPageInfo=check
params=count=countSql
</value> </property>
</bean>
</array>
</property> </bean> <bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="jimSqlSessionFactory"/>
<property name="basePackage" value="com.jim.logstashmvc.dao.generated.mapper"/>
</bean>
  • 通用mapper的用法:

    • mapper,所有生成的mapper就继承于Mapper<T>,默认持有通用mapper所有接口,包含CRUD常见操作
    • IService,通用mapper接口的定义,我们可以根据自己的业务修改此接口
@Service
public interface IService<T> { T selectByKey(Object key); int save(T entity); int delete(Object key); int updateAll(T entity); int updateNotNull(T entity); List<T> selectByExample(Object example); //TODO 其他...
}
    • BaseService,通用mapper的实现类
public abstract class BaseService<T> implements IService<T> {

    @Autowired
protected Mapper<T> mapper; public Mapper<T> getMapper() {
return mapper;
} @Override
public T selectByKey(Object key) {
return mapper.selectByPrimaryKey(key);
} public int save(T entity) {
return mapper.insert(entity);
} public int delete(Object key) {
return mapper.deleteByPrimaryKey(key);
} public int updateAll(T entity) {
return mapper.updateByPrimaryKey(entity);
} public int updateNotNull(T entity) {
return mapper.updateByPrimaryKeySelective(entity);
} public List<T> selectByExample(Object example) {
return mapper.selectByExample(example);
} //TODO 其他...
}
    • 具体服务类
@Service
public class ProductServiceImpl extends BaseService<Product> implements ProductService {
@Override
public List<Product> selectByProduct(Product product, int page, int rows) {
Example example = new Example(Product.class);
Example.Criteria criteria = example.createCriteria();
if(!StringUtils.isBlank(product.getName())){
criteria.andEqualTo("name",product.getName());
}
if (product.getId() != null) {
criteria.andEqualTo("id", product.getId());
}
PageHelper.startPage(page, rows);
return selectByExample(example); } }

安装postgresql并且成功远程连接,集成MBG生成mapper以及model,然后将mybatis与spring集成,最后通过通用mapper中联起来就达到了我们的目的:通过少量的代码完成大部分的工作,重复劳动交给工具完成。但通用mapper有它的优点也就有它的缺点,需要根据项目环境来平衡,个人感觉利大于弊。

本文引用:
   1:http://www.mybatis.tk/
   2:https://github.com/abel533/Mybatis-Spring

从头开始搭建一个mybatis+postgresql平台的更多相关文章

  1. 从头开始搭建一个dubbo+zookeeper平台

    本篇主要是来分享从头开始搭建一个dubbo+zookeeper平台的过程,其中会简要介绍下dubbo服务的作用. 首先,看下一般网站架构随着业务的发展,逻辑越来越复杂,数据量越来越大,交互越来越多之后 ...

  2. 搭建一个dubbo+zookeeper平台

    本篇主要是来分享从头开始搭建一个dubbo+zookeeper平台的过程,其中会简要介绍下dubbo服务的作用. 首先,看下一般网站架构随着业务的发展,逻辑越来越复杂,数据量越来越大,交互越来越多之后 ...

  3. mybatis+postgresql平台

    mybatis+postgresql平台        最近有个项目的数据库使用postgresql,使用原生态的mybatis操作数据,原生态的没什么不好,只不过国内有个tk.mybatis的工具帮 ...

  4. 如何基于Go搭建一个大数据平台

    如何基于Go搭建一个大数据平台 - Go中国 - CSDN博客 https://blog.csdn.net/ra681t58cjxsgckj31/article/details/78333775 01 ...

  5. Mybaits 源码解析 (一)----- 搭建一个mybatis框架(MyBatis HelloWorld)

    源码分析之前先搭一个mybatis的demo,这个在看源码的时候能起到了很大的作用,因为在看源码的时候,会恍然大悟,为什么要这么配置,为什么要这么写.(老鸟可以跳过这篇) 开发环境的准备 创建mave ...

  6. 从头开始搭建一个Spring boot+RabbitMQ环境

    *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...

  7. 从头开始搭建一个Spring boot+ActiveMQ高可用分布式环境

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  8. 从头开始搭建一个VSCode+NetCore的项目

    看这个前,先要对VS开发C#有所了解 获取作案工具 NetCore SDK https://www.microsoft.com/net/learn/get-started/windows 安装 建立工 ...

  9. 部署LAMP环境搭建一个网站论坛平台

    修改主机名 Hostname openstack-001 Hostname Login 修改本地域名解析 Vi /etc/hosts 最后一行添加 192.168.1.56 openstack-001 ...

随机推荐

  1. 《第一本docker书》—— 读后总结

    关于docker 这本书其实并没有读完,只不过最近工作比较繁忙,也无心再看这些用不到的书.以后要是工作需要,再仔细学习吧. 这次的阅读算是达到目的了,对docker有了一定的了解.它的作用.意义以及大 ...

  2. KnockoutJS 3.X API 第六章 组件(2) 组件注册

    要使Knockout能够加载和实例化组件,必须使用ko.components.register注册它们,从而提供如此处所述的配置. 注意:作为替代,可以实现一个自定义组件加载器(自定义加载器下一节介绍 ...

  3. java 成长之路

    分享总结 title: java 成长之路 tags: grammar_cjkRuby: true 经验差异 1-3年 要求 建议 3-5年 建议 5年+ 经验差异 最近一年比较忙,经历了创业公司的倒 ...

  4. WaitType:SOS_SCHEDULER_YIELD

    今天遇到一个query,处于SOS_SCHEDULER_YIELD 状态,physical IO 不增加,CPU的使用一直在增长.当一个sql query长时间处于SOS_SCHEDULER_YIEL ...

  5. Sql Server系列:数据库对象

    数据库对象是数据库的组成部分,数据表.视图.索引.存储过程以及触发器等都是数据库对象. 数据库的主要对象是数据表,数据表是一系列二维数组的集合,用于存储各种信息. 视图表面上看与表几乎一样,具有一组命 ...

  6. (App.Current.RootVisual as PhoneApplicationFrame).Navigate(new Uri("/MainPage.xaml", UriKind.Relative));

    (App.Current.RootVisual as PhoneApplicationFrame).Navigate(new Uri("/MainPage.xaml", UriKi ...

  7. Vue.js学习笔记(2)vue-router

    vue中vue-router的使用:

  8. Create Volume 操作(Part I) - 每天5分钟玩转 OpenStack(50)

    前面已经学习了 Cinder 的架构和相关组件,从本节我们开始详细分析 Cinder 的各种操作,首先讨论 Cinder 如何创建 volume. Create 操作流程如下: 客户(可以是 Open ...

  9. java.util.NoSuchElementException: Timeout waiting for idle object

    出现这个问题第一个想法就是连接池的参数设置问题,把最大连接数量设置大一些就行了,但是我就一个客服端访问服务器,连接池连接数量不可能会不够用.我的项目架构是spring mvc+hibernate,用s ...

  10. 哪些HTML5特性值得期待

    首先大家可以看一下<HTML5程序设计(第二版)>最后一章关于HTML5未来展望.地址:http://www.ituring.com.cn/article/1690?q=html5%E6% ...