mybatis使用心得(mark一下)
mybatis使用心得博客分类:
[*]开源jar包应用
mybatis物理分页mybatis nullmybatis spring
一、mybatis版本
个人建议使用:
Java代码
[*]<dependency>
[*] <groupId>org.mybatis</groupId>
[*] <artifactId>mybatis</artifactId>
[*] <version>3.1.1</version>
[*]</dependency>
在mybatis3.1.1中优化了批量处理的效率
在底层statementHandle中提供了更加灵活的扩展性
主要是体现在插件,拦截器能做的,能够获取到的参数更多的方面
二、与spring集合的配置
Java代码
[*]<bean id="sqlSessionFactory"
[*] class="org.mybatis.spring.SqlSessionFactoryBean">
[*] <property name="dataSource" ref="datasource"></property>
[*] <property name="configLocation" value="classpath:context/mybatis-config.xml"></property>
[*] <property name="mapperLocations" value="classpath*:/com/tx/demo/**/*SqlMap.xml" />
[*] <property name="typeHandlersPackage" value="com.tx.core.mybatis.handler"></property>
[*] <property name="failFast" value="true"></property>
[*] <property name="plugins">
[*] <array>
[*] <bean class="com.tx.core.mybatis.interceptor.PagedDiclectStatementHandlerInterceptor">
[*] <property name="dialect">
[*] <bean class="org.hibernate.dialect.PostgreSQLDialect"></bean>
[*] </property>
[*] </bean>
[*] </array>
[*] </property>
[*]</bean>
[*]
[*]<bean id="myBatisExceptionTranslator" class="org.mybatis.spring.MyBatisExceptionTranslator">
[*] <property name="dataSource">
[*] <ref bean="datasource"></ref>
[*] </property>
[*]</bean>
[*]
[*]<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
[*] <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>
[*] <constructor-arg name="executorType" ref="SIMPLE"></constructor-arg>
[*] <constructor-arg name="exceptionTranslator" ref="myBatisExceptionTranslator"></constructor-arg>
[*]</bean>
[*]
[*]<bean id="myBatisDaoSupport" class="com.tx.core.mybatis.support.MyBatisDaoSupport">
[*] <property name="sqlSessionTemplate">
[*] <ref bean="sqlSessionTemplate"/>
[*] </property>
[*]</bean>
这里对配置进行一下说明
mapperLocations: 通过正则表达式,支持mybatis动态扫描添加mapper不用像ibatis,用一个还要蛋疼滴添加一个include
typeHandlersPackage: 由于mybatis默认入参如果为空,又没有指定jdbcType时会抛出异常,在这里通过配置一些默认的类型空值插入的handle,以便处理mybatis的默认类型为空的情况
例如NullAbleStringTypeHandle通过实现当String字符串中为null是调用ps.setString(i,null)其他常用类型雷同
failFast:开启后将在启动时检查设定的parameterMap,resultMap是否存在,是否合法。个人建议设置为true,这样可以尽快定位解决问题。不然在调用过程中发现错误,会影响问题定位。
myBatisExceptionTranslator:用以支持spring的异常转换,通过配置该translatro可以将mybatis异常转换为spring中定义的DataAccessException
三、mybatis的批量处理功能,
由于在3.1.1升级后,可直接通过batchExcutor实现具体的批量执行。在该excutor中会重用上一次相同的prepareStatement。
具体实现这里贴一个:
Java代码
[*]/**
[*] * 批量插入数据 <br/>
[*] * 1、数据批量插入,默认一次提交100条,当发生异常后继续提交异常行以后的数据,待集合全部进行提交后返回批量处理结果<br/>
[*] * 2、数据批量插入,如果需要回滚,当发生异常后,数据库异常即向外抛出,不会进行至全部执行后再抛出异常 <br/>
[*] * <功能详细描述>
[*] *
[*] * @param statement
[*] * @param objectCollection
[*] * @param isRollback
[*] * @return [参数说明]
[*] *
[*] * @return BatchResult<T> [返回类型说明]
[*] * @exception throws [异常类型] [异常说明]
[*] * @see [类、类#方法、类#成员]
[*] */
[*]public BatchResult batchInsert(String statement, List<?> objectList,
[*] boolean isStopWhenFlushHappenedException) {
[*] return batchInsert(statement,
[*] objectList,
[*] defaultDoFlushSize,
[*] isStopWhenFlushHappenedException);
[*]}
[*]
[*]/**
[*] * 批量插入数据
[*] *
[*] * @param statement
[*] * @param objectList
[*] * 对象列表
[*] * @param doFlushSize
[*] * @param isStopWhenFlushHappenedException
[*] * 当在flush发生异常时是否停止,如果在调用insert时抛出的异常,不在此设置影响范围内
[*] * @return void [返回类型说明]
[*] * @exception throws [异常类型] [异常说明]
[*] * @see [类、类#方法、类#成员]
[*] */
[*]// 批量插入
[*]public BatchResult batchInsert(String statement, List<?> objectList,
[*] int doFlushSize, boolean isStopWhenFlushHappenedException) {
[*] BatchResult result = new BatchResult();
[*] if (CollectionUtils.isEmpty(objectList)) {
[*] return result;
[*] }
[*] if (doFlushSize <= 0) {
[*] doFlushSize = defaultDoFlushSize;
[*] }
[*] //设置总条数
[*] result.setTotalNum(objectList.size());
[*]
[*] //从当前环境中根据connection生成批量提交的sqlSession
[*] SqlSession sqlSession = this.sqlSessionTemplate.getSqlSessionFactory()
[*] .openSession(ExecutorType.BATCH);
[*]
[*] try {
[*] // 本次flush的列表开始行行索引
[*] int startFlushRowIndex = 0;
[*] for (int index = 0; index < objectList.size(); index++) {
[*] // 插入对象
[*] insertForBatch(sqlSession,
[*] statement,
[*] objectList.get(index),
[*] null);
[*] if ((index > 0 && index % doFlushSize == 0)
[*] || index == objectList.size() - 1) {
[*] try {
[*] List<org.apache.ibatis.executor.BatchResult> test = flushBatchStatements(sqlSession);
[*] System.out.println(test);
[*] startFlushRowIndex = index + 1;
[*] }
[*] catch (Exception ex) {
[*] if (!(ex.getCause() instanceof BatchExecutorException)
[*] || isStopWhenFlushHappenedException) {
[*] DataAccessException translated = this.sqlSessionTemplate.getPersistenceExceptionTranslator()
[*] .translateExceptionIfPossible((PersistenceException) ex);
[*] throw translated;
[*] }
[*]
[*] BatchExecutorException e = (BatchExecutorException) ex.getCause();
[*] // 如果为忽略错误异常则记录警告日志即可,无需打印堆栈,如果需要堆栈,需将日志级别配置为debug
[*] logger.warn("batchInsert hanppend Exception:{},the exception be igorned.",
[*] ex.toString());
[*] if (logger.isDebugEnabled()) {
[*] logger.debug(ex.toString(), ex);
[*] }
[*]
[*] // 获取错误行数,由于错误行发生的地方
[*] int errorRownumIndex = startFlushRowIndex
[*] + e.getSuccessfulBatchResults().size();
[*] result.addErrorInfoWhenException(objectList.get(index),
[*] errorRownumIndex,
[*] ex);
[*]
[*] //将行索引调整为错误行的行号,即从发生错误的行后面一行继续执行
[*] index = errorRownumIndex;
[*] startFlushRowIndex = errorRownumIndex + 1;
[*] }
[*] }
[*] }
[*] }
[*] finally {
[*] sqlSession.close();
[*] }
[*] return result;
[*]}
这里的实现写得稍微复杂一些,
主要是,针对有些情况如果其中某条失败,还想后续数据能够继续成功提交的情况进行支持。
四、数据库物理分页,这个网上的文章也比较多,这里也提一下。在前人的基础上,我的物理分页类实现为:
Java代码
[*]<coding-3 lang="as">
[*]/*
[*] * 描 述: <描述>
[*] * 修 改 人: PengQingyang
[*] * 修改时间: 2012-11-5
[*] * <修改描述:>
[*] */
[*]package com.tx.core.mybatis.interceptor;
[*]
[*]import java.lang.reflect.Method;
[*]import java.sql.Connection;
[*]import java.sql.PreparedStatement;
[*]import java.sql.Statement;
[*]import java.util.Properties;
[*]
[*]import org.apache.ibatis.executor.statement.PreparedStatementHandler;
[*]import org.apache.ibatis.executor.statement.RoutingStatementHandler;
[*]import org.apache.ibatis.executor.statement.SimpleStatementHandler;
[*]import org.apache.ibatis.executor.statement.StatementHandler;
[*]import org.apache.ibatis.mapping.BoundSql;
[*]import org.apache.ibatis.plugin.Interceptor;
[*]import org.apache.ibatis.plugin.Intercepts;
[*]import org.apache.ibatis.plugin.Invocation;
[*]import org.apache.ibatis.plugin.Plugin;
[*]import org.apache.ibatis.plugin.Signature;
[*]import org.apache.ibatis.reflection.MetaObject;
[*]import org.apache.ibatis.session.RowBounds;
[*]import org.hibernate.dialect.Dialect;
[*]import org.slf4j.Logger;
[*]import org.slf4j.LoggerFactory;
[*]
[*]/**
[*] * <数据库分页容器处理器>
[*] * <功能详细描述>
[*] *
[*] * @author PengQingyang
[*] * @version [版本号, 2012-11-5]
[*] * @see [相关类/方法]
[*] * @since [产品/模块版本]
[*] */
[*]@Intercepts({
[*] @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }),
[*] @Signature(type = StatementHandler.class, method = "parameterize", args = { Statement.class }) })
[*]public class PagedDiclectStatementHandlerInterceptor implements Interceptor {
[*]
[*] private Logger logger = LoggerFactory.getLogger(PagedDiclectStatementHandlerInterceptor.class);
[*]
[*] private Dialect dialect;
[*]
[*] /**
[*] * 物理分页插件拦截
[*] * @param invocation
[*] * @return
[*] * @throws Throwable
[*] */
[*] public Object intercept(Invocation invocation) throws Throwable {
[*] Method m = invocation.getMethod();
[*] if ("prepare".equals(m.getName())) {
[*] return prepare(invocation);
[*] } else if ("parameterize".equals(m.getName())) {
[*] return parameterize(invocation);
[*] }
[*] return invocation.proceed();
[*] }
[*]
[*] /**
[*] * @param target
[*] * @return
[*] */
[*] public Object plugin(Object target) {
[*] return Plugin.wrap(target, this);
[*] }
[*]
[*] /**
[*] * @param properties
[*] */
[*] public void setProperties(Properties properties) {
[*]
[*] }
[*]
[*] /**
[*] * 拦截prepare修改分页
[*] * <功能详细描述>
[*] * @param invocation
[*] * @return
[*] * @throws Throwable [参数说明]
[*] *
[*] * @return Object [返回类型说明]
[*] * @exception throws [异常类型] [异常说明]
[*] * @see [类、类#方法、类#成员]
[*] */
[*] private Object prepare(Invocation invocation) throws Throwable {
[*] if (!(invocation.getTarget() instanceof RoutingStatementHandler)) {
[*] return invocation.proceed();
[*] }
[*]
[*] //提取statement
[*] RoutingStatementHandler statementHandler = (RoutingStatementHandler) invocation.getTarget();
[*]
[*] MetaObject metaStatementHandler = MetaObject.forObject(statementHandler);
[*]
[*]
[*] StatementHandler statement = (StatementHandler) metaStatementHandler.getValue("delegate");
[*] //如果不为两种statement则不继续进行处理
[*] if (!(statement instanceof SimpleStatementHandler)
[*] && !(statement instanceof PreparedStatementHandler)) {
[*] return invocation.proceed();
[*] }
[*]
[*] RowBounds rowBounds = (RowBounds) metaStatementHandler.getValue("delegate.rowBounds");
[*] //根据rowBounds判断是否需要进行物理分页
[*] if (rowBounds == null
[*] || rowBounds.equals(RowBounds.DEFAULT)
[*] || (rowBounds.getOffset() <= RowBounds.NO_ROW_OFFSET && rowBounds.getLimit() == RowBounds.NO_ROW_LIMIT)) {
[*] return invocation.proceed();
[*] }
[*]
[*] //进行处理
[*] BoundSql boundSql = statementHandler.getBoundSql();
[*] String sql = boundSql.getSql();
[*] String limitSql = dialect.getLimitString(sql,
[*] rowBounds.getOffset(),
[*] rowBounds.getLimit());
[*]
[*] if (statement instanceof SimpleStatementHandler) {
[*] limitSql.replaceAll("rownum <= ?", "rownum <= " + rowBounds.getLimit());
[*] limitSql.replaceAll("rownum_ > ?", "rownum_ > " + rowBounds.getOffset());
[*] }
[*]
[*] //如果为PreparedStatementHandler则无需替换即可
[*] metaStatementHandler.setValue("delegate.boundSql.sql",limitSql);
[*]
[*] if (logger.isDebugEnabled()) {
[*] logger.debug("生成分页SQL : " + boundSql.getSql());
[*] }
[*]
[*] return invocation.proceed();
[*] }
[*]
[*] /**
[*] * 设置分页参数
[*] * <功能详细描述>
[*] * @param invocation
[*] * @return
[*] * @throws Throwable [参数说明]
[*] *
[*] * @return Object [返回类型说明]
[*] * @exception throws [异常类型] [异常说明]
[*] * @see [类、类#方法、类#成员]
[*] */
[*] private Object parameterize(Invocation invocation) throws Throwable {
[*] //先执行系统默认的参数设置
[*] Object returnObj = invocation.proceed();
[*]
[*]
[*] //提取statement
[*] RoutingStatementHandler routingStatementHandler = (RoutingStatementHandler) invocation.getTarget();
[*] MetaObject metaStatementHandler = MetaObject.forObject(routingStatementHandler);
[*]
[*]
[*] StatementHandler statementHandler = (StatementHandler) metaStatementHandler.getValue("delegate");
[*] //如果不为两种statement则不继续进行处理
[*] if (!(statementHandler instanceof PreparedStatementHandler)) {
[*] return returnObj;
[*] }
[*]
[*] RowBounds rowBounds = (RowBounds) metaStatementHandler.getValue("delegate.rowBounds");
[*] //根据rowBounds判断是否需要进行物理分页
[*] if (rowBounds == null
[*] || rowBounds.equals(RowBounds.DEFAULT)
[*] || (rowBounds.getOffset() <= RowBounds.NO_ROW_OFFSET && rowBounds.getLimit() == RowBounds.NO_ROW_LIMIT)) {
[*] return returnObj;
[*] }
[*]
[*] //提取参数设置statement
[*] Statement statement = (Statement) invocation.getArgs();
[*] if (!(statement instanceof PreparedStatement)) {
[*] //如果对应statement不为PreparedStatement则直接返回
[*] return returnObj;
[*] }
[*]
[*] //设置分页的参数
[*] PreparedStatement ps = (PreparedStatement) statement;
[*] int parameterSize = statementHandler.getBoundSql().getParameterMappings().size();
[*] if(rowBounds.getOffset() > RowBounds.NO_ROW_OFFSET
[*] || rowBounds.getLimit() < RowBounds.NO_ROW_LIMIT){
[*] ps.setInt(parameterSize + 1, rowBounds.getLimit());
[*] parameterSize++;
[*] if(rowBounds.getOffset() > RowBounds.NO_ROW_OFFSET){
[*] ps.setInt(parameterSize + 1, rowBounds.getOffset());
[*] }
[*] }
[*]
[*] //替换rowBounds
[*] metaStatementHandler.setValue("delegate.rowBounds",
[*] RowBounds.DEFAULT);
[*]
[*] return returnObj;
[*] }
[*]
[*] /**
[*] * @return 返回 dialect
[*] */
[*] public Dialect getDialect() {
[*] return dialect;
[*] }
[*]
[*] /**
[*] * @param 对dialect进行赋值
[*] */
[*] public void setDialect(Dialect dialect) {
[*] this.dialect = dialect;
[*] }
[*]}
[*]</coding>
五、jpa注解的支持,mybatis本来优势就在于其sql可控,
个人不太倾向用太多的注解,mybatis的resultMap已经在ibatis基础上改进了很多,已经非常好用了,个人倾向于,利用表生成对应的model
然后根据实际业务将model改写,如需要oneToOne manyToOne时,添加jpa注解,调整bean属性命名后,根据model直接生成,dao,service,daoImpl,sqlMap,以及单元测试类
这个我现在有一个初步实现:
已经可以用了,大家可以一起使用一下,如果有问题,可以在这里回帖,我再进行逐步优化:
具体代码请在github上下载,建议使用eclipse版本为spring的sts
sqlMap后来考虑重用statemen有关null处已经进行调整,将于明天更新于github
有兴趣的可以从github下载相关代码:
https://github.com/txteam/tx-core/tree/1.0.x
这里贴一下自动生成的代码:
Java代码
[*]public static void main(String[] args) throws Exception{
[*] JpaEntityFreeMarkerGenerator g = new JpaEntityFreeMarkerGenerator();
[*]
[*] g.generate(Demo.class, "d:/mybatis");
[*]}
Java代码
[*]<?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="demo">
[*]
[*] <!-- auto generate default resultMap -->
[*] <resultMap id="demoMap"
[*] type="com.tx.core.mybatis.data.Demo">
[*] <result column="subDemo_id" property="subDemo.id"/>
[*] </resultMap>
[*]
[*] <!-- auto generate default find -->
[*] <select id="findDemo"
[*] parameterType="com.tx.core.mybatis.data.Demo"
[*] resultMap="demoMap">
[*] SELECT
[*] TW.ID,
[*] TW.INTTEST,
[*] TW.BOOLEANTEST,
[*] TW.PASSOWRD,
[*] TW.ENDDATE,
[*] TW.ISBOOLEANOBJTEST,
[*] TW.LASTUPDATEDATE,
[*] TW.TESTBIGDECEIMAL,
[*] TW.INTEGERTEST,
[*] TW.EMAIL,
[*] TW.NEWNAME AS name,
[*] TW.SUBDEMO AS subDemo_id,
[*] TW.TESTINTEGER,
[*] TW.CREATEDATE
[*] FROM WD_DEMO TW
[*] WHERE
[*] <trim prefixOverrides="AND | OR">
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(id)">
[*] AND TW.ID = #{id}
[*] </if>
[*] </trim>
[*] </select>
[*]
[*] <!-- auto generate default query -->
[*] <select id="queryDemo"
[*] parameterType="com.tx.core.mybatis.data.Demo"
[*] resultMap="demoMap">
[*] SELECT
[*] TW.ID,
[*] TW.INTTEST,
[*] TW.BOOLEANTEST,
[*] TW.PASSOWRD,
[*] TW.ENDDATE,
[*] TW.ISBOOLEANOBJTEST,
[*] TW.LASTUPDATEDATE,
[*] TW.TESTBIGDECEIMAL,
[*] TW.INTEGERTEST,
[*] TW.EMAIL,
[*] TW.NEWNAME AS name,
[*] TW.SUBDEMO AS subDemo_id,
[*] TW.TESTINTEGER,
[*] TW.CREATEDATE
[*] FROM WD_DEMO TW
[*] <trim prefix="WHERE" prefixOverrides="AND | OR">
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(id)">
[*] AND TW.ID = #{id}
[*] </if>
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(intTest)">
[*] AND TW.INTTEST = #{intTest}
[*] </if>
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(booleanTest)">
[*] AND TW.BOOLEANTEST = #{booleanTest}
[*] </if>
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(passowrd)">
[*] AND TW.PASSOWRD = #{passowrd}
[*] </if>
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(endDate)">
[*] AND TW.ENDDATE = #{endDate}
[*] </if>
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(isBooleanObjTest)">
[*] AND TW.ISBOOLEANOBJTEST = #{isBooleanObjTest}
[*] </if>
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(lastUpdateDate)">
[*] AND TW.LASTUPDATEDATE = #{lastUpdateDate}
[*] </if>
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(testBigDeceimal)">
[*] AND TW.TESTBIGDECEIMAL = #{testBigDeceimal}
[*] </if>
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(integerTest)">
[*] AND TW.INTEGERTEST = #{integerTest}
[*] </if>
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(email)">
[*] AND TW.EMAIL = #{email}
[*] </if>
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(name)">
[*] AND TW.NEWNAME = #{name}
[*] </if>
[*] <if test="subDemo != null">
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(subDemo.id)">
[*] AND TW.SUBDEMO = #{subDemo.id}
[*] </if>
[*] </if>
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(testInteger)">
[*] AND TW.TESTINTEGER = #{testInteger}
[*] </if>
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(createDate)">
[*] AND TW.CREATEDATE = #{createDate}
[*] </if>
[*] </trim>
[*] <choose>
[*] <when test="@com.tx.core.util.OgnlUtils@isNotEmpty(orderSql)">
[*] ORDER BY #{orderSql}
[*] </when>
[*] <otherwise>
[*] <!-- //TODO:ADD DEFAULT ORDER COLUMN OR DONOTHING! -->
[*] </otherwise>
[*] </choose>
[*] </select>
[*]
[*] <!-- auto generate default count -->
[*] <select id="queryDemoCount"
[*] parameterType="com.tx.core.mybatis.data.Demo"
[*] resultType="java.lang.Integer">
[*] SELECT COUNT(1)
[*] FROM WD_DEMO TW
[*] <trim prefix="WHERE" prefixOverrides="AND | OR">
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(id)">
[*] AND TW.ID = #{id}
[*] </if>
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(intTest)">
[*] AND TW.INTTEST = #{intTest}
[*] </if>
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(booleanTest)">
[*] AND TW.BOOLEANTEST = #{booleanTest}
[*] </if>
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(passowrd)">
[*] AND TW.PASSOWRD = #{passowrd}
[*] </if>
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(endDate)">
[*] AND TW.ENDDATE = #{endDate}
[*] </if>
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(isBooleanObjTest)">
[*] AND TW.ISBOOLEANOBJTEST = #{isBooleanObjTest}
[*] </if>
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(lastUpdateDate)">
[*] AND TW.LASTUPDATEDATE = #{lastUpdateDate}
[*] </if>
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(testBigDeceimal)">
[*] AND TW.TESTBIGDECEIMAL = #{testBigDeceimal}
[*] </if>
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(integerTest)">
[*] AND TW.INTEGERTEST = #{integerTest}
[*] </if>
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(email)">
[*] AND TW.EMAIL = #{email}
[*] </if>
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(name)">
[*] AND TW.NEWNAME = #{name}
[*] </if>
[*] <if test="subDemo != null">
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(subDemo.id)">
[*] AND TW.SUBDEMO = #{subDemo.id}
[*] </if>
[*] </if>
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(testInteger)">
[*] AND TW.TESTINTEGER = #{testInteger}
[*] </if>
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(createDate)">
[*] AND TW.CREATEDATE = #{createDate}
[*] </if>
[*] </trim>
[*] </select>
[*]
[*] <!-- auto generate default insert -->
[*] <insert id="insertDemo"
[*] parameterType="com.tx.core.mybatis.data.Demo">
[*] INSERT INTO WD_DEMO
[*] (
[*] ID,
[*] INTTEST,
[*] BOOLEANTEST,
[*] PASSOWRD,
[*] ENDDATE,
[*] ISBOOLEANOBJTEST,
[*] LASTUPDATEDATE,
[*] TESTBIGDECEIMAL,
[*] INTEGERTEST,
[*] EMAIL,
[*] NEWNAME,
[*] SUBDEMO,
[*] TESTINTEGER,
[*] CREATEDATE
[*] )
[*] VALUES
[*] (
[*] #{id},
[*] #{intTest},
[*] #{booleanTest},
[*] #{passowrd},
[*] #{endDate},
[*] #{isBooleanObjTest},
[*] #{lastUpdateDate},
[*] #{testBigDeceimal},
[*] #{integerTest},
[*] #{email},
[*] #{name},
[*] <if test="subDemo != null">
[*] #{subDemo.id},
[*] </if>
[*] <if test="subDemo == null">
[*] #{subDemo,javaType=java.lang.String},
[*] </if>
[*] #{testInteger},
[*] #{createDate}
[*] )
[*] </insert>
[*]
[*] <!-- auto generate default delete -->
[*] <delete id="deleteDemo"
[*] parameterType="com.tx.core.mybatis.data.Demo">
[*] DELETE FROM WD_DEMO TW WHERE
[*] <trim prefixOverrides="AND | OR">
[*] <if test="@com.tx.core.util.OgnlUtils@isNotEmpty(id)">
[*] AND TW.ID = #{id}
[*] </if>
[*] </trim>
[*] </delete>
[*]
[*] <!-- auto generate default update -->
[*] <update id="updateDemo"
[*] parameterType="java.util.Map">
[*] UPDATE wd_demo TW
[*] <trim prefix="SET" suffixOverrides=",">
[*] <if test="_parameter.containsKey('intTest')">
[*] INTTEST = #{intTest,javaType=int},
[*] </if>
[*] <if test="_parameter.containsKey('booleanTest')">
[*] BOOLEANTEST = #{booleanTest,javaType=boolean},
[*] </if>
[*] <if test="_parameter.containsKey('passowrd')">
[*] PASSOWRD = #{passowrd,javaType=java.lang.String},
[*] </if>
[*] <if test="_parameter.containsKey('endDate')">
[*] ENDDATE = #{endDate,javaType=java.sql.Date},
[*] </if>
[*] <if test="_parameter.containsKey('isBooleanObjTest')">
[*] ISBOOLEANOBJTEST = #{isBooleanObjTest,javaType=java.lang.Boolean},
[*] </if>
[*] <if test="_parameter.containsKey('lastUpdateDate')">
[*] LASTUPDATEDATE = #{lastUpdateDate,javaType=java.sql.Timestamp},
[*] </if>
[*] <if test="_parameter.containsKey('testBigDeceimal')">
[*] TESTBIGDECEIMAL = #{testBigDeceimal,javaType=java.math.BigDecimal},
[*] </if>
[*] <if test="_parameter.containsKey('integerTest')">
[*] INTEGERTEST = #{integerTest,javaType=java.lang.Integer},
[*] </if>
[*] <if test="_parameter.containsKey('email')">
[*] EMAIL = #{email,javaType=java.lang.String},
[*] </if>
[*] <if test="_parameter.containsKey('name')">
[*] NEWNAME = #{name,javaType=java.lang.String},
[*] </if>
[*] <if test="_parameter.containsKey('subDemo')">
[*] <if test="subDemo != null">
[*] SUBDEMO = #{subDemo.id,javaType=java.lang.String},
[*] </if>
[*] <if test="subDemo == null">
[*] SUBDEMO = #{subDemo,javaType=java.lang.String},
[*] </if>
[*] </if>
[*] <if test="_parameter.containsKey('testInteger')">
[*] TESTINTEGER = #{testInteger,javaType=java.lang.Integer},
[*] </if>
[*] <if test="_parameter.containsKey('createDate')">
[*] CREATEDATE = #{createDate,javaType=java.util.Date},
[*] </if>
[*] </trim>
[*] WHERE TW.ID = #{id}
[*] </update>
[*]
[*]</mapper>
[*]<!--
[*]sqlMap生成描述:
[*]
[*]-->
Java代码
[*]/*
[*] * 描 述: <描述>
[*] * 修 改 人:
[*] * 修改时间:
[*] * <修改描述:>
[*] */
[*]package com.tx.core.mybatis.service;
[*]
[*]import java.util.HashMap;
[*]import java.util.List;
[*]import java.util.Map;
[*]
[*]import javax.annotation.Resource;
[*]
[*]import org.apache.commons.lang.StringUtils;
[*]import org.slf4j.Logger;
[*]import org.slf4j.LoggerFactory;
[*]import org.springframework.stereotype.Component;
[*]import org.springframework.transaction.annotation.Transactional;
[*]
[*]import com.tx.core.mybatis.dao.DemoDao;
[*]import com.tx.core.mybatis.model.Demo;
[*]import com.tx.core.exceptions.parameter.ParameterIsEmptyException;
[*]import com.tx.core.paged.model.PagedList;
[*]
[*]/**
[*] * Demo的业务层
[*] * <功能详细描述>
[*] *
[*] * @author
[*] * @version [版本号, ]
[*] * @see [相关类/方法]
[*] * @since [产品/模块版本]
[*] */
[*]@Component("demoService")
[*]public class DemoService {
[*]
[*] @SuppressWarnings("unused")
[*] private Logger logger = LoggerFactory.getLogger(DemoService.class);
[*]
[*] @SuppressWarnings("unused")
[*] //@Resource(name = "serviceLogger")
[*] private Logger serviceLogger;
[*]
[*] @Resource(name = "demoDao")
[*] private DemoDao demoDao;
[*]
[*] /**
[*] * 根据Id查询Demo实体
[*] * 1、当id为empty时返回null
[*] * <功能详细描述>
[*] * @param id
[*] * @return [参数说明]
[*] *
[*] * @return Demo [返回类型说明]
[*] * @exception throws 可能存在数据库访问异常DataAccessException
[*] * @see [类、类#方法、类#成员]
[*] */
[*] public Demo findDemoById(String id) {
[*] if (StringUtils.isEmpty(id)) {
[*] return null;
[*] }
[*]
[*] Demo condition = new Demo();
[*] condition.setId(id);
[*] return this.demoDao.findDemo(condition);
[*] }
[*]
[*] /**
[*] * 根据Demo实体列表
[*] * TODO:补充说明
[*] *
[*] * <功能详细描述>
[*] * @return [参数说明]
[*] *
[*] * @return List<Demo> [返回类型说明]
[*] * @exception throws [异常类型] [异常说明]
[*] * @see [类、类#方法、类#成员]
[*] */
[*] public List<Demo> queryDemoList(/*TODO:自己定义条件*/) {
[*] //TODO:判断条件合法性
[*]
[*] //TODO:生成查询条件
[*] Map<String, Object> params = new HashMap();
[*]
[*] //TODO:根据实际情况,填入排序字段等条件,根据是否需要排序,选择调用dao内方法
[*] List<Demo> resList = this.demoDao.queryDemoList(params);
[*]
[*] return resList;
[*] }
[*]
[*] /**
[*] * 分页查询Demo实体列表
[*] * TODO:补充说明
[*] *
[*] * <功能详细描述>
[*] * @return [参数说明]
[*] *
[*] * @return List<Demo> [返回类型说明]
[*] * @exception throws [异常类型] [异常说明]
[*] * @see [类、类#方法、类#成员]
[*] */
[*] public PagedList<Demo> queryDemoPagedList(/*TODO:自己定义条件*/int pageIndex,
[*] int pageSize) {
[*] //TODO:判断条件合法性
[*]
[*] //TODO:生成查询条件
[*] Map<String, Object> params = new HashMap<String, Object>();
[*]
[*] //TODO:根据实际情况,填入排序字段等条件,根据是否需要排序,选择调用dao内方法
[*] PagedList<Demo> resPagedList = this.demoDao.queryDemoPagedList(params, pageIndex, pageSize);
[*]
[*] return resPagedList;
[*] }
[*]
[*] /**
[*] * 查询demo列表总条数
[*] * TODO:补充说明
[*] * <功能详细描述>
[*] * @return [参数说明]
[*] *
[*] * @return int [返回类型说明]
[*] * @exception throws [异常类型] [异常说明]
[*] * @see [类、类#方法、类#成员]
[*] */
[*] public int countDemo(/*TODO:自己定义条件*/){
[*] //TODO:判断条件合法性
[*]
[*] //TODO:生成查询条件
[*] Map<String, Object> params = new HashMap<String, Object>();
[*]
[*] //TODO:根据实际情况,填入排序字段等条件,根据是否需要排序,选择调用dao内方法
[*] int res = this.demoDao.countDemo(params);
[*]
[*] return res;
[*] }
[*]
[*] /**
[*] * 将demo实例插入数据库中保存
[*] * 1、如果demo为空时抛出参数为空异常
[*] * 2、如果demo中部分必要参数为非法值时抛出参数不合法异常
[*] * <功能详细描述>
[*] * @param demo [参数说明]
[*] *
[*] * @return void [返回类型说明]
[*] * @exception throws 可能存在数据库访问异常DataAccessException
[*] * @see [类、类#方法、类#成员]
[*] */
[*] @Transactional
[*] public void insertDemo(Demo demo) {
[*] //TODO:验证参数是否合法,必填字段是否填写,
[*] //如果没有填写抛出parameterIsEmptyException,
[*] //如果有参数不合法ParameterIsInvalidException
[*] if (demo == null /*TODO:|| 其他参数验证*/) {
[*] throw new ParameterIsEmptyException(
[*] "DemoService.insertDemo demo isNull.");
[*] }
[*]
[*] this.demoDao.insertDemo(demo);
[*] }
[*]
[*] /**
[*] * 根据id删除demo实例
[*] * 1、如果入参数为空,则抛出异常
[*] * 2、执行删除后,将返回数据库中被影响的条数
[*] * @param id
[*] * @return 返回删除的数据条数,<br/>
[*] * 有些业务场景,如果已经被别人删除同样也可以认为是成功的
[*] * 这里讲通用生成的业务层代码定义为返回影响的条数
[*] * @return int [返回类型说明]
[*] * @exception throws 可能存在数据库访问异常DataAccessException
[*] * @see [类、类#方法、类#成员]
[*] */
[*] @Transactional
[*] public int deleteById(String id) {
[*] if (StringUtils.isEmpty(id)) {
[*] throw new ParameterIsEmptyException(
[*] "DemoService.deleteById id isEmpty.");
[*] }
[*]
[*] Demo condition = new Demo();
[*] condition.setId(id);
[*] return this.demoDao.deleteDemo(condition);
[*] }
[*]
[*] /**
[*] * 根据id更新对象
[*] * <功能详细描述>
[*] * @param demo
[*] * @return [参数说明]
[*] *
[*] * @return boolean [返回类型说明]
[*] * @exception throws [异常类型] [异常说明]
[*] * @see [类、类#方法、类#成员]
[*] */
[*] @Transactional
[*] public boolean updateById(Demo demo) {
[*] //TODO:验证参数是否合法,必填字段是否填写,
[*] //如果没有填写抛出parameterIsEmptyException,
[*] //如果有参数不合法ParameterIsInvalidException
[*] if (demo == null || StringUtils.isEmpty(demo.getId())) {
[*] throw new ParameterIsEmptyException(
[*] "DemoService.updateById demo or demo.id is empty.");
[*] }
[*]
[*] //TODO:生成需要更新字段的hashMap
[*] Map<String, Object> updateRowMap = new HashMap<String, Object>();
[*] updateRowMap.put("id", demo.getId());
[*]
[*] //TODO:需要更新的字段
[*] updateRowMap.put("intTest", demo.getIntTest());
[*] updateRowMap.put("booleanTest", demo.isBooleanTest());
[*] updateRowMap.put("passowrd", demo.getPassowrd());
[*] updateRowMap.put("endDate", demo.getEndDate());
[*] updateRowMap.put("isBooleanObjTest", demo.getIsBooleanObjTest());
[*] updateRowMap.put("lastUpdateDate", demo.getLastUpdateDate());
[*] updateRowMap.put("testBigDeceimal", demo.getTestBigDeceimal());
[*] updateRowMap.put("integerTest", demo.getIntegerTest());
[*] updateRowMap.put("email", demo.getEmail());
[*] updateRowMap.put("name", demo.getName());
[*] //type:java.lang.String
[*] updateRowMap.put("subDemo", demo.getSubDemo());
[*] updateRowMap.put("testInteger", demo.getTestInteger());
[*] updateRowMap.put("createDate", demo.getCreateDate());
[*]
[*] int updateRowCount = this.demoDao.updateDemo(updateRowMap);
[*]
[*] //TODO:如果需要大于1时,抛出异常并回滚,需要在这里修改
[*] return updateRowCount >= 1;
[*] }
[*]}
Java代码
[*]/*
[*] * 描 述: <描述>
[*] * 修 改 人:
[*] * 修改时间:
[*] * <修改描述:>
[*] */
[*]package com.tx.core.mybatis.dao.impl;
[*]
[*]import java.util.List;
[*]import java.util.Map;
[*]
[*]import javax.annotation.Resource;
[*]
[*]import org.springframework.stereotype.Component;
[*]
[*]import com.tx.core.mybatis.dao.DemoDao;
[*]import com.tx.core.mybatis.data.Demo;
[*]import com.tx.core.mybatis.model.Order;
[*]import com.tx.core.mybatis.support.MyBatisDaoSupport;
[*]import com.tx.core.paged.model.PagedList;
[*]
[*]/**
[*] * Demo持久层
[*] * <功能详细描述>
[*] *
[*] * @author
[*] * @version [版本号, 2012-12-11]
[*] * @see [相关类/方法]
[*] * @since [产品/模块版本]
[*] */
[*]@Component("demoDao")
[*]public class DemoDaoImpl implements DemoDao {
[*]
[*] @Resource(name = "myBatisDaoSupport")
[*] private MyBatisDaoSupport myBatisDaoSupport;
[*]
[*] /**
[*] * @param condition
[*] */
[*] @Override
[*] public void insertDemo(Demo condition) {
[*] this.myBatisDaoSupport.insertUseUUID("demo.insertDemo", condition, "id");
[*] }
[*]
[*] /**
[*] * @param condition
[*] * @return
[*] */
[*] @Override
[*] public int deleteDemo(Demo condition) {
[*] return this.myBatisDaoSupport.delete("demo.deleteDemo", condition);
[*] }
[*]
[*] /**
[*] * @param condition
[*] * @return
[*] */
[*] @Override
[*] public Demo findDemo(Demo condition) {
[*] return this.myBatisDaoSupport.<Demo> find("demo.findDemo", condition);
[*] }
[*]
[*] /**
[*] * @param params
[*] * @return
[*] */
[*] @Override
[*] public List<Demo> queryDemoList(Map<String, Object> params) {
[*] return this.myBatisDaoSupport.<Demo> queryList("demo.queryDemo",
[*] params);
[*] }
[*]
[*] /**
[*] * @param params
[*] * @param orderList
[*] * @return
[*] */
[*] @Override
[*] public List<Demo> queryDemoList(Map<String, Object> params,
[*] List<Order> orderList) {
[*] return this.myBatisDaoSupport.<Demo> queryList("demo.queryDemo",
[*] params,
[*] orderList);
[*] }
[*]
[*] /**
[*] * @param params
[*] * @return
[*] */
[*] @Override
[*] public int countDemo(Map<String, Object> params) {
[*] return this.myBatisDaoSupport.<Integer> find("demo.queryDemoCount",
[*] params);
[*] }
[*]
[*] /**
[*] * @param params
[*] * @param pageIndex
[*] * @param pageSize
[*] * @return
[*] */
[*] @Override
[*] public PagedList<Demo> queryDemoPagedList(Map<String, Object> params,
[*] int pageIndex, int pageSize) {
[*] return this.myBatisDaoSupport.<Demo> queryPagedList("demo.queryDemo",
[*] params,
[*] pageIndex,
[*] pageSize);
[*] }
[*]
[*] /**
[*] * @param params
[*] * @param pageIndex
[*] * @param pageSize
[*] * @param orderList
[*] * @return
[*] */
[*] @Override
[*] public PagedList<Demo> queryDemoPagedList(Map<String, Object> params,
[*] int pageIndex, int pageSize, List<Order> orderList) {
[*] return this.myBatisDaoSupport.<Demo> queryPagedList("demo.queryDemo",
[*] params,
[*] pageIndex,
[*] pageSize,
[*] orderList);
[*] }
[*]
[*] /**
[*] * @param updateRowMap
[*] * @return
[*] */
[*] @Override
[*] public int updateDemo(Map<String, Object> updateRowMap) {
[*] return this.myBatisDaoSupport.update("demo.updateDemo", updateRowMap);
[*] }
[*]}
页:
[1]