一、mybatis版本
个人建议使用:
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis</artifactId>
- <version>3.1.1</version>
- </dependency>
在mybatis3.1.1中优化了批量处理的效率
在底层statementHandle中提供了更加灵活的扩展性
主要是体现在插件,拦截器能做的,能够获取到的参数更多的方面
二、与spring集合的配置
- <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。
具体实现这里贴一个:
- /**
- * 批量插入数据 <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;
- }
这里的实现写得稍微复杂一些,
主要是,针对有些情况如果其中某条失败,还想后续数据能够继续成功提交的情况进行支持。
四、数据库物理分页,这个网上的文章也比较多,这里也提一下。在前人的基础上,我的物理分页类实现为:
- <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()[0];
- 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
这里贴一下自动生成的代码:
- public static void main(String[] args) throws Exception{
- JpaEntityFreeMarkerGenerator g = new JpaEntityFreeMarkerGenerator();
- g.generate(Demo.class, "d:/mybatis");
- }
- <?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生成描述:
- -->
- /*
- * 描 述: <描述>
- * 修 改 人:
- * 修改时间:
- * <修改描述:>
- */
- 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;
- }
- }
- /*
- * 描 述: <描述>
- * 修 改 人:
- * 修改时间:
- * <修改描述:>
- */
- 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);
- }
- }
相关推荐
在使用MyBatis时,我们需要理解其核心组件和工作原理,以便更好地进行数据库操作。 一、MyBatis核心配置文件 MyBatis的核心配置文件通常命名为`mybatis-config.xml`,它是整个MyBatis系统的总配置文件,包含了数据...
Java开发系列MyBatis使用以及实现Java开发系列MyBatis使用以及实现Java开发系列MyBatis使用以及实现Java开发系列MyBatis使用以及实现Java开发系列MyBatis使用以及实现Java开发系列MyBatis使用以及实现Java开发系列...
mybatis简单使用mybatis简单使用demomybatis简单使用demomybatis简单使用demomybatis简单使用demomybatis简单使用demomybatis简单使用demomybatis简单使用demomybatis简单使用demomybatis简单使用demomybatis简单...
mybatis使用案例,包含源码,配置等 mybatis使用案例,包含源码,配置等 mybatis使用案例,包含源码,配置等 mybatis使用案例,包含源码,配置等 mybatis使用案例,包含源码,配置等
在使用MyBatis时,你需要在项目中引入此jar包,并在Spring或者其他的初始化代码中配置MyBatis的SqlSessionFactory,它是MyBatis的主要入口点,用于创建SqlSession对象,进而执行SQL操作。 再来看`mysql-connector-...
MyBatis可以使用简单的XML或注解进行配置和原始映射,将接口和Java的POJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。 标题“mybatis demo mybatis 实例”指的是一个MyBatis的学习示例项目,...
标题“hibernate与mybatis一起使用取长补短”暗示了在一个项目中同时采用这两种框架,旨在充分利用它们各自的优点,以提升项目的性能和灵活性。 Hibernate是一款强大的ORM框架,它提供了完整的对象模型支持,包括...
MyBatis使用的jar包和源码包,开发中会经常用到,从官网上下的,可以保证资源的正确性
推荐新手小白使用的mybatis思维图,适合快速上手。使用Xmind绘制,打开请使用Xmind(免费版)。不足之处,请指出!
MyBatis可以使用简单的XML或注解进行配置和原始映射,将接口和Java的POJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。 在"mybatis使用实例"中,我们主要会探讨以下几个关键知识点: 1. **...
MyBatis 是一款优秀的持久层框架,可以很方便的在java中实现对数据库的操作。 MyBatis 可以将sql语句映射为java接口函数,直接对实体进行操作。 MyBatis 的映射类(Mapper)在映射sql语句时有两种方式,一种是xml...
在本示例中,我们将不使用Mapper接口来演示如何通过MyBatis进行基本的数据库查询,这对于理解MyBatis的核心工作原理是非常有帮助的。 首先,MyBatis的核心组件包括XML配置文件、SqlSessionFactory和SqlSession。XML...
本部分主要关注如何单独使用MyBatis,不涉及与其他框架的集成。 1. **MyBatis简介** MyBatis消除了几乎所有的JDBC代码和手动设置参数以及获取结果集。它将SQL语句与Java代码分离,提供了一个更简洁、更易于维护的...
关于springboot 和mybatis使用添加mybatis依赖 首先是springboot项目,依赖mybatis 。环境不多说,主要看配置。
MyBatis Generator 使用手册 MyBatis Generator 是 MyBatis 的代码生成工具,旨在通过反射数据库表结构生成对应的Java代码,简化开发过程,提高开发效率。本手册将指导用户如何使用 MyBatis Generator 生成代码,...
深入理解SpringBoot中关于Mybatis使用方法 Spring Boot是一款流行的Java框架,MyBatis是一款流行的ORM框架,两者结合使用可以简化数据库操作。下面将深入理解SpringBoot中关于Mybatis使用方法。 Orm框架的本质是...
- 在Spring中,使用SqlSessionFactoryBean创建SqlSessionFactory,通过配置数据源、MyBatis配置文件等信息。 - MyBatis的Mapper接口可以通过`@Mapper`注解标识,Spring会自动扫描并将其代理为Mapper实例。 - 使用...
MyBatis 枚举全面使用指南 抓下来打包成了HTML文件, 方便离线观看
MyBatis 可以使用简单的 XML 或注解用于配置和原始映射,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。 ### 关键知识点 1. **MyBatis 使用环境搭建** - MyBatis 可以与 ...
在实际项目中,MyBatis 的使用能够有效地简化数据库操作,提高开发效率。以下是 MyBatis 在项目中的核心知识点: 1. **XML 配置与注解方式**:MyBatis 提供了 XML 配置文件和注解两种方式来定义 SQL 映射。XML 配置...