mybatis+postgresql平台

      

最近有个项目的数据库使用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. 从头开始搭建一个mybatis+postgresql平台

         最近有个项目的数据库使用postgresql,使用原生态的mybatis操作数据,原生态的没什么不好,只不过国内有个tk.mybatis的工具帮助我们做了很多实用的事情,大多数情况下我们需要 ...

  2. Spring+mybatis+postgresql整合

    最近做了一个项目,需要使用Spring+mybatis+postgresql,下面记录一下整合步骤: 一.准备JAR包: 我使用的是maven,所以直接晒出pom.xml <project xm ...

  3. mybatis postgresql insert后返回自增id

    在使用mybatis + postgresql,我们有时在插入数据时需要返回自增id的值,此时在插入时,可以按照以下例子来编写mapper文件 <insert id="insertUs ...

  4. mybatis电子商务平台b2b2c

    技术解决方案 开发语言: java.j2ee 数据库:mysql JDK支持版本: JDK1.6.JDK1.7.JDK1.8版本 核心技术:分布式.云服务.微服务.服务编排等. 核心架构: 使用Spr ...

  5. mybatis postgresql 批量删除

    一.需求介绍 前端是一个列表页面,列表可以进行复选框的选择,后台进行关联表数据的删除. 二.框架介绍 springboot+mybatis 数据库用的postgresql 三.具体代码(前端js) 1 ...

  6. Spring Boot + MyBatis + PostgreSql

    Maven构建项目 1.访问http://start.spring.io/ 2.选择构建工具Maven Project.Spring Boot版本1.3.6以及一些工程基本信息,点击“Switch t ...

  7. mybatis + postgresql 遇到的问题

    org.postgresql.util.PSQLException: ERROR: relation "circlefence" does not exist  这个问题是数据库表 ...

  8. Postgresql中string转换成timestamp类型

    Mybatis+Postgresql TO_DATE(#{startTime}, 'YYYY-MM-DD') AND op_date <![CDATA[>= ]]>  TO_TIME ...

  9. MyBatis 与 Spring 整合

    MyBatis-Spring 项目 目前大部分的 Java 互联网项目,都是用 Spring MVC + Spring + MyBatis 搭建平台的. 使用 Spring IoC 可以有效的管理各类 ...

随机推荐

  1. 二、获取AccessToken

    二.获取AccessToken 1.官方文档: access_token是微信官方公众号调用接口的全局唯一票据,开发者调用任何接口都需要使用access_token,由于access_token有效期 ...

  2. api文档生成工具 C#

    要为编写的程序编写文档,这是件费力气的事,如果能自动生成就好了. 不怕做不到,就怕想不到.这不,搜索到了Sandcastle 比较好的参考文章: 1.Sandcastle官方网址: http://sh ...

  3. Winform中上传、下载文件选择打开文件的位置

    打开将要上传的文件 var fileName="";OpenFileDialog fileDialog = new OpenFileDialog(); fileDialog.Mul ...

  4. [C#参考]锁定lock

    Lock关键字解释: lock 关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁. 下面的示例包含一个 lock 语句. lock 关键字可确保当一个线程位于代码的临界区 ...

  5. IO流操作-图片操作(二)

    一:Stream和Byte的含义 Stream:流,一般指文件流,内存流,可读的流和可写的流等,是一种数据转换的格式,流在计算机里可以表示为流输入或输出的一个连续的字节序列,它在使用完后,需要把资源释 ...

  6. Django Web开发【2】Django入门

    配置开发环境 1.安装Python,我使用的是centos 6.0,python版本为2.6.6 2.安装Django,Django版本为1.3.5 在Django官网下载对应版本之后,解压压缩包,进 ...

  7. 编程习题——Maximum Subarray

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  8. 普通内存、ECC内存和REG ECC内存有什么不同

    都知道,在INTEL平台,北桥负责与CPU的联系,并控制内存.AGP.PCI数据在北桥内部传输.基本上只要主板芯片组确定,那么其支持的内存类型也就确定了. INTEL芯片组划分的很清楚,865PE属于 ...

  9. java MemCachedClient遍历memcache中所有的key

    在java memcached client documentation中没有提共遍历memcache所有key的方法.但是提供了两个方法statsItems和statsCacheDump,通过sta ...

  10. ZOJ Monthly, March 2013

    A题 题目大意:给出一棵树,一开始节点值均为0,先要求完成在线操作:将某子树所有节点值取反,或者查询某子树总点权. 题解:很基础的线段树题,既然两个操作都是子树操作,那么就先树链剖分一下,将子树操作转 ...