zoukankan      html  css  js  c++  java
  • 从头开始搭建一个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


  • 相关阅读:
    [20190415]10g下那些latch是共享的.txt
    [20190415]11g下那些latch是共享的.txt
    [20190409]pre_page_sga=true与连接缓慢的问题.txt
    [20190402]Library Cache mutex.txt
    scrapy简单使用方法
    PHP多进程系列笔(转)
    RdKafka文档翻译
    python判断字符串中是否包含子字符串
    python 逐行读取txt文件
    redis使用watch完成秒杀抢购功能(转)
  • 原文地址:https://www.cnblogs.com/ASPNET2008/p/5657027.html
Copyright © 2011-2022 走看看