mybatis 总结:
1,框架定义:
对于程序员来说,框架是一套资源,这套资源中会包含jar包、文档、还有些包含源码、代码示例等。
2,MyBatis体系结构
1,接口层:
数据查询接口、数据新增接口、数据更新接口、数据删除接口、获取配置接口
2,数据处理层:
1)参数映射:参数映射配置、参数映射解析、参数类型解析
2)SQL解析:SQL获取、SQL解析、动态SQL
3)SQL执行:SimpleExecutor、BatchExcutor、ReuseExecutor
4)结果映射:结果映射配置、结果类型转换、结果数据拷贝
3,基础支撑层:
连接管理、事务管理、配置加载、缓存处理
配置框架
3,MyBatis工作原理
1,
2,作用:作为数据库访问层的角色,对数据库进行 增删改查 操作。
4,成员变量和属性的区别
1,成员变量是私有的
2,属性是 get / set 方法的方法名,去掉get/set后首字母小写,属性是公开的
5,配置文件与约束
1,约束文件一般是DTD文件,相关的约束规则就是写在这里面的
2,把DTD约束文件添加到配置文件中,可以使程序员只能使用规定的标签,不能使用自定义的标签,否则会报错。
6,mybatis-config.xml 主配置文件
1,选择标签,按F2就会有提示,在元素标签后面会有一些符号
, :逗号表示顺序,在逗号前面的要放在前面,否则会报错
? :问好表示小于等于 1个(最多只有一个)
+ :表示大于等于1个
* :表示大于等于 0 个
没有符号:表示 1,有且仅有一个
7,源码部分
1,脏数据(dirty)
数据库中存储的数据与内存中的数据不一致
2,源码分析
1)输入流的关闭
在执行完 SqlSessionFactry 的 build(is)方法时,就已经关闭了
2)sqlsession 的创建
创建一个 defaultSqlSession 对象,并给成员变量赋予初始值
3)增删改的执行
增删改操作,底层都是调用了update()方法,
4)SqlSession 的 commit()
dirty 默认是 false,在底层代码中执行了增删改操作后 dirty 就会被赋值为 true
然后在执行commit()方法时,又给 dirty 赋值成 false
在底层代码在执行到最后时,会根据 dirty 的值进行判断是否需要进行事务回滚,如果dirty 为 true 时则执行回滚操作,反之则不执行。
private boolean isCommitOrRollbackRequired(boolean force){
return (!autoCommit && dirty) || force;
}
5)SqlSession的关闭
在底层代码中调用了transaction.close();
8,MyBatis 的 CURD 操作
1,增加:
1)插入数据没有插入ID值,在执行插入后马上获取到这条数据的 ID值
底层是使用反射机制实现的,把生成的 ID 的值赋值给对象的 ID 属性。
在数据库中的 SQL 语句
方式一:
insert into student(name,age,score)values("王五",25,95.5);
select @@identity; 这个 select 语句只能跟在 insert 语句的后面,不能单独使用
方式二:
insert into student(name,age,score)values("王五",25,95.5);
select last_insert_id();
在mapper.xml文件中的写法:
<insert id="insertStudent" palameterType="Student">
insert into student(name,age,score)values("王五",25,95.5)
<selectKey resultType="int" keyProperty="id" order="AFTER">
select @@identity
</selectKey>
</insert>
2,删除 delete
3,修改
1)update
2)当MyBatis 判断条件为 等于 的时候(其他的判断不需要),常量 需要加 .toString() 来转换,这种方法是稳定的,推荐使用,比如:
<!-- 正确的,稳定,推荐使用 -->
<if test="newsImage != null and newsImage == '1'.toString()">
<![CDATA[ and len(newsImage) > 0 ]]>
</if>
其中判断 newsImage == '1' 时,人为认为成功,但实际上是不成功的,需要改为 newsImage == '1'.toString()方可成功,原因具体没有细入研究,根据实际使用推测应该是 “等于” 在java中是个比较复杂问题,涉及的“等于”有可能是变量地址相等,或者是变量值内容相等,在XML文件中简单的 == 在经过MyBatis处理后无法判断是哪种类型的“相等”,所以加.toString()做强制转换操作,MyBatis就知道是值内容的比较,当然就成功了; 注意这个常量不限于数字,对于字母,如 'y' 同样需要加上 .toString()方可成功,如下:
<!-- 正确的,稳定,推荐使用 -->
<if test="newsImage != null and newsImage == 'y'.toString()">
<![CDATA[ and len(newsImage) > 0 ]]>
</if>
那给变量加 .toString() 可以吗?这个是错误的,至少实际在所使用的myBatis版本(mybatis-3.2.5.jar,mybatis-spring-1.2.1.jar)是不可以,以后版本不知道,这应该是在经过 myBatis 时,影响到其转换操作,故出现错误,如下是错误的:
<!-- 错误的 -->
<if test="newsImage != null and newsImage.toString() == 'y'">
<![CDATA[ and len(newsImage) > 0 ]]>
</if>
既然是值内容的比较,我们自然联想到 Java 的 equals , equalsIgnoreCase 关键字,用这个可以吗? 实际测试过,有时成功,有时不成功(有可能跟我的机子和我使用的Java环境的原因),很不稳定,不推荐使用,所以如下是不稳定的:
<!--有时成功,有时不成功,不推荐使用-->
<if test="newsImage != null and newsImage.equal('y')">
<![CDATA[ and len(newsImage) > 0 ]]>
</if>
4,查询
模糊查询
where name like concat('%',#{name},'%')
或:
where name like '%' #{name} '%'
或:
where name like '%' || #{name} || '%'
前面两种方式底层使用的是 paremeterstatemer 对象,预编译效率高,使用的是 ? 号作为占位符,可以防止SQL注入攻击
或:
where name like '%${value}%'
这种方式底层使用的是 statemet 对象字符串拼接,执行效率低,不能防止SQL注入攻击,这种方式了解即可。
5,属性名和查询字段名不相同
处理方式一:使用 resultMap 进行关系映射
处理方式二:在SQL语句中使用 as 进行转换
6,Mapper 动态代理
使用 mybatis 时 Dao 的实现类其实没有干什么实际性的工作,它仅仅就是通过 SqlSession 的相关 API 定位到映射文件 mapper 中相应的 id 的 SQL 语句,真正对 DB 进行操作的工作其实是由框架通过 mapper 中的 SQL 语句完成的。
所以,mybatis 框架就抛开了 dao 的实现方式称为 Mapper 的动态代理方式。
Mapper 动态代理方式无需程序员实现 dao 接口。接口是由 mybatis 结合映射文件自动生成的动态代理实现的。
1)xml 文件中的 namespace 是对应 dao 层接口的全限定类名
2)接口方法名与 xml 文件中的 id 相同
9,入参为多个参数时
底层是通过反射机制去找属性的 get / set 方法的
#{} 中可以放什么内容:
1,参数的对象属性
2,随意内容,此时的 #{} 是一个占位符
3,参数为 map 时的 key
4,参数为 map 时,若可用所对应的value为对象,则可将该对象的属性放入
5,参数的索引号
1)使用 map入参
在 map 中可以存储对象 或 其他类型的数据
在 mapper.xml 文件中使用时,通过 #{map的key},如果map中存有对象,取值得时候可以通过对象key类点出属性名 #{stu.name}
2)使用索引
在mapper.xml文件中使用参数的索引(入参的顺序,从0开始)来获取入参参数,#{0} #{1}
10,动态SQL
查询条件不固定
1)在编写动态SQL语句时,以前都是使用 where 1 = 1 and 其他条件
以上的写法执行效率不高,如果是数据量大的话,每执行一次都会执行一次 1 = 1 的判断,所以执行效率低
2)使用 <where> 标签
在生成SQL语句的时候,where 标签会自动的把多余的 and 去掉,效果和 where 1 = 1 and 其他条件是一样的,但是这个的执行效率更高
eg:
<select id="xxxx" resultType="aaaa">
select id,name,age
from student
<where>
<if test="name != null and name != '' " >
and name like '%' #{name} '%'
</if>
<if test=" age > 0 ">
and age > #{age}
</if>
</where>
</select>
3)<choose>标签
<choose>标签类似于switch,当满足其中一个when的条件时,则不会去判断其他的when
eg:
<where>
<choose>
<when test=" name != null and name != ' ' ">
and name like '%' #{name} '%'
</when>
<when test="|age > 0 ">
and age > #{age}
</when>
<otherwise>
1 = 2
</otherwise>
</choose>
</where>
4)<foreach>标签的使用
1,用来遍历数组
<if test="array.length > 0">
<foreach collection="array" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</if>
2,用来遍历集合
<if test="list.size > 0">
<foreach collection="array" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</if>
3,遍历的集合中存在泛型
<if test="list.size > 0">
<foreach collection="array" item="stu" open="(" close=")" separator=",">
#{stu.id}
</foreach>
</if>
5)<sql>标签,即SQL片段
可以用来替换SQL语句中的任意部分的语句,好处:便于修改和重用,但是可读性较差
编写
<sql id = "base_list_sql" ></sql>
使用
<include refid="base_list_sql" />
11,关联关系查询
关联查询分为四种:
关联关系在代码中以 属性 体现出来,在数据库中就是 表与表之间 的主外键关系,外键都是建立在多的一方
1)一对多关联关系
一方可以看到多方,但是多方不一定看到一方,即一方会有多方的属性,多方不一定有一方的属性,在一的一方的实体类属性中一般都是以 set 集合来定义多的一方的属性,因为 set 集合是无序且不可重复的
方式一:通过多表连接查询实现, 这种方式不能使用延迟加载
<resultMap type="Country" id ="countryMapper>
<id column = "cid" property = "cid">
<result column = "cname" property = "cname">
<collection property = "ministers" ofType = "Minister">
<id column = "mid" property = "mid" />
<result column = "mname" property = "mname" />
</collection>
</resultMap>
<select id = "selecrCountryById" resultMap = "countryMapper">
select cid,cname,mid,mname
from country,minister
where countryId = cid and cid = #{cid}
</select>
方式二:多单单独查询方式实现,这种方式的好处:可以使用延迟加载
<select id = "selectMinisterByCountry" resultType="Minster">
select mid,mname from minister where countryId = #{cid}
</select>
<resultMap type="Country" id="countryMapper">
<id column = "cid" property = "cid"/>
<result column = "cname" property="cname">
<collection property="ministers" ofType="Minister" select="selectMinisterByCountry" column="cid" />
</resultMap>
<select id = "selectCountryById" resultMap = "countryMapper">
select cid,cname from country where cid = #{cid}
</select>
2)多对一关联关系
多方看到一方(即在多方定义了一方的对象作为属性)
解决方式一:通过多表连接查询实现
<resultMap type="Minister" id ="ministerMapper>
<id column = "mid" property = "mid" />
<result column = "mname" property = "mname" />
<association property = "ministers" javaType = "Country">
<id column = "cid" property = "cid">
<result column = "cname" property = "cname">
</association>
</resultMap>
<select id = "selectMinisterById" resultMap = "ministerMapper">
select cid,cname,mid,mname
from country,minister
where countryId = cid and mid = #{mid}
</select>
解决方式二:通过多表单独查询方式实现
<select id = "selectCountryById" resultType = "Country">
select cid,cname from cid = #{countryId}
</select>
<resultMap type="Minister" id ="ministerMapper>
<id column = "mid" property = "mid" />
<result column = "mname" property = "mname" />
<association property = "ministers" javaType = "Country"
select = "selectCountryById"
column = "countryId" />
</resultMap>
<select id = "selectMinisterById" resultMap = "ministerMapper">
select mid,mname
from country
where mid = #{mid}
</select>
3)自关联关系
1,定义:在同一张表或同一个类中自己即充当one方,又充当many方,是1:n 或 n:1的变型
eg:在一张员工表中,既有老板,经理,员工。老板和其他员工是一对多,经理和其他员工也是一对多
2,以一对多的方式处理:
当前栏目被看做是one方,即父栏目
实现方式一:使用递归查询出要查询指定栏目的所有子栏目
<resultMap type="NewsLabel" id="newslabelMapper">
<id column="id" property="id"/>
<result column="name" property="name"/>
<collection property="children" select="selectChildrenByParent"
column="id"/>
</resultMap>
<select id="selectChildrenByParent" resultMap="newslabelMapper">
select id,name from newslabel where pid = #{pid}
</select>
实现方式二:查询指定栏目及其所有子栏目
<select id="selectNewslabelByParent" resultMap="newslabelMapper">
select id,name from newslabel where pid=#{pid}
</select>
<resultMap type="NewsLabel" id="newslabelMapper">
<id column="id" property="id" />
<result column="name" property="name" />
<collection property="children" ofType="NewsLabel"
select="selectNewslabelByParent"
column="id" />
</resultMap>
<select id="selectNewsLabelById" resultMap="newslabelMapper">
select id,name from newslabel where id = #{id}
</result>
3,以多对一的方式处理:
当前栏目被看做many方,即子栏目
查询当前栏目及其所有父栏目
<resultMap type="NewsLabel" id="newslabelMapper">
<id column="id" property="id" />
<result column="name" property="name" />
<association property="parent" javaType="NewsLabel"
select="selectNewsLabelById"
column="pid" />
</resultMap>
<select id="selectNewsLabelById" resultMap="newslabelMapper">
select id,name,pid from newslabel where id = #{id}
</result>
4)多对多关联关系
多对多关系的两张表之间需要借助 第三张关系表 来完成查询
在多对多关系中如果双方都使用toString()输出对象内容时,很可能会导致Stack Overflow error,这不是栈内存溢出,而是达到了栈的深度(栈有一定的深度,不同的电脑这个深度不一样)
如果是报 OutOfMemoryError 内存溢出一般是出现在申请了较多的内存空间没有释放的情形。
12,mybatis 的延迟加载
1)定义:lazyLoadingEnabled
是指在进行关联查询(从查询)时(单表没有延迟加载),按照设置延迟规则推迟对关联对象的 select 查询。延迟加载可以有效的减少数据库的压力
注:mybatis的延迟加载只是对关联对象的查询有延迟设置,对于主加载对象都是直接执行查询语句的
2)关联对象的加载时机:
1,直接加载
执行完主加载对象的 select 语句,马上执行对关联对象的 select 查询
2,侵入式延迟加载
aggressiveLazyLoading
执行对主加载对象的查询时,不会执行对关联对象的查询,当要访问主加载对象的详情时,就会马上执行关联对象的 select 查询。即对关联对象的查询执行,侵入到了之家在对象的详情访问中。也可以这样理解:将关联对象的详情侵入到了主加载对象的详情中,即将主加载的详情作为主加载的对象的详情的一部分出现了。
3,深度延迟加载
执行对主加载对象的查询时,不会执行对关联对象的查询,访问主加载对象的详情时也不会执行关联对象的select查询。只有当真正访问关联对象的详情时,才会执行对关联对象的select 查询
3)延迟加载的配置:
在mybatis.xml 的主配置文件中进行配置
<settings>
延迟加载的总开关
<setting name="lazyLoadingEnabled" value="true" />
<setting name="agressiveLazyLoading" value="true"/>
</settings>
13,查询缓存
1)分类:根据缓存的作用域和生命周期,可以分为两种:一级缓存,二级缓存。
2)划分规则:
mybatis 查询缓存的作用域是根据 mapper 的 namespace 划分的,相同的 namespace 的缓存数据存放在同一个缓存区域。不同 namespace 下的数据互不干扰。无论是一级缓存还是二级缓存都是按照 namespace 进行分别存放的。
3)生命周期:
但一、二级缓存的不同之处在于,sqlsession 一旦关闭,则SQLsession 中的数据将不存在,即一级缓存就不复存在。而二级缓存的生命周期会与整个应用同步,与sqlsession 是否关闭无关。换句话说,一级缓存是在同一个线程(同一个sqlsession)间共享数据,而二级缓存是在不同线程(不同的sqlsession)间共享数据(要在同一个namespace下才行)
4)一级缓存底层原理:
1,缓存的底层实现是一个 Map,Map 的 value 是查询结果
2,Map 的key,即查询依据,使用的ORM框架不同,查询依据是不同的。
MyBatis 的查询数据的依据是:Sql 的 id + sql 语句 + 哈希值
Hibernate 的查询依据是:查询结果对象的 id
5)增删改对一级缓存的影响:增删改操作会清空一级缓存,无论是否提交。
6)二级缓存
1,开启内置的二级缓存:
1)在映射文件中的所有增删改标签前添加 < cache /> 标签即可
2)对实体进行实例化
2,Cache Hit Ratio 查询缓存命中率
查询缓存时,从缓存中查询出数据的次数百分比,实际查询的是 map 的 key 值是否存在
3,二级缓存的配置
为 <cache /> 标签添加一些相关属性设置,可以对二级缓存的郧西警性能进行控制,如果不指定设置,则均保持默认值。
<cache evication = "FIFO" flushInterval = "10800000" readOnly = "true" size ="512" />
evication:逐出策略。
当二级缓存中的对象达到最大值时,就需要通过逐出策略将缓存中的对象移出缓存。默认值为 LRU 。
常用的策略有:
FIFO:First In First Out,先进先出
LRU:Least Recently Used ,未被使用时间最长的
flushInterval:刷新缓存的时间间隔,单位毫秒。这里的刷新缓存即清空缓存。一般不指定,即当执行增删改时刷新缓存。
readOnly:设置缓存中数据是否只读。
只读的缓存会给所有调用者返回缓存对象的相同实例,因此这些对象不能被修改,这些提供了很重要的性能优势。但读写的缓存会返回缓存对象的拷贝。这会慢一些,但是安全,因此默认是 false
size:二级缓存中可以存放最多对象个数。默认为 1024 个。
4,增删改对二级缓存的影响
1)增删改同样也会清空二级缓存
2)对于二级缓存的清空,实际上是对所查找 key 对应的 value 置为 null,而并非将 <key, value>对,即 Entry 对象删除
3)从 DB 中进行 select 查询的条件是:
1,缓存中根本就不存在这个 key
2,缓存中存在该 key 所对应的 Entry 对象,但其 value 为null
4)设置增删改不刷新二级缓存
在映射文件中的增删改标签中添加 flushCache = "false" 属性即可
eg:
<insert id = "insertStudent" flushCache = "false">
insert into xxxxxxx
</insert>
注:一级缓存不能进行增删改不刷新缓存
5,二级缓存的关闭
在 mybatis 的主配置文件中,进行设置。
全局配置,配置后所有的二级缓存都会被关闭
<settings>
<setting name="cacheEnabled" value="false">
</settings>
局部关闭
useCache="false",当全局是开启时,使用这个属性可以关闭当前查询的二级缓存
<select id="selectStudentById" useCache="false" resultType="Student">
select id,name from student where id = #{id}
</select>
6,二级缓存的使用规则:
如果不遵循以下规则,可能从缓存中获取的数据是不是最新的数据,或数据不一致。
1)多个 namespace 不要操作同一张表
因为缓存时以 namespace 进行划分的,不同 namespace 中的数据互不干扰。
2)不要在关联关系表上执行增删改操作,即只能做单表操作。
3)查询多于修改时使用二级缓存
14,MaBatis注解式开发
1)注解的基础语法:
1,注解后面试没有分号的
2)注解首字母是大写的,因为注解与类、接口、枚举是同一个级别的。一个注解,在后台对应着一个 @interface 类
3)在同一个语法单元上,同一个注解只能使用一次。
4)在注解与语法单元(同一个类或同一个方法中)之间可以隔若干空行、注释等非代码内容
5)在使用注解时有默认的属性可以不进行指定,但没有指定默认值得属性,就要全部指定
5)eg:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Insert{
String [ ] value();
}
2)myBatis 注解式开发
1,使用注解
public interface IStudentMapper {
// 如果 value 只有一个元素,大括号可以省略不写,如果注解里面只用到一个 value属性,那么 value 可以省略不写
@Insert(value={"insert into student(name,age) values(#{name},#{age}"})
void insertStudent(Student student);
}
2,在mybatis 的主配置问价中进行注册
<mappers>
// 进行以下配置,在找不到 mapper 映射文件后就会找注解
<package name="com.hsz.dao" />
</mappers>
15,ehcache二级缓存
是一个第三方的专门做二级缓存的一个项目,使用 ehcache 二级缓存,实体类无需实现序列化接口
1)使用步骤:
1,导 jar 包,ehcache-core-2.6.8.jar,mybatis-ehcache-1.0.3.jar
2,在映射文件中的<cache />标签中引入 ehcache
<cache type="org.mybatis.caches.ehcache.EhcacheCache" />
3,添加 ehcache.xml 配置文件
在 ehcache 的核心 jar 包里面,把ehcaceh-fxxxxx.xml拷贝出来,然后把名字给为 ehcaceh.xml 并添加到项目中就可以直接使用了
2)ehcache二级缓存的配置
16,mybatis 反向生成代码
方式一:生成到项目中
1)在 maven 项目中的 pom.xml 文件中添加 mybatis-generator 插件
<!-- mybatis generator的插件 -->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version> // 这里的版本一定要选这个
<configuration>
<!-- 配置configureFile的路径和名称 -->
<configurationFile>
${basedir}/src/main/resources/META-INF/mybatis/generatorConfig.xml
</configurationFile>
</configuration>
</plugin>
2)新建 generatorConfig.xml 文件
添加如下配置:
<?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="C:/Users/administrator/.m2/repository/mysql/mysql-connector-java/5.1.34/mysql-connector-java-5.1.34.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:3306/studnet" userId="root" password="">
</jdbcConnection>
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!--生成Model类存放位置-->
<javaModelGenerator targetPackage="com.dzy.model" targetProject="src/main/java">
<property name="enableSubPackages" value="true"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!--生成映射文件存放位置-->
<sqlMapGenerator targetPackage="com.dzy.mapping" targetProject="src/main/java">
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>
<!--生成Dao类存放位置-->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.dzy.dao" targetProject="src/main/java">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator>
<!--生成对应表及类名-->
<table tableName="course_info" domainObjectName="CourseInfo" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
<table tableName="user_info" domainObjectName="UserInfo" enableCountByExample="false"></table>
<table tableName="course_user_info" domainObjectName="CourseUserInfo" enableSelectByExample="true"></table>
</context>
</generatorConfiguration>
3)在项目的 pom.xml 文件上右击运行 run as --> maven build。。
输入:mybatis-generator:generate,运行即可
方式二:使用 doc 命令,生成到在本地磁盘中
1)在本地新建一个文件夹命名为:generator
2)准备需要的 jar 包:(版本可以自己选择)
mybatis-generator-core-1.3.2.jar
mysql-connector-java-5.1.34.jar
3)在 generator 文件夹中国新建一个文件,命名为:generator.xml
添加如下内容:
<?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="D:\generator\mysql-connector-java-5.1.34.jar" />
<!-- <classPathEntry location="C:\oracle\product\10.2.0\db_1\jdbc\lib\ojdbc14.jar" />-->
<context id="DB2Tables" targetRuntime="MyBatis3">
<commentGenerator>
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!-- 数据库链接URL、用户名、密码 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/my_db?characterEncoding=utf8" userId="root" password="123456">
<!--<jdbcConnection driverClass="oracle.jdbc.driver.OracleDriver" connectionURL="jdbc:oracle:thin:@localhost:1521:orcl" userId="msa" password="msa">-->
</jdbcConnection>
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- 生成模型的包名和位置 -->
<javaModelGenerator targetPackage="andy.model" targetProject="D:\generator\src">
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- 生成的映射文件包名和位置 -->
<sqlMapGenerator targetPackage="andy.mapping" targetProject="D:\generator\src">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!-- 生成DAO的包名和位置 -->
<javaClientGenerator type="XMLMAPPER" targetPackage="andy.dao" targetProject="D:\generator\src">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<!-- 要生成那些表(更改tableName和domainObjectName就可以) -->
<table tableName="kb_city" domainObjectName="KbCity" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false" />
<!-- <table tableName="course_info" domainObjectName="CourseInfo" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false" />
<table tableName="course_user_info" domainObjectName="CourseUserInfo" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false" /> -->
</context>
</generatorConfiguration>
4)修改代码中 D:\generator 自己所放jar包路径、数据库链接地址、用户名、密码、以及需要生成文件对应的表名,保存即可
目录结构如下:
5)打开 doc 命令窗口,进入当前目录下,输入以下命令:
java -jar mybatis-generator-core-1.3.2.jar -configfile generator.xml -overwrite
执行完以上操作即生成了 dao、entity、mapper.xml 三种文件
17,PageHelper 分页插件
18,SQL 语句批量操作
1)insert 语句 批量插入
insert into lcrm_risk_flag_info(customer_id,update_time)
values
<foreach collection="list" index="index" item="item" separator=",">
(#{item.customerId,jdbcType=VARCHAR},DATE_FORMAT(NOW(),'%Y/%m/%d %H:%i:%S'))
</foreach>
2)通过 insert 语句 备份一个表的数据到另一个表
insert into lcrm_risk_flag_info_his(
lcrm_risk_flag_info_his_id,customer_id,cert_id,update_time)
select
lcrm_risk_flag_info_id, customer_id,cert_id,DATE_FORMAT(NOW(),'%Y/%m/%d %H:%i:%S') FROM lcrm_risk_flag_info a where object_type='1' and a.object_no in
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
#{item.objectNo}
</foreach>
3)批量进行修改
update lcrm_apply_info set flag=#{status,jdbcType=VARCHAR} where lcrm_apply_info_id in
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
#{item.lcrmApplyInfoId}
</foreach>
4)批量删除
delete from lcrm_risk_flag_info where object_no in
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
#{item.objectNo}
</foreach>
19,使用经验:
1)入参如果是字符串,在进行判断是否为空时最好顺便判断长度大于 0
str != null and str.length > 0
2)