解决:java.lang.NoSuchMethodException: tk.mybatis.mapper.provider.base.BaseSelectProvider
控制台报错: java.lang.NoSuchMethodException:tk.mybatis.mapper.provider.base.BaseSelectProvider.<init>() 浏览器访问:http://localhost:8081/category/list?pid=0 解决办法: 应该导入import tk.mybatis.spring.annotation.MapperScan这个包。 from:https://blog.csdn.net/qq_37495786/article/details/83448614
View DetailsMybatis通用Mapper(tk.mybatis)的使用
使用Mybatis的开发者,大多数都会遇到一个问题,就是要写大量的SQL在xml文件中,除了特殊的业务逻辑SQL之外,还有大量结构类似的增删改查SQL。而且,当数据库表结构改动时,对应的所有SQL以及实体类都需要更改。这工作量和效率的影响或许就是区别增删改查程序员和真正程序员的屏障。这时,通用Mapper便应运而生……
View DetailsMySql Usage Notes
Unsigned Fields MySql supports both signed, and unsigned, numeric fields. These are not JDBC types, so MyBatis generator cannot automatically account for these types of fields. The Java data types are always signed. This can lead to a loss of precision when using unsigned fields. The solution is to provide a <columnOverride> for any unsigned numeric field in MySql. Here is an example of how to deal with an unsigned bigint field in MySql:
1 2 3 |
<table tableName="ALLTYPES" > <columnOverride column="UNSIGNED_BIGINT_FIELD" javaType="java.lang.Object" jdbcType="LONG" /> </table> |
You will have to cast the returned value to the appropriate type yourself (in this […]
View DetailsException in thread “main“ java.lang.NoClassDefFoundError: org/mybatis/generator/api/dom/xml/Element
错误日志:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
Exception in thread "main" java.lang.NoClassDefFoundError: org/mybatis/generator/api/dom/xml/Element at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:348) at org.mybatis.generator.internal.ObjectFactory.internalClassForName(ObjectFactory.java:144) at org.mybatis.generator.internal.ObjectFactory.createInternalObject(ObjectFactory.java:180) at org.mybatis.generator.internal.ObjectFactory.createCommentGenerator(ObjectFactory.java:241) at org.mybatis.generator.config.Context.getCommentGenerator(Context.java:266) at org.mybatis.generator.codegen.mybatis3.model.SimpleModelGenerator.getCompilationUnits(SimpleModelGenerator.java:51) at org.mybatis.generator.codegen.mybatis3.IntrospectedTableMyBatis3Impl.getGeneratedJavaFiles(IntrospectedTableMyBatis3Impl.java:181) at org.mybatis.generator.config.Context.generateFiles(Context.java:460) at org.mybatis.generator.api.MyBatisGenerator.generate(MyBatisGenerator.java:262) at org.mybatis.generator.api.MyBatisGenerator.generate(MyBatisGenerator.java:132) at com.weChat.MybatisStartup.GeneratorDisplay.generator(GeneratorDisplay.java:33) at com.weChat.MybatisStartup.GeneratorDisplay.main(GeneratorDisplay.java:17) Caused by: java.lang.ClassNotFoundException: org.mybatis.generator.api.dom.xml.Element at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ... 13 more |
原因及其解决办法: 错误日志中很明显的说是 mybatis 的代码自动生成依赖 generator 的 api 存在问题,查看 pom.xml 文件的依赖,发现引用是正常的,也就是说引用和使用都不可能有问题,因为我并没有直接操作 generator 的 api ,那么只可能是版本的问题了,而我的这个依赖的版本是 1.4.0 ,是目前最高的版本: 所以只有可能是我的版本太高了,下降一个版本试试,换成1.3.7的果然就好了!看来做这个不能写的太满,不然很容易给自己埋雷啊! from:https://www.cnblogs.com/90s-ITBoy/p/13388452.html
View Details在 Gradle 中使用 MyBatis Generator
在 Intellij IDEA 中结合 Gradle 使用 MyBatis Generator 逆向生成代码 Info: JDK 1.8 Gradle 2.14 Intellij IDEA 2016.3 前言 由于 IDEA 的教程较少,且 MyBatis Generator 不支持 Gradle 直接运行,因此这次是在自己折腾项目过程中,根据一些参考资料加上自己的实践得出的结论,并附上相应的 Demo 可供自己未来参考,也与大家分享。 本文的 Demo 也可以当作工具直接导入 IDEA,加上自己的数据库信息即可生成代码。 创建项目 详细的创建步骤可以参考使用 Gradle 构建 Struts 2 Web 应用中「新建 Gradle Web 项目」一节即可。当创建完毕,需要等待 Gradle 联网构建,由于国内网络因素,可能需要稍作等待。当构建完成,目录结构应如下图一致: Gradle 构建完成 配置依赖 这里需要使用 MyBatis Generator,MySQL 驱动,以及 MyBatis Mapper。由于代码生成单独运行即可,不需要参与到整个项目的编译,因此在 build.gradle 中添加配置:
1 2 3 |
configurations { mybatisGenerator } |
在 Maven Repository (http://mvnrepository.com/) 分别搜索依赖: org.mybatis.generator mysql-connector-java tk.mybatis:mapper 依赖的版本并不是局限于某个特定版本,可以选择适时相应的更新版本。添加到 build.gradle 的 dependencies 中(注意前面需将「compile group:」改为 「mybatisGenerator」):
1 2 3 4 5 6 7 |
dependencies { testCompile group: 'junit', name: 'junit', version: '4.11' mybatisGenerator 'org.mybatis.generator:mybatis-generator-core:1.3.5' mybatisGenerator 'mysql:mysql-connector-java:5.1.40' mybatisGenerator 'tk.mybatis:mapper:3.3.9' } |
设置数据库信息 在 resources 下,新建 mybatis 文件夹,并新建 config.properties 和 generatorConfig.xml,文件结构如下: 配置文件目录 在 config.properties 中配置数据库和要生成的 […]
View Detailscom.mysql.cj.jdbc.Driver和com.mysql.jdbc.Driver的区别
今天写东西测试的时候发现一个问题,如下: application.yml中数据源是这样配置的: 第一反应就是记忆中连接mysql的驱动不都是com.mysql.jdbc.Driver吗?com.mysql.cj.jdbc.Driver是什么鬼? 后来查看了一下才知道 这个跟驱动的依赖版本有关
1 2 3 4 5 |
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> |
com.mysql.cj.jdbc.Driver是mysql-connector-java 6 中的特性,相比mysql-connector-java 5 多了一个时区:serverTimezone,把数据源配置的驱动改一下就好了 这样启动就不会再报:Loading class com.mysql.jdbc.Driver'. This is deprecated. The new driver class iscom.mysql.cj.jdbc.Driver’. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary. 使用UTC会有8小时的时差(中国快全球标准8小时,比如:全球标准当前是上午1点,中国时间则为上午9点),可设置为北京时间东八区GMT%2B8 或者上海时间Asia/Shanghai。 总结: com.mysql.jdbc.Driver和mysql-connector-java 5一起用。 com.mysql.cj.jdbc.Driver和mysql-connector-java 6 一起用。 from:https://blog.csdn.net/weixin_43770545/article/details/90486809
View Details首次使用gradle出现Could not find method leftShift() for arguments解决办法
1、在win10桌面编写test.gradle脚本,里面内容如下
1 2 3 |
task helloword << { println 'Hello gradle qick start' } |
2、在doc命令窗口执行脚本
1 |
gradle -q helloword |
结果如下: 3、解决办法 查看为gradle 5.0中 << 已经过时了,即(<<),是推荐使用doLast 来替代的,可以通过降低gradle版本(比如4.10.1)或者使用doLast解决 重新修改脚本如下,执行后正常输出’Hello gradle qick start
1 2 3 |
task helloword { println 'Hello gradle qick start' } |
或者
1 2 3 4 5 |
task helloword { doLast{ println 'Hello gradle qick start' } } |
人要耐得住寂寞,才能守得住繁华。人生最痛苦的就是拿不起放不下,不属于自己的快乐,及时放手也许是一种解脱,生活中没有谁对谁错,只有适不适合。当发现很多已经改变,更要面对的是事实。 from:https://www.cnblogs.com/yuanchaoyong/p/11421595.html
View Details使用Mybatis-Generator自动生成Dao、Model、Mapping相关文件
Mybatis属于半自动ORM,在使用这个框架中,工作量最大的就是书写Mapping的映射文件,由于手动书写很容易出错,我们可以利用Mybatis-Generator来帮我们自动生成文件。 1、相关文件 关于Mybatis-Generator的下载可以到这个地址:https://github.com/mybatis/generator/releases 由于我使用的是Mysql数据库,这里需要在准备一个连接mysql数据库的驱动jar包 以下是相关文件截图: 和Hibernate逆向生成一样,这里也需要一个配置文件: generatorConfig.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <!--数据库驱动--> <classPathEntry location="mysql-connector-java-5.0.8-bin.jar"/> <context id="DB2Tables" targetRuntime="MyBatis3"> <commentGenerator> <property name="suppressDate" value="true"/> <property name="suppressAllComments" value="true"/> </commentGenerator> <!--数据库链接地址账号密码--> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost/mymessages" userId="root" password="root"> </jdbcConnection> <javaTypeResolver> <property name="forceBigDecimals" value="false"/> </javaTypeResolver> <!--生成Model类存放位置--> <javaModelGenerator targetPackage="lcw.model" targetProject="src"> <property name="enableSubPackages" value="true"/> <property name="trimStrings" value="true"/> </javaModelGenerator> <!--生成映射文件存放位置--> <sqlMapGenerator targetPackage="lcw.mapping" targetProject="src"> <property name="enableSubPackages" value="true"/> </sqlMapGenerator> <!--生成Dao类存放位置--> <javaClientGenerator type="XMLMAPPER" targetPackage="lcw.dao" targetProject="src"> <property name="enableSubPackages" value="true"/> </javaClientGenerator> <!--生成对应表及类名--> <table tableName="message" domainObjectName="Messgae" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table> </context> </generatorConfiguration> |
需要修改文件配置的地方我都已经把注释标注出来了,这里的相关路径(如数据库驱动包,生成对应的相关文件位置可以自定义)不能带有中文。 上面配置文件中的:
1 |
<table tableName="message" domainObjectName="Messgae" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table> |
tableName和domainObjectName为必选项,分别代表数据库表名和生成的实力类名,其余的可以自定义去选择(一般情况下均为false)。 生成语句文件:
1 |
java -jar mybatis-generator-core-1.3.2.jar -configfile generatorConfig.xml -overwrite |
2、使用方法 在该目录按住Shift键,右键鼠标选择"在此处打开命令窗口",复制粘贴生成语句的文件代码即可。 看下效果图: 生成相关代码: Message.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
package lcw.model; public class Messgae { private Integer id; private String title; private String describe; private String content; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title == null ? null : title.trim(); } public String getDescribe() { return describe; } public void setDescribe(String describe) { this.describe = describe == null ? null : describe.trim(); } public String getContent() { return content; } public void setContent(String content) { this.content = content == null ? null : content.trim(); } } |
MessgaeMapper.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
<?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="lcw.dao.MessgaeMapper" > <resultMap id="BaseResultMap" type="lcw.model.Messgae" > <id column="id" property="id" jdbcType="INTEGER" /> <result column="title" property="title" jdbcType="VARCHAR" /> <result column="describe" property="describe" jdbcType="VARCHAR" /> <result column="content" property="content" jdbcType="VARCHAR" /> </resultMap> <sql id="Base_Column_List" > id, title, describe, content </sql> <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" > select <include refid="Base_Column_List" /> from message where id = #{id,jdbcType=INTEGER} </select> <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" > delete from message where id = #{id,jdbcType=INTEGER} </delete> <insert id="insert" parameterType="lcw.model.Messgae" > insert into message (id, title, describe, content) values (#{id,jdbcType=INTEGER}, #{title,jdbcType=VARCHAR}, #{describe,jdbcType=VARCHAR}, #{content,jdbcType=VARCHAR}) </insert> <insert id="insertSelective" parameterType="lcw.model.Messgae" > insert into message <trim prefix="(" suffix=")" suffixOverrides="," > <if test="id != null" > id, </if> <if test="title != null" > title, </if> <if test="describe != null" > describe, </if> <if test="content != null" > content, </if> </trim> <trim prefix="values (" suffix=")" suffixOverrides="," > <if test="id != null" > #{id,jdbcType=INTEGER}, </if> <if test="title != null" > #{title,jdbcType=VARCHAR}, </if> <if test="describe != null" > #{describe,jdbcType=VARCHAR}, </if> <if test="content != null" > #{content,jdbcType=VARCHAR}, </if> </trim> </insert> <update id="updateByPrimaryKeySelective" parameterType="lcw.model.Messgae" > update message <set > <if test="title != null" > title = #{title,jdbcType=VARCHAR}, </if> <if test="describe != null" > describe = #{describe,jdbcType=VARCHAR}, </if> <if test="content != null" > content = #{content,jdbcType=VARCHAR}, </if> </set> where id = #{id,jdbcType=INTEGER} </update> <update id="updateByPrimaryKey" parameterType="lcw.model.Messgae" > update message set title = #{title,jdbcType=VARCHAR}, describe = #{describe,jdbcType=VARCHAR}, content = #{content,jdbcType=VARCHAR} where id = #{id,jdbcType=INTEGER} </update> </mapper> |
MessgaeMapper.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
package lcw.dao; import lcw.model.Messgae; public interface MessgaeMapper { int deleteByPrimaryKey(Integer id); int insert(Messgae record); int insertSelective(Messgae record); Messgae selectByPrimaryKey(Integer id); int updateByPrimaryKeySelective(Messgae record); int updateByPrimaryKey(Messgae record); } |
from:https://www.cnblogs.com/zhujiabin/p/4990762.html
View DetailsJS更随机的随机数
一.问题背景 一个二维平面上有一群NPC,每一回合可以随机向上/下/左/右任一方向走1步,有单位碰撞体积(NPC位置不能重合) 规则就这么简单,初始情况下这群NPC是被人工均匀分布在二维平面上的,运行N个回合后发现所有NPC都集中在了左下角。。怎么会这样,说好的随机呢? 二.分析 现有的实现是这样的: 根据NPC的当前位置判断得到可以去的位置,把结果存放在一维数组arr里P.S.上/下/左/右最多4个点(周围空荡荡的),最少0个点(被围起来了) 生成[0, arr.length – 1]内的一个随机数,作为目标位置索引值index
1 2 3 4 5 |
// 生成随机数[min, max] w.Util.rand = function(min, max) { return Math.round(Math.random() * (max - min) + min); } |
控制NPC移动到arr[index]的位置 逻辑应该是没有问题的,可是为什么运行结果是NPC都跑到左下角开会去了呢?等等,为什么是左下而不是其它角角? 因为实现第一步的时候是按照上 -> 下 -> 左 -> 右的顺序判断的,最后都去了左下角,说明向上和向右的概率太小了(生成随机数的函数rand是没问题的,确实能得到[min, max]的数) 问题的根源是Math.random()不给力,生成[0, 1)之间的小数,取到0和靠近1的值概率很小,所以rand()函数生成的随机数取到min和mix的概率也很小,向上/向右的可能性也就小了 三.解决方案 既然取到min和max的概率很小,中间概率比较均匀,那好办,切掉这两个值就好了。具体实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
function randEx(min, max) { var num; var maxEx = max + 2; // 扩大范围到[min, max + 2],引入两个多余值替换min/max do{ num = Math.round(Math.random() * (maxEx - min) + min); num--; } while (num < min || num > max); // 范围不对,继续循环 return num; } |
值得一提的是上面的加2减1比较巧妙,能够恰好排除min和max 四.运行结果 JS中Math.random()返回值的概率差异可能比你想象的要大些,在实际应用中是不可接受的 测试代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
// 生成随机数[min, max] w.Util.rand = function(min, max) { return Math.round(Math.random() * (max - min) + min); } // 生成更随机的随机数[min, max] function randEx(min, max) { var num; var maxEx = max + 2; // 扩大范围到[min, max + 2],引入两个多余值替换min/max do{ num = Math.round(Math.random() * (maxEx - min) + min); num--; } while (num < min || num > max); // 范围不对,继续循环 return num; } function testRand(times, fun) { var arr = [1, 2, 3, 4]; var count = []; var randVal; for (var i = 0; i < times; i++) { // 获取[0, 3]的随机数 randVal = fun(0, arr.length - 1); // 记录次数 if (typeof count[randVal] !== "number") { count[randVal] = 0; } count[randVal]++; } console.log(count); } console.log("100 times"); testRand(100, w.Util.rand); // 之前的实现 testRand(100, randEx); // 改进过的实现 console.log("1000 times"); testRand(1000, w.Util.rand); // 之前的实现 testRand(1000, randEx); // 改进过的实现 console.log("10000 times"); testRand(10000, w.Util.rand); // 之前的实现 testRand(10000, randEx); // 改进过的实现 console.log("100000 times"); testRand(100000, w.Util.rand); // 之前的实现 testRand(100000, randEx); // 改进过的实现 |
后话 理论上Java的Math.random(),C#的next可能也存在这个问题,这里就没有必要验证了,因为randEx函数的思想(加2减1,嫌效果不好还可以加4减2、加6减3……直到满意为止)是通用的 from:https://www.cnblogs.com/ayqy/p/4511565.html?utm_source=tuicool
View DetailsWindows配置多个git用户
Window配置多个Git账户,SSH连接GitHub、GitLab 最新版本GIt配置对应多个Git仓库(不需要添加多个用户名和邮箱): 在本地git上添加一个用户名和邮箱,生成一对公钥和私钥,把公钥加入到各个配置SSH key里面。 1.检查本机是否有ssh key设置,切换到.ssh目录 $ cd ~/.ssh 或cd .ssh 2.配置git用户名和邮箱,配置多个用户时添加 --add 参数 $ git config --global --add user.name "username" $ git config --global --add user.email "email" 3.查看用户名和邮箱 $ git config --list 4.生成github.com,gitlab.com对应的私钥公钥. $ ssh-keygen -t rsa -C "test@qq.com" 注:生成id_rsa私钥公钥时需要命不同文件名,密码可设可不设。 5.添加ssh key到对应的GitHub,GitLab上面 登录GitHub系统;点击右上角账号头像的“▼”→Settings→SSH kyes→Add SSH key。 复制id_rsa.pub的公钥内容到Key填写框内。 $ssh -T git@github.com 测试公钥配置是否成功 6.在.ssh下面建立配置文件,文件名为config的文件且不需要添加文件后缀。 config文件配置内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# 配置github.com Host https://github.com/ HostName https://github.com/ IdentityFile C:/Users/zengsm/.ssh/id_rsa PreferredAuthentications publickey User username1 # 配置git.gitlab.com Host http://gitlab.zsm.com/ HostName http://gitlab.zsm.com/ IdentityFile C:/Users/zengsm/.ssh/id_rsa_gitlab PreferredAuthentications publickey User username2 |
HostName 真实的域名地址 IdentityFile id_rsa的地址 PreferredAuthentications 配置登录时用什么权限认证--可设为publickey,password publickey,keyboard-interactive等 User 配置使用用户名 # 可以通过 ssh-add -l 来确私钥列表 $ ssh-add -l # 可以通过 ssh-add -D 来清空私钥列表 $ ssh-add -D 7.克隆代码:从刚才配置的github上克隆项目: git clone git@配置的别名:用户名/项目名.git (例:git clone git@github.com:username/projectname.git) from:https://www.cnblogs.com/zengming/p/7908171.html
View Details