Mybatis-3.3.0官方文档-中文.pdf
mybatis异常invalidcomparison:java.util.Dateandj。。。

mybatis异常invalidcomparison:java.util.Dateandj。
开发中改动mapper⽂件后需要重新编译发布, 由于⼯程⽐较⼤⾮常耗时, 所以为⽅便快速测试⼲脆写了⼀个⼩java⼯程. ⼯程中⽤到的dao, mapper和实体类都是从⼯程中拷出来的, 数据库也是同⼀个. 但是遇到⼀个⽐较奇怪的问题实体类中有⼀个属性private Date createTime;对应该属性数据库中定义的是create_time datetimemapper中该属性映射的定义<result column="create_time" property="createTime" jdbcType="TIMESTAMP" />以下是mapper中对应Dao⽅法SQL语句<select id="selectByCreateTime" resultMap="userMap">select * from user<where><if test="createTime != null and createTime !='' " >date(create_time) = date(#{createTime,jdbcType=TIMESTAMP})</if></where></select>其中date()函数只是⽤来把年⽉⽇时分秒的⽇期截取为年⽉⽇, 这个对于该异常没有任何影响在测试类中创建实体并为其属性赋值User user=new User();user.setCreateTime(new SimpleDateFormat("yyyy-MM-dd").parse("2016-01-18"));然后执⾏查询⽅法dao.selectByCreateTime(user)的时候就报错了1 Exception in thread "main" org.apache.ibatis.exceptions.PersistenceException:2 ### Error querying database. Cause: ng.IllegalArgumentException: invalid comparison: java.util.Date and ng.String3 ### Cause: ng.IllegalArgumentException: invalid comparison: java.util.Date and ng.String4 at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)5 at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:122)6 at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:113)7 at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:122)8 at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:64)9 at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:53)10 at com.sun.proxy.$Proxy0.selectByCreateTime(Unknown Source)11 at mybatis.Test.buyerInfoTimeTest(Test.java:53)12 at mybatis.Test.main(Test.java:39)13 Caused by: ng.IllegalArgumentException: invalid comparison: java.util.Date and ng.String14 at pareWithConversion(OgnlOps.java:92)15 at org.apache.ibatis.ognl.OgnlOps.isEqual(OgnlOps.java:142)16 at org.apache.ibatis.ognl.OgnlOps.equal(OgnlOps.java:794)17 at org.apache.ibatis.ognl.ASTNotEq.getValueBody(ASTNotEq.java:53)18 at org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)19 at org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:258)20 at org.apache.ibatis.ognl.ASTAnd.getValueBody(ASTAnd.java:61)21 at org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)22 at org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:258)23 at org.apache.ibatis.ognl.Ognl.getValue(Ognl.java:494)24 at org.apache.ibatis.ognl.Ognl.getValue(Ognl.java:458)25 at org.apache.ibatis.scripting.xmltags.OgnlCache.getValue(OgnlCache.java:44)26 at org.apache.ibatis.scripting.xmltags.ExpressionEvaluator.evaluateBoolean(ExpressionEvaluator.java:32)27 at org.apache.ibatis.scripting.xmltags.IfSqlNode.apply(IfSqlNode.java:34)28 at org.apache.ibatis.scripting.xmltags.MixedSqlNode.apply(MixedSqlNode.java:33)29 at org.apache.ibatis.scripting.xmltags.TrimSqlNode.apply(TrimSqlNode.java:55)30 at org.apache.ibatis.scripting.xmltags.MixedSqlNode.apply(MixedSqlNode.java:33)31 at org.apache.ibatis.scripting.xmltags.DynamicSqlSource.getBoundSql(DynamicSqlSource.java:41)32 at org.apache.ibatis.mapping.MappedStatement.getBoundSql(MappedStatement.java:280)33 at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:80)34 at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:120)35 ... 7more看样⼦是因为类型不符合, 但是想了想, Date类型对应MySQL的datetime, 以及mapper中jdbcType都没问题啊. ⽽且完全⼀样的东西在原⼯程中是完全正常的. 既然都是⼀样的代码, 那就找找俩⼯程有啥不⼀样的吧⾸先是mysql jar版本不同. 换成原⼯程中的版本也⽆效. 然后是mybatis jar版本不⼀样, 换成原⼯程中的版本问题就解决了!原⼯程中配置的是mybatis-3.2.8, ⽽我测试⼯程中⽤的是mybatis-3.3.0.后来在⽹上找了⼀下才知道, 原来这是mybatis 3.3.0中对于时间参数进⾏⽐较时的⼀个bug. 如果拿传⼊的时间类型参数与空字符串''进⾏对⽐判断则会引发异常. 所以在上⾯的代码中去该该判断, 只保留⾮空判断就正常了<if test="createTime != null and createTime !='' " >date(create_time) = date(#{createTime,jdbcType=TIMESTAMP})</if>改为<if test="createTime != null">date(create_time) = date(#{createTime,jdbcType=TIMESTAMP})</if>。
mybatis-generator数据库注释实体类生成以及generatorConfig文件配置

mybatis-generator数据库注释实体类⽣成以及generatorConfig⽂件配置项⽬⾥新建表时model,mapper以及mapper.xml基本都是⽤Mybatis Generator(以下简称为MBG)⾃动⽣成的,但是MBG⾃动⽣成的model的注释实在有点⾮⼈类,⾄少中国⼈是完全接受不了的,在配置中禁⽤掉注释吧,倒是简单了,可是⽣成的model类光秃秃的,啥都没有,字段⽅法没有注释,使⽤很不⽅便,别⼈看也不知道这个字段是啥含义,到最后还是要⾃⼰添加,⼀张表多点⼏⼗个字段,特么添加累死了,不能这么⼲,得想法⼦,百度了⼀下⽹上,基本有两种⽅法,第⼀种,就是直接修改MGB的源代码,第⼆种就是⾃⼰写⼀个类实现CommentGenerator接⼝,先说⾃⼰写⼀个新类实现CommentGenerator接⼝的⽅法来使⾃动⽣成的model类含有中⽂注释吧.⼀:⾸先你得有⼀个maven项⽬,这个我就不多提⼆:通过mybatis generator实现⾃动⽣产model,mapper以及mapper.xml,具体参考 Intellij IDEA 14中使⽤MyBatis-generator ⾃动⽣成MyBatis代码三:通过查看你会发现,注解类是在mybatis-generator-core jar包中 org.mybatis.generator.internal包下的DefaultCommentGenerator类。
那么这⾥有两种⽅法,⼀种是重写DefaultCommentGenerator类,另外⼀种中修改jar包中的源码,但很明显第⼀种⽅法⽐较简单,这⾥也只介绍第⼀种⽅法的写法。
3.1在源代码中新建⼀个类MyCommentGenerator,实现CommentGenerator接⼝,类的代码如下:package org.mybatis.generator;/*** Created by 草帽boy on 2017/2/16.* mybatis generator ⾃定义comment⽣成器.* 基于MBG 1.3.2.* @author ZhangAY 2016-02-19*/import java.text.SimpleDateFormat;import java.util.Date;import java.util.Properties;import mentGenerator;import org.mybatis.generator.api.IntrospectedColumn;import org.mybatis.generator.api.IntrospectedTable;import org.mybatis.generator.api.dom.java.*;import org.mybatis.generator.api.dom.xml.XmlElement;import org.mybatis.generator.config.MergeConstants;import org.mybatis.generator.config.PropertyRegistry;import org.mybatis.generator.internal.util.StringUtility;public class MyCommentGenerator implements CommentGenerator {private Properties properties;private Properties systemPro;private boolean suppressDate;private boolean suppressAllComments;private String currentDateStr;public MyCommentGenerator() {super();properties = new Properties();systemPro = System.getProperties();suppressDate = false;suppressAllComments = false;currentDateStr = (new SimpleDateFormat("yyyy-MM-dd")).format(new Date());}public void addJavaFileComment(CompilationUnit compilationUnit) {// add no file level comments by defaultreturn;}/*** Adds a suitable comment to warn users that the element was generated, and* when it was generated.*/public void addComment(XmlElement xmlElement) {return;}public void addRootComment(XmlElement rootElement) {// add no document level comments by defaultreturn;}public void addConfigurationProperties(Properties properties) {this.properties.putAll(properties);suppressDate = StringUtility.isTrue(properties.getProperty(MENT_GENERATOR_SUPPRESS_DATE));suppressAllComments = StringUtility.isTrue(properties.getProperty(MENT_GENERATOR_SUPPRESS_ALL_COMMENTS));}/*** This method adds the custom javadoc tag for. You may do nothing if you do* not wish to include the Javadoc tag - however, if you do not include the* Javadoc tag then the Java merge capability of the eclipse plugin will* break.** @param javaElement the java element*/protected void addJavadocTag(JavaElement javaElement, boolean markAsDoNotDelete) {javaElement.addJavaDocLine(" *");StringBuilder sb = new StringBuilder();sb.append(" * ");sb.append(MergeConstants.NEW_ELEMENT_TAG);if (markAsDoNotDelete) {sb.append(" do_not_delete_during_merge");}String s = getDateString();if (s != null) {sb.append(' ');sb.append(s);}javaElement.addJavaDocLine(sb.toString());}/*** This method returns a formated date string to include in the Javadoc tag* and XML comments. You may return null if you do not want the date in* these documentation elements.** @return a string representing the current timestamp, or null*/protected String getDateString() {String result = null;if (!suppressDate) {result = currentDateStr;}return result;}public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable) { if (suppressAllComments) {return;}StringBuilder sb = new StringBuilder();innerClass.addJavaDocLine("/**");sb.append(" * ");sb.append(introspectedTable.getFullyQualifiedTable());sb.append(" ");sb.append(getDateString());innerClass.addJavaDocLine(sb.toString());innerClass.addJavaDocLine(" */");}public void addEnumComment(InnerEnum innerEnum, IntrospectedTable introspectedTable) { if (suppressAllComments) {return;}StringBuilder sb = new StringBuilder();innerEnum.addJavaDocLine("/**");// addJavadocTag(innerEnum, false);sb.append(" * ");sb.append(introspectedTable.getFullyQualifiedTable());innerEnum.addJavaDocLine(sb.toString());innerEnum.addJavaDocLine(" */");}public void addFieldComment(Field field, IntrospectedTable introspectedTable,IntrospectedColumn introspectedColumn) {if (suppressAllComments) {return;}StringBuilder sb = new StringBuilder();field.addJavaDocLine("/**");sb.append(" * ");sb.append(introspectedColumn.getRemarks());field.addJavaDocLine(sb.toString());// addJavadocTag(field, false);field.addJavaDocLine(" */");}public void addFieldComment(Field field, IntrospectedTable introspectedTable) {if (suppressAllComments) {return;}StringBuilder sb = new StringBuilder();field.addJavaDocLine("/**");sb.append(" * ");sb.append(introspectedTable.getFullyQualifiedTable());field.addJavaDocLine(sb.toString());field.addJavaDocLine(" */");}public void addModelClassComment(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) { }public void addGeneralMethodComment(Method method, IntrospectedTable introspectedTable) {if (suppressAllComments) {return;}// method.addJavaDocLine("/**");// addJavadocTag(method, false);// method.addJavaDocLine(" */");}public void addGetterComment(Method method, IntrospectedTable introspectedTable,IntrospectedColumn introspectedColumn) {if (suppressAllComments) {return;}method.addJavaDocLine("/**");StringBuilder sb = new StringBuilder();sb.append(" * ");sb.append(introspectedColumn.getRemarks());method.addJavaDocLine(sb.toString());sb.setLength(0);sb.append(" * @return ");sb.append(introspectedColumn.getActualColumnName());sb.append(" ");sb.append(introspectedColumn.getRemarks());method.addJavaDocLine(sb.toString());// addJavadocTag(method, false);method.addJavaDocLine(" */");}public void addSetterComment(Method method, IntrospectedTable introspectedTable,IntrospectedColumn introspectedColumn) {if (suppressAllComments) {return;}method.addJavaDocLine("/**");StringBuilder sb = new StringBuilder();sb.append(" * ");sb.append(introspectedColumn.getRemarks());method.addJavaDocLine(sb.toString());Parameter parm = method.getParameters().get(0);sb.setLength(0);sb.append(" * @param ");sb.append(parm.getName());sb.append(" ");sb.append(introspectedColumn.getRemarks());method.addJavaDocLine(sb.toString());// addJavadocTag(method, false);method.addJavaDocLine(" */");}public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable, boolean markAsDoNotDelete) {if (suppressAllComments) {return;}StringBuilder sb = new StringBuilder();innerClass.addJavaDocLine("/**");sb.append(" * ");sb.append(introspectedTable.getFullyQualifiedTable());innerClass.addJavaDocLine(sb.toString());sb.setLength(0);sb.append(" * @author ");sb.append(systemPro.getProperty(""));sb.append(" ");sb.append(currentDateStr);// addJavadocTag(innerClass, markAsDoNotDelete);innerClass.addJavaDocLine(" */");}}3.2.再新建⼀个类StartUp,⽤于运⾏项⽬,(若是集成Eclipse,可直接运⾏操作,查看mybatis与eclipse的集成,这⾥不介绍了)也就是运⾏StartUp类就会直接⽣成model,mapper以及mapper.xml,类的代码如下:package org.mybatis.generator;/*** Created by 草帽boy on 2017/2/16.* 启动⽂件,只需要点击运⾏就⾏*/import java.io.File;import java.io.IOException;import .URISyntaxException;import java.sql.SQLException;import java.util.ArrayList;import java.util.List;import org.mybatis.generator.api.MyBatisGenerator;import org.mybatis.generator.config.Configuration;import org.mybatis.generator.config.xml.ConfigurationParser;import org.mybatis.generator.exception.InvalidConfigurationException;import org.mybatis.generator.exception.XMLParserException;import org.mybatis.generator.internal.DefaultShellCallback;public class StartUp {public static void main(String[] args) throws URISyntaxException {try {List<String> warnings = new ArrayList<String>();boolean overwrite = true;//直接获取generatorConfig.xml的⽂件路径根据具体情况查看File configFile = new File("E:\\IDEAWorkPlace\\GraduationDesign\\CourseDesignManageSystem\\20170122\\CourseDesignManage\\src\\main\\resources\\generatorConfig.xml"); ConfigurationParser cp = new ConfigurationParser(warnings);Configuration config = cp.parseConfiguration(configFile);DefaultShellCallback callback = new DefaultShellCallback(overwrite);MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);myBatisGenerator.generate(null);} catch (SQLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();} catch (InvalidConfigurationException e) {e.printStackTrace();} catch (XMLParserException e) {e.printStackTrace();}}}3.3 另外需要简单修改⼀下generatorConfig.xml中的注释配置<commentGenerator type="org.mybatis.generator.MyCommentGenerator"><!-- <property name="suppressDate" value="true"/><!– 是否去除⾃动⽣成的注释 true:是: false:否 –><property name="suppressAllComments" value="false"/>--></commentGenerator>commentGenerator 的type是你刚刚重构的MyCommentGenerator类的位置3.4其中我的⽂件结构如下:四:点击运⾏StartUp,你会发现model,mapper以及mapper.xml都已经产⽣,其中实体类的运⾏的结果如下注意:若是出现中⽂乱码,在generatorConfig.xml⽂件中增加以下配置<property name="javaFileEncoding" value="UTF-8"/>1.以下是generatorConfig.xml配置⽂件<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE generatorConfiguration PUBLIC "-////DTD MyBatis Generator Configuration 1.0//EN" "/dtd/mybatis-generator-config_1_0.dtd" > <generatorConfiguration ><!-- 数据库驱动包位置 --><classPathEntrylocation="D:\repository\mysql\mysql-connector-java\5.1.34\mysql-connector-java-5.1.34.jar"/><context id="context1"><property name="javaFileEncoding" value="UTF-8"/><commentGenerator type="com.wareic.utils.MyCommentGenerator"></commentGenerator><!-- <commentGenerator>是否去除⾃动⽣成的注释 true:是: false:否<property name="suppressAllComments" value="true"/></commentGenerator> --><!-- 数据库链接URL、⽤户名、密码 --><jdbcConnection driverClass="com.mysql.jdbc.Driver"connectionURL="jdbc:mysql://17.16.32.2:3306/db_wareic" userId="root" password="123456"/><!-- ⽣成模型的包名和位置 wareic为项⽬名称 --><javaModelGenerator targetPackage="com.wareic.model" targetProject="wareic/src/main/java"/><!-- ⽣成的映射⽂件报名和位置 --><sqlMapGenerator targetPackage="com.wareic.mapper" targetProject="wareic/src/main/java"/><!-- ⽣成DAO的包名和位置 --><javaClientGenerator targetPackage="com.wareic.mapper" targetProject="wareic/src/main/java" type="XMLMAPPER"/><!-- 要⽣成的那些表(更改tableName 和domainObjectName 就可以了) --><table schema="db_wareic" tableName="t_product" domainObjectName="Product" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"><!-- <columnOverride column="FILMID" property="FILMID" /> --></table></context></generatorConfiguration>2.执⾏startUp类型中的main函数3.MyBatis Generator官⽹:---------------------作者:王卫东来源:CSDN原⽂:https:///wwd0501/article/details/76618363版权声明:本⽂为博主原创⽂章,转载请附上博⽂链接!。
SpringBoot+Mybatis-plus多数据源配置(MySQL、Sqlserver)

SpringBoot+Mybatis-plus多数据源配置(MySQL、Sqlserver)前⾔:本章案例利⽤dynamic-datasource-spring-boot-starter集成多数据源,mybaits-plus采⽤3.3.0版本,主要讲述配置多数据源,其案例中也包含了逻辑删除、攻击SQL阻断解析器、p6spySQL性能分析打印、事务以及分页和乐观锁插件。
dynamic-datasource-spring-boot-starter 是⼀个基于springboot的快速集成多数据源的启动器,其⽀持 Jdk 1.7+, SpringBoot 1.4.x 1.5.x 2.0.x。
⼀、pom.xml<!--代码简化,⼯具相关 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!--SQLServer 驱动--><dependency><groupId>com.microsoft.sqlserver</groupId><artifactId>sqljdbc4</artifactId><version>4.0</version><scope>runtime</scope></dependency><!--mysql 驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.3.0</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>2.4.2</version></dependency><dependency><groupId>p6spy</groupId><artifactId>p6spy</artifactId><version>3.8.0</version></dependency>⼆、application.ymlserver:port: 8888servlet:context-path: /serverspring:application:name: springboot-manyDataSourcesdatasource:p6spy: truedynamic:datasource:master:driver-class-name: com.p6spy.engine.spy.P6SpyDriverurl: jdbc:p6spy:mysql://localhost:3306/datasourceName?characterEncoding=utf8&useSSL=false&serverTimezone=GMTusername: rootpassword: root# url: jdbc:mysql://localhost:3306/ datasourceName?characterEncoding=utf8&useSSL=false&serverTimezone=GMT# username: root# password: root# driver-class-name: com.mysql.cj.jdbc.Driverdb2:driver-class-name: com.p6spy.engine.spy.P6SpyDriverurl: jdbc:p6spy:sqlserver://localhost:1433;DatabaseName=datasourceNameusername: sapassword: root# url: jdbc:sqlserver://localhost:1433;DatabaseName= datasourceName# username: sa# password: root# driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver#⽇志logging:level:com.example.demo : debug三、spy.propertiesmodulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory# ⾃定义⽇志打印logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger#⽇志输出到控制台appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger# 使⽤⽇志系统记录 sql#appender=com.p6spy.engine.spy.appender.Slf4JLogger# 设置 p6spy driver 代理deregisterdrivers=true# 取消JDBC URL前缀useprefix=true# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.excludecategories=info,debug,result,commit,resultset# ⽇期格式dateformat=yyyy-MM-dd HH:mm:ss# 实际驱动可多个#driverlist=org.h2.Driver# 是否开启慢SQL记录outagedetection=true# 慢SQL记录标准 2 秒outagedetectioninterval=2四、MybatisPlusConfig@Configuration@EnableTransactionManagement//开启事务public class MybatisPlusConfig {/*** mybatisplus 分页插件* @return*/@Beanpublic PaginationInterceptor paginationInterceptor(){PaginationInterceptor paginationInterceptor = new PaginationInterceptor();List<ISqlParser> sqlParserList = new ArrayList<>();// 攻击 SQL 阻断解析器、加⼊解析链;防⽌⼩⽩或者恶意进⾏delete update 全表操作。
Mybatis-3.3.0官方文档-中文.pdf

来获取。
Copyright © 2010–2015 . All rights reserved.XML 配置文件(configuration XML)中包含了对 MyBatis 系统的核心设置,包含获取数据库连接实例的数据源(DataSource)和决定事务范围和控制方式的事务管理器(TransactionManager)。
XML 配置文件的详细内容后面再探讨,这里先给出一个简单的示例:当然,还有很多可以在XML 文件中进行配置,上面的示例指出的则是最关键的部分。
要注意 XML 头部的声明,用来验证 XML 文档正确性。
environment 元素体中包含了事务管理和连接池的配置。
mappers 元素则是包含一组 mapper 映射器(这些 mapper 的XML 文件包含了 SQL 代码和映射定义信息)。
不使用 XML 构建 SqlSessionFactory如果你更愿意直接从 Java 程序而不是 XML 文件中创建 configuration,或者创建你自己的 configuration 构建器,MyBatis 也提供了完整的配置类,提供所有和 XML 文件相同功能的配置项。
注意该例中,configuration 添加了一个映射器类(mapper class)。
映射器类是 Java 类,它们包含 SQL 映射语句的注解从而避免了 XML 文件的依赖。
不过,由于 Java 注解的一些限制加之某些 MyBatis 映射的复杂性,XML 映射对于大多数高级映射(比如:嵌套Join 映射)来说仍然是必须的。
有鉴于此,如果存在一个对等的 XML 配置文件的话,MyBatis 会自动查找并加载它(这种情况下,BlogMapper.xml 将会基于类路径和 BlogMapper.class 的类名被加载进来)。
具体细节稍后讨论。
从 SqlSessionFactory 中获取 SqlSession既然有了 SqlSessionFactory ,顾名思义,我们就可以从中获得 SqlSession 的实例了。
mybatis中文版教程

MyBatis Spring1.0.0-RC3参考文档MyBatis 社区()Copyright © 2010本文档的拷贝仅允许您个人使用或分发给其他用户,但是不能收取任何费用,后期的发布无论是印刷版或电子版,也会进行版权声明。
本文档由南磊(nanlei1987@)翻译目录第一章介绍 (3)1.1 整合动机 (3)1.2 要求 (3)1.3 感谢 (3)第二章入门 (4)2.1 安装 (4)2.2 快速创建 (4)第三章SqlSessionFactoryBean (6)3.1 创建 (6)3.2 属性 (6)第四章事务 (8)4.1 标准配置 (8)4.2 容器管理事务 (8)第五章使用SqlSession (9)5.1 SqlSessionSupport (9)5.2 SqlSessionTemplate (9)第六章MapperFactoryBean (11)6.1 创建 (11)6.2 注入映射器 (11)6.3 自动配置 (12)第七章使用MyBatis API (13)第八章示例代码 (14)第一章介绍1.1 整合动机正如第二版,Spring仅支持iBatis2。
那么我们就想将MyBatis3的支持加入到Spring3.0(参考Spring的Jira的问题)中。
不幸的是,Spring 3.0的开发在MyBatis 3.0官方发布前就结束了。
因为Spring开发团队不想发布一个基于非发行版的MyBatis的整合支持,那么Spring 官方的支持就不得不等到至少3.1版本了。
要在Spring中支持MyBatis,MyBatis社区认为现在应该是自己团结贡献者和有兴趣的人一起来开始进行Spring和MyBatis整合的时候了。
这个小类库就来创建丢失的粘贴Spring和MyBtatis这两个流行框架的胶水。
减少用户不得不来配置MyBatis和Spring 3.X上下文环境的样板和冗余代码。
Mybatis的配置文件和映射文件详解

Mybatis的配置⽂件和映射⽂件详解⼀、Mybatis的全局配置⽂件1、SqlMapConfig.xml(名称可变)是mybatis的全局配置⽂件,配置内容如下:properties(属性)settings(全局配置参数)typeAliases(类型别名)typeHandlers(类型处理器)objectFactory(对象⼯⼚)plugins(插件)environments(环境集合属性对象)environment(环境⼦属性对象)transactionManager(事务管理)dataSource(数据源)mappers(映射器)2、properties将数据库连接参数单独配置在db.properties(名称可变)中,放在类路径下。
这样只需要在SqlMapConfig.xml中加载db.properties的属性值。
这样在SqlMapConfig.xml中就不需要对数据库连接参数硬编码。
将数据库连接参数只配置在db.properties中,原因:⽅便对参数进⾏统⼀管理,其它xml可以引⽤该db.properties例如:db.propertiesjdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/mybatisername=rootjdbc.password=root相应的SqlMapConfig.xml<properties resource="db.properties"/><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${ername}"/><property name="password" value="${jdbc.password}"/></dataSource></environment></environments>注意: MyBatis 将按照下⾯的顺序来加载属性:⾸先、在properties标签中指定的属性⽂件⾸先被读取。
【MyBatis系列3】最全MyBatis中XML映射文件(Mapper)标签分析及示例

【MyBatis系列3】最全MyBatis中XML映射⽂件(Mapper)标签分析及⽰例前⾔MyBatis的强⼤之处就在于它的映射器⽂件,⽽这也正是MyBatis的魔⼒所在,对于任何MyBatis的使⽤者来说,MyBatis的映射⽂件是必须要掌握的。
Mapper⽂件标签Mapper中⼀个提供了9个顶层标签,除了1个已经过期的我们不需要去了解,另外8个都是必须要掌握的,只要熟练掌握了标签的使⽤,使⽤MyBatis才能如鱼得⽔。
接下来我们就⼀个个来分析⼀下这些标签的使⽤。
<cache> – 该命名空间的缓存配置。
<cache-ref> – 引⽤其它命名空间的缓存配置。
<resultMap> – 描述如何从数据库结果集中加载对象,是最复杂也是最强⼤的元素。
<parameterMap> – ⽼式风格的参数映射。
此元素已被废弃,并可能在将来被移除!请使⽤⾏内参数映射。
⽂档中不会介绍此元素。
<sql> – 可被其它语句引⽤的可重⽤语句块。
<insert> – 映射插⼊语句。
<update> – 映射更新语句。
<delete> – 映射删除语句。
<select> – 映射查询语句。
selectselect⽤来映射查询语句,是我们使⽤最多的⼀种标签,也是最复杂的⼀种标签。
⽐如下⾯就是⼀个简单的select标签的使⽤<select id="listUserByUserName" parameterType="String" resultType="lwUser">select user_id,user_name from lw_user where user_name=#{userName}</select>select标签内,提供了⼀些⼆级标签,下⾯就列举出了全部的⼆级标签:<selectid="selectPerson"parameterType="int"parameterMap="deprecated"resultType="hashmap"resultMap="personResultMap"flushCache="false"useCache="true"timeout="10000"fetchSize="256"statementType="PREPARED"resultSetType="FORWARD_ONLY"databaseId="mysql"resultOrdered="false"resultSets="xxx,xxx"lang=""></select>id必选标签。
Mybatis之XML、注解

Mybatis之XML、注解前⾔ 上篇简单介绍了Mybatis的简单实⽤,本篇先对上次实验环境的⼀些内容进⾏优化,然后验证Mybatis的XML配置以及注解⽅式。
实验环境优化 数据库配置 在mybatis的配置⽂件中,引⼊数据库配置⽂件db.properties,然后修改配置⽂件driver=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost:3306/mybatisname=rootpassword=adminmybatis配置⽂件 mybatis-config.xml<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configurationPUBLIC "-////DTD Config 3.0//EN""/dtd/mybatis-3-config.dtd"><configuration><!-- 数据库配置⽂件 --><properties resource="db.properties"/><!--development : 开发模式work : ⼯作模式--><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="${driver}"/><property name="url" value="${url}"/><property name="username" value="${name}"/><property name="password" value="${password}"/></dataSource></environment></environments><mappers><mapper resource="com/lion/mapper/UserMapper.xml"/></mappers></configuration>实体类定义别名 没有为实体定义别名时,在sql映射xml中应⽤实体时,⽐如parameterType resultType 中就需要配置实体的全路径名(全限定名)。
MyBatis3用户指南中文版

MyBatis3.2.2中文官方文档

MyBatis用户指南中文版最近更新: 02 四月2013Version: 3.2.2PDF Creator :Esin.z2013/04/10内容目录MyBatis (1)简介 (3)什么是MyBatis? (3)Help make this documentation better (3)关于翻译 (3)入门 (3)从XML 中构建SqlSessionFactory (3)不使用XML 构建SqlSessionFactory (4)从SqlSessionFactory 中获取SqlSession (5)探究已映射的SQL 语句 (5)范围和生命周期 (7)XML 映射配置文件 (8)properties (9)settings (10)typeAliases (14)typeHandlers (15)Handling Enums (18)objectFactory (20)plugins (20)environments (21)databaseIdProvider (24)mappers (25)Mapper XML 文件 (26)select (27)insert, update and delete (28)sql (31)Parameters (32)Result Maps (33)Auto-mapping (49)缓存 (50)动态SQL (52)if (53)choose, when, otherwise (53)trim, where, set (54)foreach (56)bind (56)Multi-db vendor support (57)Pluggable Scripting Languages For Dynamic SQL (57)Java API (58)应用目录结构 (58)SqlSessions (59)Statement Builders (72)SelectBuilder (72)SqlBuilder (75)Logging (76)Logging Configuration (77)简介什么是 MyBatis?MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架。
MyBatis3整合Spring3项目依赖类库jar包之间的依赖

12-5-6项目依赖项目依赖compile以下是这一项目的编译依赖列表。
编译和运行本应用需要这些依赖。
GroupId ArtifactId版本类型License备注org.mybatis mybatis 3.1.1jar The Apache Software License, Version 2.0No org.springframework spring-context 3.1.1.RELEASE jar The Apache Software License, Version 2.0No org.springframework spring-core 3.1.1.RELEASE jar The Apache Software License, Version 2.0No org.springframework spring-jdbc 3.1.1.RELEASE jar The Apache Software License, Version 2.0No org.springframework spring-tx 3.1.1.RELEASE jar The Apache Software License, Version 2.0No org.springframework.batch spring-batch-core 2.1.8.RELEASE jar Apache 2.0Yestest以下是这一项目的测试依赖列表。
这些依赖仅仅在编译和运行本应用中的单元测试时需要。
GroupId ArtifactId版本类型Licensecglib cglib 2.2.2jar ASF 2.0com.mockrunner mockrunner-jdk1.5-j2ee1.30.4jar Mockrunner License, based on Apache Software License, version 1.1javax.transaction transaction-api 1.1jar-junit junit 4.10jar Common Public License Version 1.0log4j log4j 1.2.16jar The Apache Software License, Version 2.0ognl ognl 2.6.9jar BSD Licenseorg.hsqldb hsqldb 2.2.4jar HSQLDB License, a BSD open source licenseorg.springframework spring-test 3.1.1.RELEASE jar The Apache Software License, Version 2.0项目传递依赖以下是本项目的传递依赖列表。
MyBatis官方中文文档

提示 命名空间的一点注释
命名空间(Namespaces)在之前版本的 MyBatis 中是可选的,容易引起混淆因此是没有益处的。现在的命名空 间则是必须的,目的是希望能比只是简单的使用更长的完全限定名来更进一步区分语句。 命名空间使得你所见到的接口绑定成为可能,尽管你觉得这些东西未必用得上,你还是应该遵循这里的规定以防哪 天你改变了主意。出于长远考虑,使用命名空间,并将它置于合适的 Java 包命名空间之下,你将拥有一份更加整 洁的代码并提高了 MyBatis 的可用性。 命名解析:为了减少输入量,MyBatis 对所有的命名配置元素(包括语句,结果映射,缓存等)使用了如下的命名 解析规则。 完全限定名(比如“com.mypackage.MyMapper.selectAllThings”)将被直接查找并且找到即用。 短名称(比如“selectAllThings”)如果全局唯一也可以作为一个单独的引用。如果不唯一,有两个或两个以上的相 同名称(比如“com.foo.selectAllThings ”和“com.bar.selectAllThings”),那么使用时就会收到错误报告说短名称 是不唯一的,这种情况下就必须使用完全限定名。
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-////DTD Config 3.0//EN" "/dtd/mybatis-3-config.dtd"> <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments> <mappers> <mapper resource="org/mybatis/example/BlogMapper.xml"/> </mappers> </configuration>
Spring Security-3.0.1 中文官方文档(翻译版)

Spring Security-3.0.1 中文官方文档(翻译版)这次发布的Spring Security-3.0.1 是一个bug fix 版,主要是对3.0 中存在的一些问题进行修正。
文档中没有添加新功能的介绍,但是将之前拼写错误的一些类名进行了修正,建议开发者以这一版本的文档为参考。
另:Spring Security 从2010-01-01 以后,版本控制从SVN 换成了GIT,我们在翻译文档的时候,主要是根据SVN 的变化来进行文档内容的比对,这次换成GIT 后,感觉缺少了之前那种文本比对工具,如果有对GIT 熟悉的朋友,还请推荐一下文本比对的工具,谢谢。
序言I. 入门1. 介绍1.1. Spring Security 是什么?1.2. 历史1.3. 发行版本号1.4. 获得Spring Security1.4.1. 项目模块1.4.1.1. Core - spring-security-core.jar1.4.1.2. Web - spring-security-web.jar1.4.1.3. Config - spring-security-config.jar1.4.1.4. LDAP - spring-security-ldap.jar1.4.1.5. ACL - spring-security-acl.jar1.4.1.6. CAS - spring-security-cas-client.jar1.4.1.7. OpenID - spring-security-openid.jar1.4.2. 获得源代码2. Security 命名空间配置2.1. 介绍2.1.1. 命名空间的设计2.2. 开始使用安全命名空间配置2.2.1. 配置web.xml2.2.2. 最小<http> 配置2.2.2.1. auto-config 包含了什么?2.2.2.2. 表单和基本登录选项2.2.3. 使用其他认证提供器2.2.3.1. 添加一个密码编码器2.3. 高级web 特性2.3.1. Remember-Me 认证2.3.2. 添加HTTP/HTTPS 信道安全2.3.3. 会话管理2.3.3.1. 检测超时2.3.3.2. 同步会话控制2.3.3.3. 防止Session 固定攻击2.3.4. 对OpenID 的支持2.3.4.1. 属性交换2.3.5. 添加你自己的filter2.3.5.1. 设置自定义AuthenticationEntryPoint2.4. 保护方法2.4.1. <global-method-security> 元素2.4.1.1. 使用protect-pointcut 添加安全切点2.5. 默认的AccessDecisionManager2.5.1. 自定义AccessDecisionManager2.6. 验证管理器和命名空间3. 示例程序3.1. Tutorial 示例3.2. Contacts3.3. LDAP 例子3.4. CAS 例子3.5. Pre-Authentication 例子4. Spring Security 社区4.1. 任务跟踪4.2. 成为参与者4.3. 更多信息II. 结构和实现5. 技术概述5.1. 运行环境5.2. 核心组件5.2.1. SecurityContextHolder, SecurityContext 和Authentication 对象5.2.1.1. 获得当前用户的信息5.2.2. UserDetailsService5.2.3. GrantedAuthority5.2.4. 小结5.3. 验证5.3.1. 什么是Spring Security 的验证呢?5.3.2. 直接设置SecurityContextHolder 的内容5.4. 在web 应用中验证5.4.1. ExceptionTranslationFilter5.4.2. AuthenticationEntryPoint5.4.3. 验证机制5.4.4. 在请求之间保存SecurityContext 。
mybatis的两种分页方式:RowBounds和PageHelper

mybatis的两种分页⽅式:RowBounds和PageHelper1.原理:拦截器。
使⽤⽅法:RowBounds:在mapper.java中的⽅法中传⼊RowBounds对象//接⼝⽅法public List<Honor> getHonorList(HashMap<String, Object> maps,RowBounds rowBounds);//调⽤⽅法RowBounds rowBounds = new RowBounds(offset, page.getPageSize()); // offset起始⾏ // limit是当前页显⽰多少条数据RowBounds rowBounds = new RowBounds(2, 2);List<Honor> honors = studentMapper.getHonorList(maps,rowBounds);Mybatis使⽤RowBounds对象进⾏分页,它是针对ResultSet结果集执⾏的内存分页,⽽⾮物理分页,可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使⽤分页插件来完成物理分页。
分页插件的基本原理是使⽤Mybatis提供的插件接⼝,实现⾃定义插件,在插件的拦截⽅法内拦截待执⾏的sql,然后重写sql,根据dialect⽅⾔,添加对应的物理分页语句和物理分页参数。
举例:select * from student,拦截sql后重写为:select t.* from (select * from student)t limit 0,102.Mybatis的插件 PageHelper 分页查询使⽤⽅法Mybatis的⼀个插件,PageHelper,⾮常⽅便mybatis分页查询。
国内⽜⼈的⼀个开源项⽬,有兴趣的可以去看源码,都有中⽂注释(ps:某些源码⼀⼤堆英⽂,痛哭流涕!)在github上仓库地址为:Mybatis-PageHelper它⽀持基本主流与常⽤的数据库,这可以在它的⽂档上看到。
mybatis-中文文档

mybatis-中⽂⽂档1 Mybatis的介绍Mybatis就是⼀个封装jdbc的持久层框架,它和hibernate都属于ORM框架,但是具体的说,hibernate是⼀个完全的orm框架,⽽mbatis是⼀个不完全的orm框架.Mybatis让程序员只关注sql本⾝,⽽不需要去关注如连接的创建、statement 的创建等操作。
Mybatis会将输⼊参数据、输出结果进⾏映射MyBatis 本是的⼀个开源项⽬, 2010年这个项⽬由apache software foundation 迁移到了google code,并且改名为MyBatis,实质上Mybatis 对ibatis进⾏⼀些改进。
MyBatis是⼀个优秀的持久层框架,它对jdbc的操作数据库的过程进⾏封装,使开发者只需要关注 SQL 本⾝,⽽不需要花费精⼒去处理例如注册驱动、创建connection、创建statement、⼿动设置参数、结果集检索等jdbc繁杂的过程代码。
Mybatis通过xml或注解的⽅式将要执⾏的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进⾏映射⽣成最终执⾏的sql语句,最后由mybatis框架执⾏sql并将结果映射成java对象并返回。
2 分析jdbc的问题2.1 原⽣态的jdbc代码publicstaticvoid main(String[] args) {Connection connection = null;PreparedStatement preparedStatement = null;ResultSet resultSet = null;try {//1、加载数据库驱动Class.forName("oracle.jdbc.OracleDriver");//2、通过驱动管理类获取数据库链接connection = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE", "xiaoming", "root");//3、定义sql语句 ?表⽰占位符String sql = "select * from t_user where t_name = ?";//4、获取预处理statementpreparedStatement = connection.prepareStatement(sql);//5、设置参数,第⼀个参数为sql语句中参数的序号(从1开始),第⼆个参数为设置的参数值preparedStatement.setString(1, "程冠西");//6、向数据库发出sql执⾏查询,查询出结果集resultSet = preparedStatement.executeQuery();//7、遍历查询结果集while(resultSet.next()){System.out.println(resultSet.getString("t_id")+""+resultSet.getString("t_name")); }} catch (Exception e) {e.printStackTrace();}finally{//8、释放资源if(resultSet!=null){try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}if(preparedStatement!=null){try {preparedStatement.close();} catch (SQLException e) {e.printStackTrace();}}if(connection!=null){try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}}2.2 问题总结1、在创建连接时,存在硬编码配置⽂件2、在执⾏statement时存在硬编码配置⽂件(映射⽂件)3、频繁的开启的关闭数据库连接,会造成数据库性能下降。
Mybatis之foreach用法----List、Array、Map三种类型遍历

Mybatis之foreach⽤法----List、Array、Map三种类型遍历在mybatis的xml⽂件中构建动态sql语句时,经常会⽤到标签遍历查询条件。
特此记录下不同情况下书写⽅式!-------仅供⼤家参考------1. foreach元素的属性collection: 需做foreach(遍历)的对象,作为⼊参时,list、array对象时,collection属性值分别默认⽤"list"、"array"代替,Map对象没有默认的属性值。
但是,在作为⼊参时可以使⽤@Param(“keyName”)注解来设置⾃定义collection属性值,设置keyName后,list、array 会失效;item:集合元素迭代时的别名称,该参数为必选项;index:在list、array中,index为元素的序号索引。
但是在Map中,index为遍历元素的key值,该参数为可选项;open:遍历集合时的开始符号,通常与close=")"搭配使⽤。
使⽤场景IN(),values()时,该参数为可选项;separator:元素之间的分隔符,类⽐在IN()的时候,separator=",",最终所有遍历的元素将会以设定的(,)逗号符号隔开,该参数为可选项;close:遍历集合时的结束符号,通常与open="("搭配使⽤,该参数为可选项;2.foreach时,collection属性值的三种情况:如果传⼊的参数类型为List时,collection的默认属性值为list,同样可以使⽤@Param注解⾃定义keyName;如果传⼊的参数类型为array时,collection的默认属性值为array,同样可以使⽤@Param注解⾃定义keyName;如果传⼊的参数类型为Map时,collection的属性值可为三种情况:(1.遍历map.keys;2.遍历map.values;3.遍历map.entrySet()),稍后会在代码中⽰例;3.代码⽰例:3.1 collection属性值类型为List:Mapper接⼝定义的⽅法:UserList为模拟返回的数据对象List<UserList> getUserInfo(@Param("userName") List<String> userName);Mapper.xml 动态sql构建,Mapper接⼝的⽅法名和xml⽂件的id值,必须⼀⼀对应,否则会报错:-----建议做if test="xxxx !=null and xxxx.size()>0"的校验,⽐较严谨。
MybatisPlus主键策略(type=IdType.ASSIGN_ID等详解)

MybatisPlus主键策略(type=IdType.ASSIGN_ID等详解)三,主键策略我们可以通过@TableId注解的类型属性来设置主键id的增长策略,⼀共有⼏个多个主键策略,可根据情况⾃由配置。
1,ASSIGN_ID(雪花算法)如果不设置类型值,默认则使⽤IdType.ASSIGN_ID策略(⾃3.3.0起)。
该策略会使⽤雪花算法⾃动⽣成主键ID,主键类型为长或字符串(分别对应的MySQL的表字段为BIGINT和VARCHAR)提⽰:该策略使⽤接⼝IdentifierGenerator的⽅法nextId(以实现类为DefaultIdentifierGenerator雪花算法),下⾯是雪花算法介绍:雪花算法(雪花)是微博开源的分布式ID⽣成算法其核⼼思想就是:使⽤⼀个64位的长型的数字作为全局唯⼀ID。
在分布式系统中的应⽤⼗分⼴泛,且ID引⼊了时间戳,基本上保持⾃增的。
1个2 3 4 5 6 7 8@Datapublic class UserInfo {//指定主键⽣成策略使⽤雪花算法(默认策略) @TableId(type = IdType.ASSIGN_ID)private Long id;private String userName;private String passWord;}2,ASSIGN_UUID(排除中划线的UUID)如果使⽤IdType.ASSIGN_UUID策略,并重新⾃动⽣成排除中划线的UUID作为主键。
主键类型为String,对应MySQL的表分段为VARCHAR(32)提⽰:该策略使⽤接⼝IdentifierGenerator的⽅法nextUUID1个2 3 4 5 6 7 8@Datapublic class UserInfo {//指定主键⽣成策略为不含中划线的UUID @TableId(type = IdType.ASSIGN_UUID) private String id;private String userName;private String passWord;}3,AUTO(数据库ID⾃增)对于像MySQL这样的⽀持主键⾃动递增的数据库,我们可以使⽤IdType.AUTO策略。
org.apache.ibatis.exceptions.PersistenceExcep。。。

org.apache.ibatis.exceptions.PersistenceExcep。
Caused by: org.apache.ibatis.exceptions.PersistenceException:### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: Connections could not be acquired from the underlying database!### The error may exist in file [D:\tomcat\apache-tomcat-8.0.20\webapps\JobSubmission2_war\WEB-INF\classes\mapper\StudentMapper.xml]### The error may involve com.duowenjia.mapper.StudentMapper.studentLogin### The error occurred while executing a query### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: Connections could not be acquired from the underlying database!at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) ~[mybatis-3.3.0.jar:3.3.0]at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:122) ~[mybatis-3.3.0.jar:3.3.0]at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:113) ~[mybatis-3.3.0.jar:3.3.0]at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:73) ~[mybatis-3.3.0.jar:3.3.0]at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_181]at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_181]at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_181]at ng.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_181]at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:386) ~[mybatis-spring-1.2.3.jar:1.2.3] ... 49 common frames omittedCaused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: Connections could not be acquired from the underlying database!at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:80) ~[spring-jdbc-4.1.7.RELEASE.jar:4.1.7.RELEASE]at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:82) ~[mybatis-spring-1.2.3.jar:1.2.3]at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:68) ~[mybatis-spring-1.2.3.jar:1.2.3]at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:315) ~[mybatis-3.3.0.jar:3.3.0]at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:75) ~[mybatis-3.3.0.jar:3.3.0]at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:61) ~[mybatis-3.3.0.jar:3.3.0]at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:303) ~[mybatis-3.3.0.jar:3.3.0]at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:154) ~[mybatis-3.3.0.jar:3.3.0]at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:102) ~[mybatis-3.3.0.jar:3.3.0]at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:82) ~[mybatis-3.3.0.jar:3.3.0]at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:120) ~[mybatis-3.3.0.jar:3.3.0]... 56 common frames omitted今天在使⽤ssm框架时出现了⼀个错误,之前都是好好的,突然出现了错误。
mybatis-plus通用字段自动化(如逻辑删除和更新时间等)

mybatis-plus通⽤字段⾃动化(如逻辑删除和更新时间等)⼀般来说某些项⽬⽐较规范的情况下,⼤多数表都会有逻辑删除字段和通⽤字段,例如更新时间,创建时间,更新⼈,创建⼈等等,但是在代码开发上会产⽣很多冗余的代码,逻辑删除的话,⾃⼰写⽐较繁琐,⽽且容易有遗漏逻辑。
本来打算⾃⼰写切⾯去实现,偶然发现mybatis-plus已经帮封装实现了,试了⼀下,很好⽤,所以分享⼀下。
逻辑删除逻辑删除的意思就是某些业务表,在⽤户删除某条数据的时候,不真正删除,⽽是将此数据某字段改成类似“已删除”,⽽查询语句、更新语句等会忽略此条被逻辑删除的数据。
这⾥就不多介绍mybatis-plus的基础使⽤了,没接触过的⼩伙伴可以去官⽹研究⼀下,都是中⽂,很好看懂。
贴⼀下我们mybatis-plus的pom依赖:<!-- mybatis plus 核⼼依赖 --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.0</version></dependency><!-- mybatis plus 代码⽣成器依赖 --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.4.0</version></dependency><!-- 代码⽣成器模板 --><dependency><groupId>org.apache.velocity</groupId><artifactId>velocity-engine-core</artifactId><version>2.1</version></dependency>逻辑删除⽐较简单,在3.3版本之后只要两步:1.在配置⽂件中加⼊:mybatis-plus:global-config:db-config:logic-delete-field: deleted # 全局逻辑删除的实体字段名logic-delete-value: 1 # 逻辑已删除值(默认为 1)logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)这⾥的deleted就是数据库表中表⽰逻辑删除与否的字段名,⼀般都是tinyint或者boolean,如果是boolean,logic-delete-value和logic-not-delete-value设置成true和false就⾏。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
来获取。
Copyright © 2010–2015 . All rights reserved.XML 配置文件(configuration XML)中包含了对 MyBatis 系统的核心设置,包含获取数据库连接实例的数据源(DataSource)和决定事务范围和控制方式的事务管理器(TransactionManager)。
XML 配置文件的详细内容后面再探讨,这里先给出一个简单的示例:当然,还有很多可以在XML 文件中进行配置,上面的示例指出的则是最关键的部分。
要注意 XML 头部的声明,用来验证 XML 文档正确性。
environment 元素体中包含了事务管理和连接池的配置。
mappers 元素则是包含一组 mapper 映射器(这些 mapper 的XML 文件包含了 SQL 代码和映射定义信息)。
不使用 XML 构建 SqlSessionFactory如果你更愿意直接从 Java 程序而不是 XML 文件中创建 configuration,或者创建你自己的 configuration 构建器,MyBatis 也提供了完整的配置类,提供所有和 XML 文件相同功能的配置项。
注意该例中,configuration 添加了一个映射器类(mapper class)。
映射器类是 Java 类,它们包含 SQL 映射语句的注解从而避免了 XML 文件的依赖。
不过,由于 Java 注解的一些限制加之某些 MyBatis 映射的复杂性,XML 映射对于大多数高级映射(比如:嵌套Join 映射)来说仍然是必须的。
有鉴于此,如果存在一个对等的 XML 配置文件的话,MyBatis 会自动查找并加载它(这种情况下,BlogMapper.xml 将会基于类路径和 BlogMapper.class 的类名被加载进来)。
具体细节稍后讨论。
从 SqlSessionFactory 中获取 SqlSession既然有了 SqlSessionFactory ,顾名思义,我们就可以从中获得 SqlSession 的实例了。
SqlSession 完全包含了面向数据库执行SQL 命令所需的所有方法。
你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。
例如:诚然这种方式能够正常工作,并且对于使用旧版本 MyBatis 的用户来说也比较熟悉,不过现在有了一种更直白的方式。
使用对于给定语句能够合理描述参数和返回值的接口(比如说BlogMapper.class),你现在不但可以执行更清晰和类型安全的代码,而且还不用担心易错的字符串字面值以及强制类型转换。
例如:现在我们来探究一下这里到底是怎么执行的。
探究已映射的 SQL 语句现在,或许你很想知道 SqlSession 和 Mapper 到底执行了什么操作,而 SQL 语句映射是个相当大的话题,可能会占去文档的大部分篇幅。
不过为了让你能够了解个大概,这里会给出几个例子。
在上面提到的两个例子中,一个语句应该是通过 XML 定义,而另外一个则是通过注解定义。
先看 XML 定义这个,事实上 MyBatis 提供的全部特性可以利用基于 XML 的映射语言来实现,这使得 MyBatis 在过去的数年间得以流行。
如果你以前用过 MyBatis,这个概念应该会比较熟悉。
不过 XML 映射文件已经有了很多的改进,随着文档的进行会愈发清晰。
这里给出一个基于 XML 映射语句的示例,它应该可以满足上述示例中 SqlSession 的调用。
对于这个简单的例子来说似乎有点小题大做了,但实际上它是非常轻量级的。
在一个 XML 映射文件中,你想定义多少个映射语句都是可以的,这样下来,XML 头部和文档类型声明占去的部分就显得微不足道了。
文件的剩余部分具有很好的自解释性。
在命名空间“com.mybatis.example.BlogMapper”中定义了一个名为“selectBlog”的映射语句,这样它就允许你使用指定的完全限定名“org.mybatis.example.BlogMapper.selectBlog”来调用映射语句,就像上面的例子中做的那样:你可能注意到这和使用完全限定名调用 Java 对象的方法是相似的,之所以这样做是有原因的。
这个命名可以直接映射到在命名空间中同名的 Mapper 类,并在已映射的 select 语句中的名字、参数和返回类型匹配成方法。
这样你就可以向上面那样很容易地调用这个对应 Mapper 接口的方法。
不过让我们再看一遍下面的例子:第二种方法有很多优势,首先它不是基于字符串常量的,就会更安全;其次,如果你的 IDE 有代码补全功能,那么你可以在有了已映射SQL 语句的基础之上利用这个功能。
提示命名空间的一点注释命名空间(Namespaces)在之前版本的 MyBatis 中是可选的,容易引起混淆因此是没有益处的。
现在的命名空间则是必须的,目的是希望能比只是简单的使用更长的完全限定名来区分语句更进一步。
命名空间使得你所见到的接口绑定成为可能,尽管你觉得这些东西未必用得上,你还是应该遵循这里的规定以防哪天你改变了主意。
出于长远考虑,使用命名空间,并将它置于合适的 Java 包命名空间之下,你将拥有一份更加整洁的代码并提高了 MyBatis 的可用性。
命名解析:为了减少输入量,MyBatis 对所有的命名配置元素(包括语句,结果映射,缓存等)使用了如下的命名解析规则。
命名解析:完全限定名(比如“com.mypackage.MyMapper.selectAllThings”)将被直接查找并且找到即用。
短名称(比如“selectAllThings”)如果全局唯一也可以作为一个单独的引用。
如果不唯一,有两个或两个以上的相同名称(比如“com.foo.selectAllThings ”和“com.bar.selectAllThings”),那么使用时就会收到错误报告说短名称是不唯一的,这种情况下就必须使用完全限定名。
对于像 BlogMapper 这样的映射器类(Mapper class)来说,还有另一招来处理。
它们的映射的语句可以不需要用 XML 来做,取而代之的是可以使用 Java 注解。
比如,上面的 XML 示例可被替换如下:对于简单语句来说,注解使代码显得更加简洁,然而 Java 注解对于稍微复杂的语句就会力不从心并且会显得更加混乱。
因此,如果你需要做很复杂的事情,那么最好使用 XML 来映射语句。
选择何种方式以及映射语句的定义的一致性对你来说有多重要这些完全取决于你和你的团队。
换句话说,永远不要拘泥于一种方式,你可以很轻松的在基于注解和 XML 的语句映射方式间自由移植和切换。
范围(Scope)和生命周期理解我们目前已经讨论过的不同范围和生命周期类是至关重要的,因为错误的使用会导致非常严重的并发问题。
提示对象生命周期和依赖注入框架依赖注入框架可以创建线程安全的、基于事务的 SqlSession 和映射器(mapper)并将它们直接注入到你的 bean 中,因此可以直接忽略它们的生命周期。
如果对如何通过依赖注入框架来使用 MyBatis 感兴趣可以研究一下 MyBatis-Spring 或 MyBatis-Guice 两个子项目。
SqlSessionFactoryBuilder这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。
因此 SqlSessionFactoryBuilder 实例的最佳范围是方法范围(也就是局部方法变量)。
你可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但是最好还是不要让其一直存在以保证所有的 XML 解析资源开放给更重要的事情。
SqlSessionFactorySqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由对它进行清除或重建。
使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。
因此SqlSessionFactory 的最佳范围是应用范围。
有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。
SqlSession每个线程都应该有它自己的 SqlSession 实例。
SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的范围是请求或方法范围。
绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。
也绝不能将 SqlSession 实例的引用放在任何类型的管理范围中,比如 Serlvet 架构中的 HttpSession。
如果你现在正在使用一种 Web 框架,要考虑SqlSession 放在一个和 HTTP 请求对象相似的范围中。
换句话说,每次收到的 HTTP 请求,就可以打开一个 SqlSession,返回一个响应,就关闭它。
这个关闭操作是很重要的,你应该把这个关闭操作放到 finally 块中以确保每次都能执行关闭。
下面的示例就是一个确保 SqlSession 关闭的标准模式:在你的所有的代码中一致性地使用这种模式来保证所有数据库资源都能被正确地关闭。
映射器实例(Mapper Instances)映射器是创建用来绑定映射语句的接口。
映射器接口的实例是从 SqlSession 中获得的。
因此从技术层面讲,映射器实例的最大范围是和 SqlSession 相同的,因为它们都是从 SqlSession 里被请求的。
尽管如此,映射器实例的最佳范围是方法范围。
也就是说,映射器实例应该在调用它们的方法中被请求,用过之后即可废弃。
并不需要显式地关闭映射器实例,尽管在整个请求范围(request scope)保持映射器实例也不会有什么问题,但是很快你会发现,像 SqlSession 一样,在这个范围上管理太多的资源的话会难于控制。
所以要保持简单,最好把映射器放在方法范围(method scope)内。
下面的示例就展示了这个实践:Copyright © 2010–2015 . All rights reserved.aggressiveLazyLoading当启用时,对任意延迟属性的调用会使带有延迟加载属性的对象完整加载;反之,每种属性将会按需加载。
true | false truemultipleResultSetsEnabled是否允许单一语句返回多结果集(需要兼容驱动)。
true | false trueuseColumnLabel使用列标签代替列名。