# Ubuntu/Debian apt-get update && apt-get install postgresql postgresql-contrib # 啟動服務 systemctl start postgresql systemctl enable postgresql
推薦 pgAdmin 4(官方自帶)或 DBeaver(通用)。默認超級用戶:postgres/postgres。
# 1. postgresql.conf - 監聽地址 listen_addresses = '*' # 默認 localhost,改為 * 監聽所有網卡 # 2. pg_hba.conf - 客戶端認證 # TYPE DATABASE USER ADDRESS METHOD host all all 0.0.0.0/0 md5 # 允許所有 IP 密碼登錄 # 或限制網段 host all all 192.168.1.0/24 md5
修改後 systemctl restart postgresql。
| 組件 | Maven 坐標 | 作用 |
|---|---|---|
| MyBatis 核心 | org.mybatis:mybatis | SQL 映射框架 |
| Spring 整合 | org.mybatis:mybatis-spring | SqlSessionFactoryBean、MapperScannerConfigurer |
| 代碼生成器 | org.mybatis.generator:mybatis-generator-core | DB → Entity/Mapper/XML |
| 通用 Mapper | tk.mybatis:mapper | 單表 CRUD 接口複用 |
| 分頁插件 | com.github.pagehelper:pagehelper | 物理分頁攔截 |
| PostgreSQL 驅動 | org.postgresql:postgresql | JDBC 驅動 |
<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>42.2.5</version></dependency>
<dependency><groupId>tk.mybatis</groupId><artifactId>mapper</artifactId><version>${mapper.version}</version></dependency>
</dependencies>
</plugin>
<generatorConfiguration>
<properties resource="config.properties"/>
<context id="pg" targetRuntime="MyBatis3Simple" defaultModelType="flat">
<property name="beginningDelimiter" value="\""/>
<property name="endingDelimiter" value="\""/>
<!-- tk.mybatis 通用 Mapper 插件 -->
<plugin type="tk.mybatis.mapper.generator.MapperPlugin">
<property name="mappers" value="tk.mybatis.mapper.common.Mapper"/>
<property name="caseSensitive" value="true"/>
</plugin>
<jdbcConnection driverClass="${jdbc.driverClass}"
connectionURL="${jdbc.url}"
userId="${jdbc.username}"
password="${jdbc.password}"/>
<javaModelGenerator targetPackage="${model.package}" targetProject="${java.project}"/>
<sqlMapGenerator targetPackage="mapper" targetProject="${resources.project}"/>
<javaClientGenerator targetPackage="${mapper.package}" targetProject="${java.project}" type="XMLMAPPER"/>
<table tableName="product" domainObjectName="Product">
<generatedKey column="id" sqlStatement="postgresql" identity="true"/>
</table>
</context>
</generatorConfiguration>
targetRuntime="MyBatis3Simple":生成極簡 Mapper(僅 CRUD),配合通用 Mapper 使用,**避免與 MyBatis3 生成的 Example 方法衝突**beginningDelimiter="\""generatedKey:PostgreSQL 串列主鍵回寫@Table(name = "product")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
// getter/setter
}
public interface ProductMapper extends Mapper{ // 繼承 insert、deleteByPrimaryKey、updateByPrimaryKey、selectByPrimaryKey、selectAll、selectByExample 等 }
<mapper namespace="com.demo.mapper.ProductMapper">
<resultMap id="BaseResultMap" type="com.demo.entity.Product">
<id column="id" property="id" jdbcType="BIGINT"/>
<result column="name" property="name" jdbcType="VARCHAR"/>
</resultMap>
</mapper>
<!-- 數據源 -->
<bean id="dataSource" class="org.apache.commons.dbcp2.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="maxTotal" value="20"/>
<property name="validationQuery" value="SELECT 1"/>
<property name="testWhileIdle" value="true"/>
</bean>
<!-- SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
<property name="typeAliasesPackage" value="com.demo.entity"/>
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageHelper">
<property name="properties">
<value>
helperDialect=postgresql
reasonable=true
supportMethodsArguments=true
params=count=countSql
</value>
</property>
</bean>
</array>
</property>
</bean>
<!-- Mapper 掃描 -->
<bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<property name="basePackage" value="com.demo.mapper"/>
</bean>
public interface IService{ T selectByKey(Object key); int save(T entity); int delete(Object key); int updateAll(T entity); int updateNotNull(T entity); List selectByExample(Object example); }
public abstract class BaseServiceimplements IService { @Autowired protected Mapper mapper; @Override public T selectByKey(Object key) { return mapper.selectByPrimaryKey(key); } @Override public int save(T entity) { return mapper.insert(entity); } @Override public int delete(Object key) { return mapper.deleteByPrimaryKey(key); } @Override public int updateAll(T entity) { return mapper.updateByPrimaryKey(entity); } @Override public int updateNotNull(T entity) { return mapper.updateByPrimaryKeySelective(entity); } @Override public List selectByExample(Object example) { return mapper.selectByExample(example); } }
@Service public class ProductServiceImpl extends BaseServiceimplements ProductService { @Override public List selectByProduct(Product product, int page, int rows) { Example example = new Example(Product.class); Example.Criteria criteria = example.createCriteria(); if (StringUtils.isNotBlank(product.getName())) { criteria.andEqualTo("name", product.getName()); // 字符串字段名 } if (product.getId() != null) { criteria.andEqualTo("id", product.getId()); } PageHelper.startPage(page, rows); return selectByExample(example); } }
| 現象 | 原因 | 解決 |
|---|---|---|
啟動報 Mapped Statements collection already contains value for ... selectByExample | 用 MyBatis3 生成(含 Example 方法)+ 通用 Mapper(也有 selectByExample) → ID 衝突 | 改用 targetRuntime="MyBatis3Simple" 或不使用通用 Mapper |
| Example 無強類型 Criteria | 通用 Mapper 為了通用性,Criteria 方法簽名為 andEqualTo(String property, Object value) | 接受字符串字段名,或自擴展 Generator 生成強類型 Example |
本文構建了 PostgreSQL → tk.mybatis Generator → MyBatis3Simple + 通用 Mapper + PageHelper → Spring → 分層服務 完整鏈路。核心優勢:
權衡:通用 Mapper 犧牲了強類型 Example,複雜報表查詢仍需手寫 SQL。根據項目實際權衡選型。