從頭開始搭建一個mybatis+postgresql平台

來源:互聯網
上載者:User

標籤:

最近有個項目的資料庫使用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.selectByExampleat 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介面的定義,我們可以根據自己的業務修改此介面
@Servicepublic 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 其他...}
    • 具體服務類
@Servicepublic 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

http://www.cnblogs.com/ASPNET2008/p/5657027.html

 

從頭開始搭建一個mybatis+postgresql平台

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.