Mapper xml
1.存Date类型的 数据
插入
#{item.createTime, jdbcType=TIMESTAMP} //数据库会存带 时间的信息
#{item.createTime, jdbcType=DATE} // /数据库会存带 不时间的信息
批量插入 从dual内取 传List 数据
<insert id="insertListStable" parameterType="java.util.List">
INSERT INTO PIWEB_STABLE_PASSRATE
(
id,
factory,
car_name,
part_name,
create_time
)
<foreach collection="list" item="item" index="index" separator="union all">
(
select
#{item.id, jdbcType=VARCHAR},
#{item.factory, jdbcType=VARCHAR},
#{item.carName, jdbcType=VARCHAR},
#{item.partName, jdbcType=VARCHAR},
#{item.createTime, jdbcType=TIMESTAMP}
from
dual
)
</foreach>
</insert>
oralce 表 表字段最好为 大写
in 不能使用# 要使用$ 如 in ${category} category = “(‘a’,‘b’’)”
小于 大于 <![CDATA[ <= ]]>
2. mybatis 1对多映射配置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.paraview.sc.modules.zk.errorSchedule.mapper.ZkErrorScheduleInfoMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.paraview.sc.modules.zk.errorSchedule.entity.ZkErrorScheduleInfo">
<id column="ID" property="id" />
<result column="IGNOREREPEAT" property="ignoreRepeat" />
<result column="CREATER" property="creater" />
<result column="CREATETIME" property="createtime" />
<result column="UPDATETIME" property="updatetime" />
<association property="fixedTrigger" column="ID" select="getFixedTrigger"/>
<association property="noticeMembers" column="ID" select="getNoticeMembers"/>
<association property="cycleTrigger" column="ID" javaType="com.paraview.sc.modules.zk.errorSchedule.entity.ZkErrorScheduleTrigger" select="getCycleTrigger"/>
</resultMap>
<select id="getNoticeMembers" resultType="com.paraview.sc.modules.zk.errorSchedule.entity.ZkErrorSchduleNotice">
select * from ZK_ERROR_SCHDULE_NOTICE where TASKID = #{id}
</select>
<select id="getFixedTrigger" resultType="com.paraview.sc.modules.zk.errorSchedule.entity.ZkErrorScheduleTrigger">
select * from ZK_ERROR_SCHEDULE_TRIGGER where TASKID = #{id} AND TASKTYPE = 'fixed'
</select>
<select id="getCycleTrigger" resultType="com.paraview.sc.modules.zk.errorSchedule.entity.ZkErrorScheduleTrigger">
select * from ZK_ERROR_SCHEDULE_TRIGGER where TASKID = #{id} AND TASKTYPE = 'cycle'
</select>
</mapper>
mybaits oracle 分页xml
<select id="selectListByPage" resultMap="BaseResultMap" parameterType="java.util.Map">
SELECT
*
FROM (
select
t.*,
rownum
from
ZK_ERROR_SCHEDULE_INFO t
WHERE
DATATYPE = #{dataType}
<if test="tasktype!=null and tasktype!=''">
and TASKTYPE = #{tasktype}
</if>
and rownum <![CDATA[ <= ]]> #{pageSize}
) where rownum <![CDATA[ >= ]]> #{currPage}
</select>
mybatis for 循环及 if判断
<if test="vinList!=null and vinList.size()>0">
AND VIN in
<foreach item="item" index="index" collection="vinList"
open="(" separator="," close=")">
#{item}
</foreach>
</if>
2分组取唯一
#根据name分组取 时间最新的 一条数据
SELECT ROW_NUMBER() OVER(PARTITION BY W.NAME ORDER BY W.CREATETIME DESC) rn,W.* FROM
fawmes.V_REALORDER W
) WHERE rn = 1
choose when
<choose>
<when test="">
//...
</when>
<otherwise>
//...
</otherwise>
</choose>
if test
<if test="yearMonth lte 202101">
<include refid="kpiTstOLd"></include>
</if>
lt
lte
gt
gte
配置sql代码块
<sql id="">
sql 片段
</sql>
引用处
<include ref = ""/>
<include refid="queryTstLinName"></include>
mybatis 插入前查询是否已经存在该记录
INSERT INTO piweb_files_list (
file_name,
file_type,
file_ip,
file_location,
upload_success,
upload_time,
anly_status,
anly_time,
hdfs_path
)
<foreach collection="list" item="item" index="index" separator="union all">
(
SELECT
#{item.fileName, jdbcType=VARCHAR},
#{item.fileType, jdbcType=VARCHAR},
#{item.fileIp, jdbcType=VARCHAR},
#{item.fileLocation, jdbcType=VARCHAR},
#{item.uploadSuccess, jdbcType=VARCHAR},
#{item.uploadTime, jdbcType=TIMESTAMP},
#{item.anlyStatus, jdbcType=VARCHAR},
#{item.anlyTime, jdbcType=TIMESTAMP},
#{item.hdfsPath, jdbcType=VARCHAR}
FROM
DUAL
WHERE
NOT EXISTS (
SELECT
*
FROM
piweb_files_list
WHERE
file_name = #{item.fileName}
AND
file_location = #{item.fileLocation}
)
)
</foreach>
mybatis mysql 批量插入 计数
public int batchInsertUser(@Param("sysUsers") List<SysUserTsource> sysUsers);
<insert id="batchInsertUser" parameterType="java.util.List" useGeneratedKeys="true" keyProperty="sysUsers.userId">
INSERT INTO sys_user_tsource
(user_id, dept_id, user_name, nick_name, email, phonenumber, sex, avatar, password, status, create_by, remark, create_time)
VALUES
<foreach collection ="sysUsers" index="index" item="item" separator =",">
(
#{item.userId,jdbcType=VARCHAR},
#{item.deptId},
#{item.userName},
#{item.nickName},
#{item.email},
#{item.phonenumber},
#{item.sex},
#{item.avatar},
#{item.password},
#{item.status},
#{item.createBy},
#{item.remark},
sysdate()
)
</foreach >
</insert>
mybatis mysql 批量更新或插入
<insert id="batchInsertOrUpdateUser" parameterType="java.util.List" useGeneratedKeys="true" keyProperty="sysUsers.userId">
INSERT INTO sys_user_tsource
(user_id, dept_id, user_name, nick_name, email, phonenumber, sex, avatar, password, status, create_by, remark, create_time)
VALUES
<foreach collection ="sysUsers" index="index" item="item" separator =",">
(
#{item.userId,jdbcType=VARCHAR},
#{item.deptId},
#{item.userName},
#{item.nickName},
#{item.email},
#{item.phonenumber},
#{item.sex},
#{item.avatar},
#{item.password},
#{item.status},
#{item.createBy},
#{item.remark},
sysdate()
)
</foreach >
on duplicate key update
user_id = values(user_id),
dept_id = values(dept_id),
user_name = values(user_name),
nick_name = values(nick_name),
email = values(email),
phonenumber = values(phonenumber),
sex = values(sex),
avatar = values(avatar),
`password` = values(`password`),
`status` = values(`status`),
create_by = values(create_by),
remark = values(avatar),
create_time = values(create_time)
</insert>
mybaits oracle数据库 批量插入或更新xml
<update id="batchUpdateOrInsert" parameterType="java.util.List">
MERGE INTO TST_DATA_EXTRACT AC USING (
<foreach collection="list" separator="union" open="" item="item" index="index" close="">
SELECT
#{item.id, jdbcType=VARCHAR} as SIDP,
#{item.dataTime, jdbcType=VARCHAR} as DTIME,
#{item.dataFactory, jdbcType=VARCHAR} as FACTORY,
#{item.dataProdLine, jdbcType=VARCHAR} as PRODLINE,
#{item.dataActual, jdbcType=VARCHAR} as ACTUAL,
#{item.dataTarget, jdbcType=VARCHAR} as TARGET,
#{item.createTime, jdbcType=TIMESTAMP} as CREATETIME,
#{item.dataAvgTarget, jdbcType=VARCHAR} as AVGTARGET,
#{item.dataTst, jdbcType=VARCHAR} as DATATST
FROM
dual
</foreach>
) C ON (
AC.DATA_TIME = C.DTIME AND AC.DATA_FACTORY = C.FACTORY AND AC.DATA_PRODLINE = C.PRODLINE
)
WHEN MATCHED THEN
UPDATE
SET
AC.DATA_ACTUAL = C.ACTUAL,
AC.DATA_TARGET = C.TARGET,
AC.CREATE_TIME = C.CREATETIME,
AC.DATA_AVGTARGET = C.AVGTARGET,
AC.DATA_TST = C.DATATST
WHEN NOT MATCHED THEN
INSERT (
AC."ID",
AC."DATA_TIME",
AC."DATA_FACTORY",
AC."DATA_PRODLINE",
AC."DATA_ACTUAL",
AC."DATA_TARGET",
AC."CREATE_TIME",
AC."DATA_AVGTARGET",
AC."DATA_TST"
)
VALUES
(
C."SIDP",
C."DTIME",
C."FACTORY",
C."PRODLINE",
C."ACTUAL",
C."TARGET",
C."CREATETIME",
C."AVGTARGET",
C."DATATST"
)
<!-- <if test="index == (list.size() - 1)">
</if>-->
</update>
mybatis 异常场景原因
- 关联查询输出多出原因 : 左关联 多数据为 右表 出现 1对多
select * from(select a.CompanyID,a.UserName,a.AddTime,a.JF,
ROW_NUMBER() over(partition by a.CompanyID order by b.ID) as new_index FROM dbo.LB_Company
) t where t.new_index=1
执行视图
//存储过程 执行语句
<select id="ZSZSWEEK" parameterType="map" statementType="CALLABLE">
{
call DB2CCDP.JSC_ZSZS_TIME(
#{ETLTIME1,mode=IN,jdbcType=VARCHAR}
,#{ETLTIME2 ,mode=IN,jdbcType=VARCHAR}
,#{ETLTIME3 ,mode=IN,jdbcType=VARCHAR}
,#{FACTORYNAME,mode=IN,jdbcType=VARCHAR}
,#{STATUSSTART,mode=IN,jdbcType=VARCHAR}
,#{STATUSEND ,mode=IN,jdbcType=VARCHAR})
}
</select>
自定义部分字段更新
void upClowns(@Param("rowList") List<Map<String,Object>> rowList,
@Param("rowId") String rowId );
<update id="upClowns" >
update QUESTION_USER
<set>
<foreach collection="rowList" separator="," item="item" >
${item.tabRow} = #{item.value}
</foreach>
</set>
where id=#{rowId}
</update>
通用mapper扩展通用接口和Example 用法
@RegisterMapper 注解可以避免 mappers 参数配置,通用 Mapper 检测到该接口被继承时,会自动注册。
@RegisterMapper
public interface MyInsertListMapper<T> {
@InsertProvider(
type = MySpecialProvider.class,
method = "dynamicSQL"
) //method = "dynamicSQL"是固定值
/**
* insertList
* @param var1
* @return
*/
int insertList(List<T> var1);
}
MySpecialProvider 需要自己实现的 该类需要继承 MapperTemplate。
public class MySpecialProvider extends MapperTemplate {
public MySpecialProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
super(mapperClass, mapperHelper);
}
public String insertList(MappedStatement ms) {
Class<?> entityClass = this.getEntityClass(ms);
StringBuilder sql = new StringBuilder();
sql.append(SqlHelper.insertIntoTable(entityClass, this.tableName(entityClass)));
sql.append(SqlHelper.insertColumns(entityClass, false, false, false));
sql.append(" VALUES ");
sql.append("<foreach collection=\"list\" item=\"record\" separator=\",\" >");
sql.append("<trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">");
Set<EntityColumn> columnList = EntityHelper.getColumns(entityClass);
Iterator var5 = columnList.iterator();
while(var5.hasNext()) {
EntityColumn column = (EntityColumn)var5.next();
if (column.isInsertable()) {
sql.append(column.getColumnHolder("record") + ",");
}
}
sql.append("</trim>");
sql.append("</foreach>");
return sql.toString();
}
public String insertUseGeneratedKeys(MappedStatement ms) {
Class<?> entityClass = this.getEntityClass(ms);
StringBuilder sql = new StringBuilder();
sql.append(SqlHelper.insertIntoTable(entityClass, this.tableName(entityClass)));
sql.append(SqlHelper.insertColumns(entityClass, true, false, false));
sql.append(SqlHelper.insertValuesColumns(entityClass, true, false, false));
return sql.toString();
}
}
基础mapper
//ids "1,2,3,4" IdsMapper 进行处理
public interface IBaseMapper<T>
extends
Mapper<T>,
MySpecialProvider <T>,
ConditionMapper<T>,
IdsMapper<T> {
}
mybatis-plus
// 插件排序正则
.orderBy("REGEXP_SUBSTR('PRCODE','\\d{1,}',1,1,'i')")
//有问题
.and("create_time >= TO_DATE({0},'yyyy-mm-dd hh24:mi:ss') and create_time < TO_DATE({1},'yyyy-mm-dd hh24:mi:ss') ",beginTime,endTime)
List<BasProceedProject> basProceedProjects = this.selectList(
new EntityWrapper<BasProceedProject>()
.eq(StringUtils.isNotBlank(factor), "FACTORY", factor)
.eq(StringUtils.isNotBlank(carType), "CAR_TYPE", carType)
.eq(StringUtils.isNotBlank(projectName), "PROJECT_NAME", projectName)
);
Page<BasProceedProject> page = this.selectPage(
new Query<BasProceedProject>(params).getPage(),
new EntityWrapper<BasProceedProject>()
.like(StringUtils.isNotBlank(paramKey1),"FACTORY", paramKey1)
.like(StringUtils.isNotBlank(paramKey2),"PROJECT_NAME", paramKey2)
.like(StringUtils.isNotBlank(paramKey3),"CAR_TYPE", paramKey3)
.like(StringUtils.isNotBlank(paramKey4),"YEAR_MONTH", paramKey4)
.orderBy("REGEXP_SUBSTR('PRCODE','\\d{1,}',1,1,'i')")
);
com.baomidou.mybatisplus.mapper.BaseMapper
// dao
M extends BaseMapper <T>
// serviceImpl
public class BasProceedProjectServiceImpl extends ServiceImpl<M, T> implements IBasProceedProjectService {
}
// IService<T>
//要配置 分页配置类 不然 分页查询查询不到 总数信息
@Configuration
public class MybatisPlusConfig {
/**
* 分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
#配置
<mybatisplus.spring.boot.version>1.0.5</mybatisplus.spring.boot.version>
<mybatisplus.version>2.2.0</mybatisplus.version>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>${mybatisplus.version>}</version>
</dependency>
// springBoot 配置
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatisplus-spring-boot-starter</artifactId>
<version>${mybatisplus.spring.boot.version}</version>
</dependency>
<!--快照版本使用,正式版本无需添加此仓库-->
<repository>
<id>snapshots</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</repository>
```
```yaml
mybatisplus:
enabled: true
generic:
enabled: true
dialectType: mysql
-- 基础配置
mybatis-plus.mapper-locations=classpath:mapper/**/*.xml
#实体扫描,多个package用逗号或者分号分隔
mybatis-plus.type-aliases-package=com.example.miniproject.business.*.entity
#开启sql日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
xml
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!-- 自动扫描Mapping.xml文件 -->
<property name="mapperLocations" value="classpath:mybatis/*/*.xml"/>
<property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/>
<property name="typeAliasesPackage" value="com.baomidou.springmvc.model.*"/>
<property name="plugins">
<array>
<!-- 分页插件配置 -->
<bean id="paginationInterceptor" class="com.baomidou.mybatisplus.plugins.PaginationInterceptor">
<property name="dialectType" value="mysql"/>
</bean>
</array>
</property>
<!-- 全局配置注入 -->
<property name="globalConfig" ref="globalConfig" />
</bean>
//配置mybatisPlus 分頁
@Configuration
public class MybatisPlusConfig {
/**
* 分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
//基础mapper使用
public interface UserMapper extends BaseMapper<User> {
}
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
public void queryUserList(UserDto dto){
EntityWrapper<User> ew = new EntityWrapper<User>();
ew.where("deleted={0}", 1);
ew.in("user_type", "1");
ew.eq("role", "1");
ew.eq("status", "1");
ew.orderBy("id");
ew.orderBy("created_time", true);
log.info("selectList condition:{}", ew.getSqlSegment());
List<User> userList = this.selectList(ew);
}
}
pageHelper 使用
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
//调用方法前 分页后的第一个查询语句 会进行分页处理
Page page2 = PageHelper.startPage(pageNum, pageSize, orderBy);
//执行的语句
List<QualityControl> qControlDayValues = exposeApiMapper.getQControlDayValues(params);
PageInfo< QualityControlRespDTO> pageInfo = new PageInfo<QualityControlRespDTO>(qControlDayValues );
PageData<QualityControlRespDTO> pageData = new PageData<>();
pageData.setList(pageInfo.getList());
pageData.setTotal(page2.getTotal());
pageData.setPageNum(page2.getPageNum());
pageData.setPageSize(page2.getPageSize());
pageData.setPages(page2.getPages());
sqlSession
SqlSessionFactory
SqlSession sqlSession = sqlSessionFactory.openSession();
ExposeApiMapper exposeApiMapper = sqlSession.getMapper(ExposeApiMapper.class);
SqlSession
1. 进行连接获取 Connection 进行 设置是否自动提交 提交 回滚 等操作
2. sqlSession 进行 查询 更新 删除 提交 回滚 获取配置信息 根据 Mapper 获取mapper 等操作
https://www.jianshu.com/p/5515640d14fe
mybatis 二级缓存 实体要实现序列化接口 二级缓存是手动开启的,作用域为sessionfactory 你的Executor将会被装饰成CachingExecutor 多个session 没关系
mybatis 一级缓存是不需要的手动开启 默认开启,sqlSession级别的 在commit之前 同一语句会自动执行的 并且当commit或者rollback的时候会清除缓存,并且当执行insert、update、delete的时候也会清除缓存。
<mapper namespace="com.yihaomen.mybatis.dao.StudentMapper">
<!--开启本mapper的namespace下的二级缓存-->
<!--
eviction:代表的是缓存回收策略,目前MyBatis提供以下策略。
(1) LRU,最近最少使用的,一处最长时间不用的对象
(2) FIFO,先进先出,按对象进入缓存的顺序来移除他们
(3) SOFT,软引用,移除基于垃圾回收器状态和软引用规则的对象
(4) WEAK,弱引用,更积极的移除基于垃圾收集器状态和弱引用规则的对象。这里采用的是LRU,
移除最长时间不用的对形象
flushInterval:刷新间隔时间,单位为毫秒,这里配置的是100秒刷新,如果你不配置它,那么当
SQL被执行的时候才会去刷新缓存。
size:引用数目,一个正整数,代表缓存最多可以存储多少个对象,不宜设置过大。设置过大会导致内存溢出。
这里配置的是1024个对象
readOnly:只读,意味着缓存数据只能读取而不能修改,这样设置的好处是我们可以快速读取缓存,缺点是我们没有
办法修改缓存,他的默认值是false,不允许我们修改
-->
<cache eviction="LRU" flushInterval="100000" readOnly="true" size="1024"/>
<!--可以通过设置useCache来规定这个sql是否开启缓存,ture是开启,false是关闭-->
<select id="selectAllStudents" resultMap="studentMap" useCache="true">
SELECT id, name, age FROM student
</select>
<!--刷新二级缓存
<select id="selectAllStudents" resultMap="studentMap" flushCache="true">
SELECT id, name, age FROM student
</select>
</mapper>
改造计划
每个数据源 可以创建 一个sqlSessionFactory
配置插件 是否开启缓存
多个业务可以用同一个 sqlSessionFactory 产生不同的session 可以 使用二级缓存(同一个sqlSessionFactory 下 不同session之间) 和一级缓存(关闭自己提交 改为手动提交)
private SqlSessionFactory sqlSessionFactoryBean(DataSource dataSource) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Configuration configuration = new Configuration();
//设置查询失效时间 3分钟
configuration.setDefaultStatementTimeout(180);
sqlSessionFactoryBean.setConfiguration(configuration);
sqlSessionFactoryBean.setTransactionFactory(transactionFactory);
//分页插件
PageInterceptor pageInterceptor = new PageInterceptor();
Properties props = new Properties();
props.setProperty("reasonable", "true");
//props.setProperty("supportMethodsArguments", "true");
props.setProperty("offsetAsPageNum", "true");
props.setProperty("rowBoundsWithCount", "true");
//props.setProperty("returnPageInfo", "check");
props.setProperty("helperDialect", "mysql");
pageInterceptor.setProperties(props);
//添加插件
sqlSessionFactoryBean.setPlugins(new Interceptor[]{(Interceptor) pageInterceptor});
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:/mapper/*.xml"));
return sqlSessionFactoryBean.getObject();
}
SqlSession sqlSession = sqlSessionFactory.openSession();
ExposeApiMapper exposeApiMapper = sqlSession.getMapper(ExposeApiMapper.class);
基于 MapperTemplate 创建mybatis 的sql 模板
第一步 创建Mapper接口
@RegisterMapper
@RegisterMapper
public interface MyInsertListMapper<T> {
@InsertProvider(
type = MySpecialProvider.class,
method = "dynamicSQL"
)
/**
* insertList
* @param var1
* @return
*/
int insertList(List<T> var1);
}
MySpecialProvider 类为 自定义模板的 业务sql编写类 集成 MapperTemplate 重写构造方法
1.自定义 业务方法
SqlHelper
MappedStatement
public class MySpecialProvider extends MapperTemplate {
public MySpecialProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
super(mapperClass, mapperHelper);
}
public String insertList(MappedStatement ms) {
Class<?> entityClass = this.getEntityClass(ms);
StringBuilder sql = new StringBuilder();
sql.append(SqlHelper.insertIntoTable(entityClass, this.tableName(entityClass)));
sql.append(SqlHelper.insertColumns(entityClass, false, false, false));
sql.append(" VALUES ");
sql.append("<foreach collection=\"list\" item=\"record\" separator=\",\" >");
sql.append("<trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">");
Set<EntityColumn> columnList = EntityHelper.getColumns(entityClass);
Iterator var5 = columnList.iterator();
while(var5.hasNext()) {
EntityColumn column = (EntityColumn)var5.next();
if (column.isInsertable()) {
sql.append(column.getColumnHolder("record") + ",");
}
}
sql.append("</trim>");
sql.append("</foreach>");
return sql.toString();
}
public String insertUseGeneratedKeys(MappedStatement ms) {
Class<?> entityClass = this.getEntityClass(ms);
StringBuilder sql = new StringBuilder();
sql.append(SqlHelper.insertIntoTable(entityClass, this.tableName(entityClass)));
sql.append(SqlHelper.insertColumns(entityClass, true, false, false));
sql.append(SqlHelper.insertValuesColumns(entityClass, true, false, false));
return sql.toString();
}
}
创建接口 集成 mybatis 和 自定义mapper 的 接口
public interface IBaseMapper<T>
extends
Mapper<T>,
NewMySqlMapper<T>,
MyInsertListMapper<T>,
ConditionMapper<T>,
IdsMapper<T> {
}
// 业务类
public interface AreaMapper extends IBaseMapper<Area> {
}
DruidDataSource数据源配置mysql 的 allowMutilquery
url 添加 ?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&serverTimezone=GMT%2B8&allowMultiQueries=true
DruidDataSource 需要配置 proxyFilters 下 WallFilter config 内配置 setMultiStatementAllow 为 true
@Bean(name="dataSource",destroyMethod = "close", initMethod="init")
@Primary
public DataSource dataSource(){
DruidDataSource datasource = new DruidDataSource();
try {
datasource.setUrl(this.dbUrl);
datasource.setDbType(dbType);
datasource.setUsername(username);
datasource.setPassword(password);
datasource.setDriverClassName(driverClassName);
datasource.setInitialSize(initialSize);
datasource.setMinIdle(minIdle);
datasource.setMaxActive(maxActive);
datasource.setMaxWait(maxWait);
datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
datasource.setValidationQuery(validationQuery);
datasource.setTestWhileIdle(testWhileIdle);
datasource.setTestOnBorrow(testOnBorrow);
datasource.setTestOnReturn(testOnReturn);
datasource.setPoolPreparedStatements(poolPreparedStatements);
datasource.setFilters(filters);
datasource.setQueryTimeout(60000);
List<Filter> proxyFilters = datasource.getProxyFilters();
if(proxyFilters != null){
for(Filter filter : proxyFilters){
if(filter instanceof WallFilter){
((WallFilter) filter).setDbType(platform);
WallConfig wallConfig = new WallConfig();
wallConfig.setMultiStatementAllow(true);
((WallFilter) filter).setConfig(wallConfig);
}
}
}
} catch (SQLException e) {
log.error("druid configuration initialization filter", e);
}
return datasource;
}
表反向生成代码 velocity
<velocity.version>1.7</velocity.version>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<exclusions>
<exclusion>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
velocity 语法
模板文件 文件类型*.vm,数据传递方式 VelocityContext
Velocity 可以根据模板文件名称 获取Template
tpl 合并VelocityContext 数据 输出到 StringWriter 里
通过StringWriter 结合io进行文件操作
StringWriter sw = new StringWriter();
Template tpl = Velocity.getTemplate(template, "UTF-8");
tpl.merge(context, sw);
String path = ystem.getProperty("user.dir") + File.separator + "src" + File.separator + "domain.java";
FileUtils.writeStringToFile(new File(path), sw.toString(), "UTF-8");
*.vm 语法
#开头为模板指令前缀
$开头为VelocityContext 内变量使用 ( 绑定的参数,存在is开头的 boolean返回的无参方法 ,可以直接 实列.名称使用。$变量可以使用其自身的方法
if 和 set 设置临时变量 指令
#if($param1 || $param2)
#set($msg="测试")
#elseif($param3)
#set($msg="测试2")
#end
! | & > < = >= <= != 都可以使用
循环 for
#foreach ($import in $importList)
import ${import};
#end
end 为 if 和for 终止指令
domain.java.vm
package ${packageName}.domain;
#foreach ($import in $importList)
import ${import};
#end
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.tcloud.cn.common.BaseEntity;
/**
* ${functionName}对象 ${tableName}
*
* @author ${author}
* @date ${datetime}
*/
#if($table.sub || $table.crud )
#set($Entity="BaseEntity")
#elseif($table.tree)
#set($Entity="TreeEntity")
#end
public class ${ClassName} extends ${Entity}
{
private static final long serialVersionUID = 1L;
#foreach ($column in $columns)
#if(!$table.isSuperColumn($column.javaField))
/** $column.columnComment */
#if($column.list)
#set($parentheseIndex=$column.columnComment.indexOf("("))
#if($parentheseIndex != -1)
#set($comment=$column.columnComment.substring(0, $parentheseIndex))
#else
#set($comment=$column.columnComment)
#end
#end
/** $comment */
private $column.javaType $column.javaField;
#end
#end
#if($table.sub)
/** $table.subTable.functionName信息 */
private List<${subClassName}> ${subclassName}List;
#end
/** get set */
#foreach ($column in $columns)
#if(!$table.isSuperColumn($column.javaField))
#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]"))
#set($AttrName=$column.javaField)
#else
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
#end
public void set${AttrName}($column.javaType $column.javaField)
{
this.$column.javaField = $column.javaField;
}
public $column.javaType get${AttrName}()
{
return $column.javaField;
}
#end
#end
#if($table.sub)
public List<${subClassName}> get${subClassName}List()
{
return ${subclassName}List;
}
public void set${subClassName}List(List<${subClassName}> ${subclassName}List)
{
this.${subclassName}List = ${subclassName}List;
}
#end
/** toString */
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
#foreach ($column in $columns)
#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]"))
#set($AttrName=$column.javaField)
#else
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
#end
.append("${column.javaField}", get${AttrName}())
#end
#if($table.sub)
.append("${subclassName}List", get${subClassName}List())
#end
.toString();
}
}