mybatis 总结_mybaits #{name.tostring}-程序员宅基地

技术标签: mybatis  

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)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_38946877/article/details/85915087

智能推荐

对象(CarDemo)_class cardemo-程序员宅基地

文章浏览阅读334次。package duixiang;class Car{ private String tapy; private String color; private int number; Car()//构造代码块 { System.out.println("Benze!!!"); } public void setTapy(String tapy)//暴露的设值接口 {_class cardemo

中国农药中间体行业发展前景预测与投资规划建议报告2021-2027年版_我国黄磷表观消费量:2015年-程序员宅基地

文章浏览阅读6.4k次。中国农药中间体行业发展前景预测与投资规划建议报告2021-2027年版第1章:农药中间体行业界定及发展环境剖析1.1 农药中间体行业的界定及统计说明1.1.1 农药行业界定1.1.2 农药中间体界定(1)农药中间体的界定(2)农药中间体的分类1.1.3 所属国民经济行业分类与代码1.1.4 本报告行业研究范围的界定说明1.1.5 本报告的数据来源及统计标准说明1.2 中国农药中间体行业政策环境1.2.1 行业监管体系及机构介绍1.2.2 行业标准体系建设现.._我国黄磷表观消费量:2015年

历届试题 连号区间数-程序员宅基地

文章浏览阅读67次。/*问题描述小明这些天一直在思考这样一个奇怪而有趣的问题:在1~N的某个全排列中有多少个连号区间呢?这里所说的连号区间的定义是:如果区间[L, R] 里的所有元素(即此排列的第L个到第R个元素)递增排序后能得到一个长度为R-L+1的“连续”数列,则称这个区间连号区间。当N很小的时候,小明可以很快地算出答案,但是当N变大的时候,问题就不是那么简单了,现在小明需要你的帮助。输入格式...

Struts学习day3-OGNL-contextMap_map頧是gnlcontext-程序员宅基地

文章浏览阅读134次。一、contextMap中放的常用内容1、存放的常用内容request:存放的ServletRequest中的属性(attributes),他是一个Map&lt;String,Object&gt;session:存放的HttpSession中的属性(attributes),他是一个Map&lt;String,Object&gt;application:存放的ServletConte..._map頧是gnlcontext

前端工程师面试题汇总(我的解析,可能不一定对)(HTML部分)-程序员宅基地

文章浏览阅读148次。1、Doctype作用?严格模式与混杂模式如何区分?它们有何意义?HTML5 为什么只需要写 <!DOCTYPE HTML>?<!DOCTYPE> 的作用<!DOCTYPE> 声明必须是 HTML 文档的第一行,位于 <html> 标签之前。<!DOCTYPE> 声明不是 HTML 标签;它是指示 web 浏览器关于页面使..._在浏览器与预设格式一样可以使用哪种标签

同步、异步、阻塞、非阻塞IO总结(IO模型总结)_同步阻塞io 哪些地方会阻塞-程序员宅基地

文章浏览阅读2.2w次,点赞56次,收藏257次。知识点概念IO操作概念同步、异步(IO模型中的概念,并非并发模式中的同步、异步)阻塞、非阻塞同步IO模型异步IO模型读写(read write)与阻塞和非阻塞各种IO模型异同对比IO操作概念在Unix系统中,一切都是文件。文件就是流的概念,在进行信息的交流过程中,对这些流进行数据的收发操作就是IO操作我们都知道unix(like)世界里,一切皆文件,而文件是什么呢?文件就是一串二进制流而已..._同步阻塞io 哪些地方会阻塞

随便推点

【历史上的今天】9 月 4 日:谷歌(Google) 23 周年;“人工智能之父” McCarthy 诞生_9月4日历史上的今天 科技时间-程序员宅基地

文章浏览阅读7.1k次,点赞22次,收藏9次。今天是 2021 年 9 月 4 日,在历史上的今天,柯达相机获得专利,从此成立相机帝国;人工智能之父 John McCarthy 出生;Google 公司正式成立,改变了许多人的命运。_9月4日历史上的今天 科技时间

1024 hello world_1024_hello_world-程序员宅基地

文章浏览阅读204次。1024程序员节是广大程序员的共同节日。1024是2的十次方,二进制计数的基本计量单位之一。针对程序员经常周末加班与工作日熬夜的情况,部分互联网机构倡议每年的10月24日为1024程序员节,在这一天建议程序员拒绝加班。 程序员就像是一个个1024,以最低调、踏实、核心的功能模块搭建起这个科技世界。1G=1024M,而1G与1级谐音,也有一级棒的意思。 程序员(英文Programmer)是从事前端、后端程序开发、系统运维、测试等的专业人员。一般将程序员分为程序设计人员和程序编码人员,但两..._1024_hello_world

dcmtk读写dicom文件头与文件内容_dcmimage.h-程序员宅基地

文章浏览阅读1k次。图像处理与VTK/ITK文章列表 #include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_iarchive.hpp> #include <iostream> #include <sstream> #include <string>#i..._dcmimage.h

JSON技术-Gson将bean转换json确保数据的正确,使用FastJson将Json转换Bean_java gson bean to jsonobject-程序员宅基地

文章浏览阅读4.2k次,点赞3次,收藏5次。一 、各个JSON技术的简介和优劣1.json-libjson-lib最开始的也是应用最广泛的json解析工具,json-lib 不好的地方确实是依赖于很多第三方包,包括commons-beanutils.jar,commons-collections-3.2.jar,commons-lang-2.6.jar,commons-logging-1.1.1.jar,ezmorph-1.0._java gson bean to jsonobject

Centos下更新Python到3.x_centos更新python3-程序员宅基地

文章浏览阅读188次。Centos下更新Python到3.x安装wget下载新版本解压缩创建一个空的文件夹,用来安装编译并安装创建软链接配置 yum参考了知乎用户-爬上墙头大佬的文章。Carlos Blog大佬的内容会更全面一些,但是链接似乎会被墙掉,所以把一些问题写在了这里。安装wget# yum install wget下载新版本这里用的版本是 Python3.7.0# wget https://www.python.org/ftp/python/3.5.2/Python-3.7.0.tgz解压缩# t_centos更新python3

pandas对dataframe的数据列进行随机抽样(Random Sample of Columns):使用sample函数进行数据列随机抽样(有放回的随机抽样,replacement)_从dataframe中读取完整的一列值,如何实现随机取值-程序员宅基地

文章浏览阅读685次,点赞3次,收藏3次。pandas对dataframe的数据列进行随机抽样(Random Sample of Columns):使用sample函数进行数据列随机抽样(有放回的随机抽样,replacement)目录pandas对dataframe的数据列进行随机抽样(Random Sample of Columns):使用sample函数进行数据列随机抽样(有放回的随机抽样,replacement)#使用sample函数进行数据列随机抽样语法#仿真数据#使用sample函数进行数据列随机抽样(有放回的随机_从dataframe中读取完整的一列值,如何实现随机取值

推荐文章

热门文章

相关标签