Mybatis的基础用法
本章内容是MyBatis的原始配置,比较繁琐,实际开发中可能用不到。推荐去看SringBoot整合Mybatis
文章主要是MyBatis基础的动态Sql,多表查询,还有缓冲涉及到的懒加载,其实后面主要是注解开发混合…Mapper.xml的。复杂的sql语句还是需要…Mapper.xml。
jdbc.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/powernode
jdbc.username=root
jdbc.password=root
# 把具体配置抽离出来更好
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 从类路径(resource)下开始查找jdbc.properties配置文件,"${key}"调用value值-->
<properties resource="jdbc.properties" />
<!--从绝对路径当中加载资源。 file:///路径 -->
<!--<properties url="file:///d:/jdbc.properties" />-->
<settings>
<!--开启驼峰命名⾃动映射 放在properties标签后⾯-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 开启懒加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
</settings>
<typeAliases>
<!--目录下所有类使用简名为别名。映射文件中可使用该大小写任意的简名-->
<package name="com.powernode.mybatis.pojo"/>
</typeAliases>
<!--数据源环境环境配置。-->
<environments default="mybatisDB">
<environment id="mybatisDB">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--从类路径(resource=) 加载映射 从文件路径 url="file:///d:.."
class加载映射xml 必须和接口路径和名字一致。
实际使用name。该目录下所有xml 均以class加载映射 -->
<package name="com.powernode.mybatis.mapper"/>
</mappers>
</configuration>
注:MyBatis是于半⾃动化 ORM 框架。 Object:Java对象, Relational:关系型数据库, Mapping:映射
实体类.java
entity 实体类,一般每一个实体类都对应一个数据库表。一般都是放在在com.域名.底下的 entity 文件夹下
当然实体类也可以看成简单类,文件夹名也有人喜欢用 domain,pojo , bean ,推荐用entity命名,给用户反馈数据一般抽离汇总定义一个 vo(value object)文件夹存放 View视图层需要的信息,也是简单类
public class XXX {
private Long id;
private String name;
private int xxx;
# get,set ,构造方法啥的补上
}
<!--也可以引入lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
@Data :相当于@Setter + @Getter + @ToString + @EqualsAndHashCode
@EqualsAndHashCode:生成hashCode()和equals()方法,默认情况下,它将使用所有非静态,非transient字段。
可以通过exclude参数中来排除更多字段。或者在of参数来准确指定使用字段。
@EqualsAndHashCode(of = {"id","name"}),这样当类的id,和name两个属性相等时则
A.equals(B) 判定两对象相等
@NoArgsConstructor:自动生成无参数构造函数。
@AllArgsConstructor:自动生成全参数构造函数。
@Accessors(chain = true)开启链式编程,写代码更加方便。
....
#eg:
@Setter
@Getter
@ToString
@EqualsAndHashCode(of = {"id","name"})
@NoArgsConstructor
@AllArgsConstructor
public class XXX {
private Long id;
private String name;
private int xxx;
}
…Mapper.xml
这是映射对应的SQL语句。一般是在 dao文件夹定义接口及其实现类,Spring的代理机制的把实现类给省去了,按规范书写接口就行,为方便配置把路径统一(java与resource都是跟路径),放接口的文件夹名字也叫mqpper,
//接口类
public interface CarMapper {//名字不重要,代理前是dao文件夹CarDao
Car 接口定义的方法名(String xxx);
Car 接口定义的方法名2();
}
// 实现类 Spring 代理了
/*public class CarDaoImpl implements CarDao {
@Override
public Car 接口定义的方法名(String arg0) {
SqlSession sqlSession = SqlSessionUtil.openSession();
return (Account) sqlSession.selectOne("对应..Mapper.xml的namespace的值.接口定义的方法名", arg0);
}
...
}*/
<?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">
<!-- namespace 必须是根路径+接口名 -->
<mapper namespace="com.powernode.mybatis.mapper.CarMapper">
后续这个配置框架就不写了,可以用IDEA模板弄一些,方便生成文件
</mapper>
<?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">
<!-- namespace 必须是根路径+接口名 -->
<mapper namespace="com.powernode.mybatis.mapper.CarMapper">
<!--select标签的resultMap属性指定结果映射。-->
<select id="接口定义的方法名" resultMap="pojo类根路径+类名">
select * from t_car
</select>
<!--可在 mybatis-config.xml 中设置<typeAliases>
别名自己指定的
<typeAlias type="com.powernode.mybatis.pojo.Car" alias="aaa"/>
采用默认的别名机制
<typeAlias type="com.powernode.mybatis.pojo.Car"/>
包(目录)下所有的类自动起别名。使用简名作为别名。
<package name="com.powernode.bank.pojo"/>
resultMap就可以直接用别名了,大小写任意
</typeAliases>-->
</mapper>
扩展配置
- 映射对应名
1. mybatis-config.xml 中开启驼峰命名⾃动映射(userName -> user_name )
<!--开启驼峰命名⾃动映射 放在properties标签后⾯-->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
2....Mapper.xml 中配置映射结果集 resultMap 以此避免直接映射 pojo
<!--
1.专门定义一个结果映射,在这个结果映射当中指定数据库表的字段名和Java类的属性名的对应关系。
2. type属性:用来指定POJO类的类名。
3. id属性:指定resultMap的唯一标识。这个id将来要在select标签中使用。
-->
<resultMap id="映射结果id" type="com.powernode.mybatis.mapper.Car">
<!--如果数据库表中有主键,一般都是有主键,要不然不符合数据库设计第一范式。-->
<!--如果有主键,建议这里配置一个id标签,可以让mybatis提高效率。-->
<id property="id" column="id"/>
<!--result标签 如果column和property是一样的,这个可以省略。-->
<result property="produceTime" column="produce_time"/>
<result property="carType" column="car_type"
javaType="string" jdbcType="VARCHAR"/>
</resultMap>
<select id="查询接口方法名" resultType=" pojo类名 -> 映射结果id">
select .. from ...
</select>
// resultType= 也可以是常量类,Mybatis都对其进行了优化,写简名即可如:long,int,string,String
- environments(配置环境)
<!--default表示默认使用的环境。-->
<!--使用mybatis创建SqlSessionFactory对象的时候,没有指定环境的话,默认使用该id环境。-->
<environments default="powernodeDB">
<!--环境(environment) 会对应一个SqlSessionFactory对象-->
<environment id="powernodeDB">
<!--transactionManager标签1.配置事务管理器。指定mybatis管理事务的方式。
type属性 1. JDBC: 使用原生的JDBC代码来管理事务。
conn.setAutoCommit(false); ... conn.commit();
2. MANAGED:将事务管理交给其它的JEE容器来管理。例如:spring
不区分分大小写。jdbc/managed
mybatis提供了一个事务管理器接口:Transaction
该接口实现类:JdbcTransaction、ManagedTransaction-->
<transactionManager type="JDBC"/>
<!--dataSource配置数据源(JDK数据源的规范javax.sql.DataSource接口)
type属性 1.UNPOOLED 每一次请求创建新的Connection对象。
2.POOLED 使用mybatis的数据库连接池。
3.JNDI 集成第三方的数据库连接池。JNDI是一套规范接口
大部分的web容器都实现了JNDI规范例如:Tomcat、Jetty、WebLogic、WebSphere
常见的数据源组件(数据库连接池)阿里巴巴的德鲁伊(druid),c3p0,dbcp
-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!--提醒:设置好参数,可以让连接池发挥的更好。事半功倍的效果。-->
<property name="poolMaximumActiveConnections" value="10"/>
<!--每隔2秒打印日志,并且尝试获取连接对象-->
<property name="poolTimeToWait" value="2000"/>
<!--强行让某个连接空闲,超时时间的设置(ms) 默认值20s -->
<property name="poolMaximumCheckoutTime" value="10000"/>
<!--最多的空闲数量 默认值10 -->
<property name="poolMaximumIdleConnections" value="5"/>
<!-- ... -->
</dataSource>
</environment>
</environments>
一个完整的setting,几乎都有默认值,配置需要的就行
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="multipleResultSetsEnabled" value="true"/>
<setting name="useColumnLabel" value="true"/>
<setting name="useGeneratedKeys" value="false"/>
<setting name="autoMappingBehavior" value="PARTIAL"/>
<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
<setting name="defaultExecutorType" value="SIMPLE"/>
<setting name="defaultStatementTimeout" value="25"/>
<setting name="defaultFetchSize" value="100"/>
<setting name="safeRowBoundsEnabled" value="false"/>
<setting name="mapUnderscoreToCamelCase" value="false"/>
<setting name="localCacheScope" value="SESSION"/>
<setting name="jdbcTypeForNull" value="OTHER"/>
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>
动态SQl:url
// 多参数传值取别名替代默认的arg~与param~中的arg~
List<Car> selectByXXX(@Param("guidePrice") Double guidePrice,
@Param("carType") String carType);
-
if
# sql语句在test条件满足时添加 <if test="carType != null and carType != ''"> and car_type = #{carType} and </if>
-
where
where标签的作⽤:让where⼦句更加动态智能。 #所有条件都为空时,where标签保证不会⽣成where⼦句。 #⾃动去除某些条件前⾯多余的and或or。 <where> <if test="brand != null and brand != ''"> and brand like #{brand}"%" </if> </where> where 可以理解成if所有拼接后的sql语句不为空,将其前缀and/or去掉,加上where 拼接 推荐写法是每个语句前面加and/or拼接符。
-
trim
trim标签的属性: # prefix:在trim标签中的语句前添加内容 # suffix:在trim标签中的语句后添加内容 # prefixOverrides:前缀覆盖掉(去掉) # suffixOverrides:后缀覆盖掉(去掉) <trim prefix="WHERE" prefixOverrides="AND |OR ">...</trim>等价于<where>.. </where> #prefixOverrides 属性会忽略通过管道符分隔的文本序列(注意此例中的空格是必要的) # 具体用法看情况,4个属性操控的都是条件语句拼接后的字符串
-
set
set主要使⽤在update语句当中,⽤来⽣成set关键字,同时去掉最后多余的“,” #相当于<trim prefix="SET" suffixOverrides=", "> update t_car <set> <if test="carNum != null and carNum != ''">car_num = #{carNum},</if> <if test="brand != null and brand != ''">brand = #{brand},</if> ... </set> where id = #{id}
-
choose (when, otherwise)
choose (when, otherwise)相当于if(){}else if(){}else{} <choose> <when> <if 条件1> </when> <when> <if 条件2> </when> <otherwise> <if 条件3> </otherwise> </choose> 最后是按条件优先级(不为空)拼接为: where 不为空且靠前的条件
-
foreach
foreach 循环数组或集合,动态⽣成sql,如:in(),or.., # 参数是数组,取别名为 ids int deleteBatchByForeach(@Param("ids") Long[] ids); # collection:集合或数组 # item:集合或数组中的元素 # separator:分隔符 # open:foreach标签中所有内容的开始 # close:foreach标签中所有内容的结束 #--------------- in(,,,) -------------- <delete id="deleteBatchByForeach"> delete from t_car where id in <foreach collection="ids" item="id" separator="," open="(" close=")"> #{id} </foreach> </delete> #--------------- or -------------- delete from t_car where <foreach collection="ids" item="id" separator="or"> id = #{id} </foreach> #--------------- 批量添加List<Object> -------------- int insertBatchByForeach(@Param("cars") List<Car> cars); <insert id="insertBatchByForeach"> insert into t_car values <foreach collection="cars" item="car" separator=","> (null,#{car.carNum},#{car.brand},#{car.guidePrice}, #{car.produceTime},#{car.carType}) </foreach> </insert>
-
sql片段与include引入
<sql id="idxx">....</sql> .. <include refid="idxx"/> ...
多表查询
多表查询的高级映射及延迟加载
直接查询(一条sql)
-
一对多
# A表属性+list<B表相关属性> # 定义映射关系 collection 表数组或Map, ofType 指该元素为X类对象 <resultMap id="clazzResultMap" type="Clazz"> <id property="cid" column="cid"/> <result property="cname" column="cname"/> <!--一对多,这里是collection。collection是集合的意思。--> <!--ofType 属性用来指定集合当中的元素类型。--> <collection property="stus" ofType="Student"> <id property="sid" column="sid"/> <result property="sname" column="sname"/> </collection> </resultMap> # 2.一条sql语句放回该结果集 eg: A left join B on 关联条件 Where 筛选条件#{} <select id="selectByCollection" resultMap="clazzResultMap"> select c.cid,c.cname,s.sid,s.sname from t_clazz c left join t_stu s on c.cid = s.cid where c.cid = #{cid} </select> # A,B 直接连接然后where筛选也是可以的
-
多对一
<!--多对一映射的第一种方式:一条SQL语句,级联属性映射。--> # A表属性+B表相关属性(级联属性映射) <resultMap id="studentResultMap" type="Student"> <id property="sid" column="sid"/> <result property="sname" column="sname"/> <result property="clazz.cid" column="cid"/> <result property="clazz.cname" column="cname"/> </resultMap> <select id="selectById" resultMap="studentResultMap"> select s.sid,s.sname,c.cid,c.cname from t_stu s left join t_clazz c on s.cid = c.cid where s.sid = #{sid} </select>
分步查询(推荐)
-
一对多
# A表属性+list<B表相关属性> <!--分步查询第一步:根据班级的cid获取班级信息。--> <resultMap id="映射结果总集id" type="Clazz"> <id property="cid" column="cid"/> <result property="cname" column="cname"/> <collection property="stut" (Clazz对象的list<B表>属性的数组名) select="com/../B接口类名.子集查询方法" column="cid" (查询条件) fetchType="lazy/eager" /> (lazy 懒加载 ) </resultMap> <select id="总调用查询方法" resultMap="映射结果总集id"> select cid,cname from t_clazz where cid = #{cid} </select> B表Mapper中 <select id="子集查询方法" resultType="Student"> select * from t_stu where cid = #{cid} </select>
-
多对一
<resultMap id="映射结果总集id" type="Student"> <id property="sid" column="sid"/> <result property="sname" column="sname"/> <association property="clazz" select="com/../B接口类名.子集查询方法" column="cid" fetchType="eager"/> </resultMap> <select id="总调用查询方法" resultMap="映射结果总集id"> select sid,sname,cid from t_stu where sid = #{sid} </select> B表Mapper中 <!--分步查询第二步:根据cid获取班级信息。--> <select id="子集查询方法" resultType="Clazz"> select cid,cname from t_clazz where cid = #{cid} </select>
-
多对多
分布查询懒加载
分步查询的优点:
第一:复用性增强。可以重复利用。(大步拆成N多个小碎步。每一个小碎步更加可以重复利用。)
第二:采用这种分步查询,可以充分利用他们的延迟加载/懒加载机制。
总结:提高性能。尽可能的不查,或者说尽可能的少查。来提高效率。
开启延迟加载:
1.分步查询的association标签中的fetchType属性
(默认为eager)设置fetchType="lazy"开启只对当前的association关联的sql语句起作用。
2.在mybatis核心配置文件中添加全局配置:lazyLoadingEnabled=true
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
</settings>
实际开发中:把全局的延迟加载打开。
如果某一步不需要使用延迟加载,请设置:fetchType="eager"
mybatis缓存
-
⼀级缓存:将查询到的数据存储到SqlSession中。
-
⼆级缓存:将查询到的数据存储到SqlSessionFactory中。
-
集成其它第三⽅的缓存(2级):⽐如EhCache【Java语⾔开发的】、Memcache【C语⾔开发的】等。
⼀级缓存默认是开启的。不需要做任何配置。
⼆级缓存的范围是SqlSessionFactory。使⽤⼆级缓存需要具备以下⼏个条件:
- 全局性地开启或关闭所有映射器配置⽂件中已配置的任何缓存。默认就是true,⽆需设置。
-
在需要使⽤⼆级缓存的SqlMapper.xml⽂件中添加配置:
-
使⽤⼆级缓存的实体类对象必须是可序列化的,也就是必须实现java.io.Serializable接⼝
-
SqlSession对象关闭或提交之后,⼀级缓存中的数据才会被写⼊到⼆级缓存当中。
此时⼆级缓存才可⽤。
cache 配置
1.eviction:指定从缓存中移除某个对象的淘汰算法。默认采⽤LRU策略。
a. LRU:Least Recently Used。最近最少使⽤。优先淘汰在间隔时间内使⽤频率最低的对象。(其
实还有⼀种淘汰算法LFU,最不常⽤。)
b. FIFO:First In First Out。⼀种先进先出的数据缓存器。先进⼊⼆级缓存的对象最先被淘汰。
c. SOFT:软引⽤。淘汰软引⽤指向的对象。具体算法和JVM的垃圾回收算法有关。
d. WEAK:弱引⽤。淘汰弱引⽤指向的对象。具体算法和JVM的垃圾回收算法有关。
2. flushInterval:
a. ⼆级缓存的刷新时间间隔。单位毫秒。如果没有设置。就代表不刷新缓存,只要内存⾜够⼤,⼀
直会向⼆级缓存中缓存数据。除⾮执⾏了增删改。
3. readOnly:
a. true:多条相同的sql语句执⾏之后返回的对象是共享的同⼀个。性能好。但是多线程并发可能
会存在安全问题。
b. false:多条相同的sql语句执⾏之后返回的对象是副本,调⽤了clone⽅法。性能⼀般。但安
全。
4. size:
a. 设置⼆级缓存中最多可存储的java对象数量。默认值1024。
集成第三方二级缓存
Maven 导包 EhCache
<!--mybatis集成ehcache的组件-->
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.2.2</version>
</dependency>
<!--ehcache需要slf4j的⽇志组件,log4j不好使-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.11</version>
<scope>test</scope>
</dependency>
配置echcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false">
<!--磁盘存储:将缓存中暂时不使⽤的对象,转移到硬盘,类似于Windows系统的虚拟内存-->
<diskStore path="e:/ehcache"/>
<!--defaultCache:默认的管理策略-->
<!--eternal:设定缓存的elements是否永远不过期。如果为true,则缓存的数据始终有
效,如果为false那么还要根据timeToIdleSeconds,timeToLiveSeconds判断-->
<!--maxElementsInMemory:在内存中缓存的element的最⼤数⽬-->
<!--overflowToDisk:如果内存中数据超过内存限制,是否要缓存到磁盘上-->
<!--diskPersistent:是否在磁盘上持久化。指重启jvm后,数据是否有效。默认为false-
->
<!--timeToIdleSeconds:对象空闲时间(单位:秒),指对象在多⻓时间没有被访问就会失
效。只对eternal为false的有效。默认值0,表示⼀直可以访问-->
<!--timeToLiveSeconds:对象存活时间(单位:秒),指对象从创建到失效所需要的时间。
只对eternal为false的有效。默认值0,表示⼀直可以访问-->
<!--memoryStoreEvictionPolicy:缓存的3 种清空策略-->
<!--FIFO:first in first out (先进先出)-->
<!--LFU:Less Frequently Used (最少使⽤).意思是⼀直以来最少被使⽤的。缓存的元
素有⼀个hit 属性,hit 值最⼩的将会被清出缓存-->
<!--LRU:Least Recently Used(最近最少使⽤). (ehcache 默认值).缓存的元素有⼀
个时间戳,当缓存容量满了,⽽⼜需要腾出地⽅来缓存新的元素的时候,那么现有缓存元素中时间戳
离当前时间最远的元素将被清出缓存-->
<defaultCache eternal="false" maxElementsInMemory="1000" overflowToDis
k="false" diskPersistent="false"
timeToIdleSeconds="0" timeToLiveSeconds="600" memoryStor
eEvictionPolicy="LRU"/>
</ehcache>
修改SqlMapper.xml⽂件中的标签,添加type属性。即可使用
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
MyBatis的逆向⼯程
逆向⼯程插件直接根据数据库表逆向⽣成Java的pojo类,SqlMapper.xml⽂件,以及Mapper接⼝类
等。这个别看了,Mybatis-plus 更方便
Maven导包
<!--配置mybatis逆向工程的插件-->
<!--定制构建过程-->
<build>
<!--可配置多个插件-->
<plugins>
<!--其中的一个插件:mybatis逆向工程插件-->
<plugin>
<!--插件的GAV坐标-->
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.4.1</version>
<!--允许覆盖-->
<configuration>
<overwrite>true</overwrite>
</configuration>
<!--插件的依赖-->
<dependencies>
<!--mysql驱动依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
配置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>
<!--
targetRuntime有两个值:
MyBatis3Simple:生成的是基础版,只有基本的增删改查。
MyBatis3:生成的是增强版,除了基本的增删改查之外还有复杂的增删改查。
-->
<context id="DB2Tables" targetRuntime="MyBatis3Simple">
<!--防止生成重复代码-->
<plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin"/>
<commentGenerator>
<!--是否去掉生成日期-->
<property name="suppressDate" value="true"/>
<!--是否去除注释-->
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<!--连接数据库信息-->
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/powernode"
userId="root"
password="123456">
</jdbcConnection>
<!-- 生成pojo包名和位置 -->
<javaModelGenerator targetPackage="com.powernode.mybatis.pojo" targetProject="src/main/java">
<!--是否开启子包-->
<property name="enableSubPackages" value="true"/>
<!--是否去除字段名的前后空白-->
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!-- 生成SQL映射文件的包名和位置 -->
<sqlMapGenerator targetPackage="com.powernode.mybatis.mapper" targetProject="src/main/resources">
<!--是否开启子包-->
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>
<!-- 生成Mapper接口的包名和位置 -->
<javaClientGenerator
type="xmlMapper"
targetPackage="com.powernode.mybatis.mapper"
targetProject="src/main/java">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator>
<!-- 表名和对应的实体类名-->
<table tableName="t_car" domainObjectName="Car"/>
</context>
</generatorConfiguration>
用maven运行插件即可
PageHelper分页
引⼊依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.3.1</version>
</dependency>
在mybatis-config.xml⽂件中配置插件
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
编写Java代码
// 开启分⻚
PageHelper.startPage(2, 2);
// 执⾏查询语句
List<Car> cars = mapper.selectAll();
// 获取分⻚信息对象
PageInfo<Car> pageInfo = new PageInfo<>(cars, 5);
pageInfo 包含信息:
PageInfo{
pageNum=2, pageSize=2, size=2, startRow=3, endRow=4, total=6, pages=3,
list=Page{count=true, pageNum=2, pageSize=2, startRow=2, endRow=4,
total=6, pages=3,reasonable=false, pageSizeZero=false}
[Car{id=86, carNum='1234', brand='丰⽥霸道',guidePrice=50.5,
produceTime='2020-10-11', carType='燃油⻋'},
Car{id=87, carNum='1234',brand='丰⽥霸道', guidePrice=50.5,
produceTime='2020-10-11', carType='燃油⻋'}],
prePage=1,nextPage=3, isFirstPage=false, isLastPage=false,
hasPreviousPage=true, hasNextPage=true,navigatePages=5,
navigateFirstPage=1, navigateLastPage=3, navigatepageNums=[1, 2, 3]}
// 可以很好的展示分页
注解开发
package com.powernode.mybatis.mapper;
import com.powernode.mybatis.pojo.Car;
import org.apache.ibatis.annotations.*;
public interface CarMapper {
@Select("select * from t_car where id = #{id}")
@Results({
@Result(property = "id", column = "id"),
@Result(property = "carNum", column = "car_num"),
@Result(property = "brand", column = "brand"),
@Result(property = "guidePrice", column = "guide_price"),
@Result(property = "produceTime", column = "produce_time"),
@Result(property = "carType", column = "car_type")
})
Car selectById(Long id);
@Update("update t_car set car_num=#{carNum},brand=#{brand},guide_price=#{guidePrice},produce_time=#{produceTime},car_type=#{carType} where id=#{id}")
int update(Car car);
@Insert("insert into t_car values(null,#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType})")
int insert(Car car);
@Delete("delete from t_car where id = #{id}")
int deleteById(Long id);
}
增Insert,删Delete,改Update,查Select,Results对应映射
简单的SQL用注解,复杂的用.xml配置