1 概述
MyBaits
是一个驰名的长久层框架,本文首先介绍了MyBatis
的简略应用,接着与Spring
进行整合,最初简略地应用了Generator
去主动生成代码。
2 MyBatis
简介
MyBatis
原本是Apache
的一个开源我的项目——iBatis
,2010年由Apaceh Software Foundation
迁徙到了Google Code
,并改名为MyBatis
。
MyBatis
是一个基于Java
的长久层框架,提供的长久层框架包含SQL Maps
和Data Access Objects
,应用简略的XML
或者注解用于配置映射,将接口和POJO
映射成数据库中的记录,是一个玲珑、不便、高效、简略、间接、半自动化的长久层框架。
3 工作原理
上图:
- 读取配置文件:
mybatis-config.xml
是全局MyBatis
配置文件,配置了MyBatis
运行环境信息 - 加载映射文件:也就是
SQL
映射文件,配置了操作数据库的SQL
语句 - 结构会话工厂:通过配置文件结构会话工厂
SqlSessionFactory
- 创立会话对象:由上一步的会话工厂创立会话对象
SqlSession
- 获取
MapperStatement
:通过用户调用的api
的Statement ID
获取MapperStatement
对象 - 输出参数映射:通过
Executor
对MapperStatement
进行解析,将各种Java
根本类型转化为SQL
操作语句中的类型 - 输入后果映射:
JDBC
执行SQL
后,借助MapperStatement
的映射关系将返回后果转化为Java
根本类型并返回
4 MyBatis
示例
首先先来看一下纯MyBaits
的示例,没有整合Spring
,一个简略的Maven
工程,我的项目构造如下:
4.1 依赖
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.5</version></dependency><dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version></dependency><!--驱动用的是MySQL,版本请自行批改--><dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.21</version></dependency>
Gradle
:
compile group: 'org.mybatis', name: 'mybatis', version: '3.5.5'compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.21'
4.2 实体类
@Setter@Getter@Builderpublic class User { private Integer id; private String name; @Override public String toString() { return "id:"+id+"\tname:"+name; }}
4.3 映射文件
新建一个叫UserMapper.xml
的映射文件:
<?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="UserMapper"> <select id="selectById" parameterType="Integer" resultType="pers.entity.User"> select * from user where id=#{id} </select> <select id="selectAll" resultType="pers.entity.User"> select * from user </select> <insert id="insert" parameterType="pers.entity.User"> INSERT INTO `user` (`id`,`name`) VALUES (#{id},#{name}) </insert> <update id="update" parameterType="pers.entity.User"> UPDATE `user` set `name`=#{name} where id=#{id} </update> <delete id="delete" parameterType="Integer"> DELETE FROM `user` WHERE `id` = #{id} </delete></mapper>
映射文件是一个XML
文件,根元素为<mapper>
,须要留神其中的namespace
属性,调用的时候通过该namespace
调用。其中的子元素示意SQL
语句:
<select>
:查问,id
指定了这条语句的id
号,调用时通过namespace.id
的形式调用,比方该条select
须要通过UserMapper.selectById
调用,parameterType
指定参数类型,这里是一个Integer
的参数,resultType
指定返回类型,实体类<insert>
/<update>
/<delete>
:对应的插入/批改/删除语句- 对于占位符:
#{}
示意是占位符,相当于传统JDBC
中的?
,#{id}
示意该占位符期待接管的参数名称为id
4.4 配置文件
MyBatis
的配置文件,叫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> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test"/> <property name="username" value="test"/> <property name="password" value="test"/> </dataSource> </environment> </environments> <mappers> <mapper resource="mapper/UserMapper.xml" /> </mappers></configuration>
指定了数据库的一些连贯属性还有mapper
的地位。
4.5 测试
public class Main { public static void main(String[] args) { try { InputStream inputStream = Resources.getResourceAsStream("config/mybatis-config.xml"); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession session = factory.openSession(); User user = session.selectOne("UserMapper.selectById",1); System.out.println(user); User user1 = User.builder().name("test").build(); session.insert("UserMapper.insert",user1); user1.setName("222"); session.update("UserMapper.update",user1); List<User> list = session.selectList("UserMapper.selectAll"); list.forEach(System.out::println); session.delete("UserMapper.delete",1); session.commit(); session.close(); } catch (Exception e) { e.printStackTrace(); } }}
次要流程如下:
- 读取配置文件:依据
org.apache.ibatis.io.Resources
读取配置文件mybatis-config.xml
,请留神配置文件的地位正确,这里的配置文件都放在resources
下,mybatis-config.xml
放在其中的config
下 - 构建
Session
:依据配置文件构建SqlSessionFactory
后,通过openSession
创立Session
- 业务操作:通过
session
的selectOne/insert/update
等进行业务操作,这类操作带两个参数,第一个参数是String
,示意配置文件中的SQL
语句,采纳namespace.id
的模式,比方这里的UserMapper.xml
中申明namespace
为UserMapper
,其中带有一条id
为selectById
的select
语句,因而调用时应用UserMapper.selectById
的模式,第二个参数是一个Object
,示意要传递的参数,也就是绑定到配置文件中对应占位符的值 - 提交与敞开:业务操作实现后提交事务并敞开
session
示例测试后果:
5 Spring
整合示例
下面的例子只是为了演示MyBatis
的根本应用,没有整合Spring
,这里的例子是把Spring
整合进来,流程也大略差不多,我的项目构造如下:
5.1 依赖
分为5类JAR
:
MyBatis
须要的JAR
Spring
须要的JAR
MyBatis
与Spring
整合的两头JAR
- 数据库驱动
JAR
- 数据源
JAR
残缺依赖如下:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.9.RELEASE</version></dependency><dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.2.9.RELEASE</version></dependency><dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.2.9.RELEASE</version></dependency><dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.2.9.RELEASE</version></dependency><dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version></dependency><dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.9.RELEASE</version></dependency><dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.21</version></dependency><dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.2.9.RELEASE</version></dependency><dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.5</version></dependency><dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.5</version></dependency><dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-dbcp2</artifactId> <version>2.8.0</version></dependency>
Gradle
:
compile group: 'org.springframework', name: 'spring-beans', version: '5.2.9.RELEASE'compile group: 'org.springframework', name: 'spring-context', version: '5.2.9.RELEASE'compile group: 'org.springframework', name: 'spring-core', version: '5.2.9.RELEASE'compile group: 'org.springframework', name: 'spring-tx', version: '5.2.9.RELEASE'compile group: 'org.springframework', name: 'spring-jdbc', version: '5.2.9.RELEASE'compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.21'compile group: 'org.apache.commons', name: 'commons-dbcp2', version: '2.8.0'compile group: 'org.mybatis', name: 'mybatis', version: '3.5.5'compile group: 'org.mybatis', name: 'mybatis-spring', version: '2.0.5'
5.2 配置文件
配置文件分为三类:
MyBatis
映射文件:编写mapper
的中央,也就是业务须要的SQL
语句MyBatis
全局配置文件:因为整合了Spring
,数据源的配置放在了Spring
的配置文件中,而只须要保留mapper
的查找地位Spring
配置文件:配置数据源+事务管理+MyBaits
的sqlSssionFactory
+组件扫描
5.2.1 MyBatis
映射文件
与下面的例子差不多,只是批改了namespace
为包名.类名
的模式:
<?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="pers.dao.UserDao"> <select id="selectById" parameterType="Integer" resultType="pers.entity.User"> select * from user where id=#{id} </select> <select id="selectAll" resultType="pers.entity.User"> select * from user </select> <insert id="insert" parameterType="pers.entity.User"> INSERT INTO `user` (`id`,`name`) VALUES (#{id},#{name}) </insert> <update id="update" parameterType="pers.entity.User"> UPDATE `user` set `name`=#{name} where id=#{id} </update> <delete id="delete" parameterType="Integer"> DELETE FROM `user` WHERE `id` = #{id} </delete></mapper>
namespace
须要与对应包名的带有@Mapper
的类配置统一。
5.2.2 MyBatis
配置文件
<?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> <mappers> <mapper resource="mapper/UserMapper.xml" /> </mappers></configuration>
5.2.3 Spring
配置文件
<?xml version="1.0" encoding="utf-8" ?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd" > <context:component-scan base-package="pers.dao"/> <context:component-scan base-package="pers.service"/> <!--数据源--> <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test"/> <property name="username" value="test"/> <property name="password" value="test"/> <!--最大连接数+最大闲暇数+初始连接数--> <property name="maxTotal" value="30"/> <property name="maxIdle" value="10"/> <property name="initialSize" value="5"/> </bean> <!--事务管理--> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!--开启事务注解--> <tx:annotation-driven transaction-manager="txManager" /> <!--创立SqlSessionFactory Bean--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="configLocation" value="classpath:config/mybatis-config.xml"/> </bean> <!--注解扫描,次要用于@Mapper,会扫描basePackge下的@Mapper注解的接口并主动拆卸为MyBatis的映射接口--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="pers.dao"/> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> </bean></beans>
5.3 长久层
须要加上@Mapper
注解,示意主动拆卸为MyBatis
的映射接口,留神:
- 映射文件中的
namespace
须要与包名.类名
对应,比方这里的包为pers.dao
,类名为UserDao
,那么映射文件中的namespace
为pers.dao.UserDao
id
须要与办法名对应,比方映射文件中的有一条select
语句的id
为selectById
,那么办法就须要命名为selectById
,且参数类型须要对应统一
@Repository@Mapperpublic interface UserDao { User selectById(Integer id); List<User> selectAll(); int insert(User user); int update(User user); int delete(Integer id);}
5.4 业务层
@Service@Transactional@RequiredArgsConstructor(onConstructor = @__(@Autowired))public class MyBatisService { private final UserDao dao; public void test(){ User user = dao.selectById(13); System.out.println(user); dao.insert(User.builder().name("333").build()); dao.update(User.builder().name("88888").id(13).build()); dao.selectAll().forEach(System.out::println); dao.delete(12); dao.selectAll().forEach(System.out::println); }}
注入UserDao
后进行简略的测试,后果如下:
6 主动生成代码
置信很多程序员也厌恶写又长又麻烦的XML
配置文件,因而,MyBatis
也提供了一个生成器插件,能够间接从表中生成实体类、dao
接口以及映射文件,能够省去很多操作。
步骤如下:
- 导入依赖
- 编写
Generator
配置文件 - 生成代码
6.1 依赖
其实就是退出一个插件:
<build> <plugins> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.4.0</version> <configuration> <!-- 在控制台打印执行日志 --> <verbose>true</verbose> <!-- 反复生成时会笼罩之前的文件--> <overwrite>true</overwrite> <configurationFile>src/main/resources/generatorConfig.xml</configurationFile> </configuration> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.21</version> </dependency> </dependencies> </plugin> </plugins></build>
数据库驱动请对应批改。
至于Gradle
版请看Kotlin
版源码。
6.2 配置文件
这里是参考他人的配置文件,批改数据库连贯、表名、包名即可:
<?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> <!-- context 是逆向工程的次要配置信息 --> <!-- id:起个名字 --> <!-- targetRuntime:设置生成的文件实用于那个 mybatis 版本 --> <context id="default" targetRuntime="MyBatis3"> <!--optional,指在创立class时,对正文进行管制--> <commentGenerator> <property name="suppressDate" value="true"/> <!-- 是否去除主动生成的正文 true:是 : false:否 --> <property name="suppressAllComments" value="true"/> </commentGenerator> <!--jdbc的数据库连贯 wg_insert 为数据库名字--> <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/test" userId="test" password="test" /> <!--非必须,类型处理器,在数据库类型和java类型之间的转换管制--> <javaTypeResolver> <!-- 默认状况下数据库中的 decimal,bigInt 在 Java 对应是 sql 下的 BigDecimal 类 --> <!-- 不是 double 和 long 类型 --> <!-- 应用罕用的根本类型代替 sql 包下的援用类型 --> <property name="forceBigDecimals" value="false"/> </javaTypeResolver> <!-- targetPackage:生成的实体类所在的包 --> <!-- targetProject:生成的实体类所在的硬盘地位 --> <javaModelGenerator targetPackage="pers.entity" targetProject="src/main/java"> <!-- 是否容许子包 --> <property name="enableSubPackages" value="false"/> <!-- 是否对modal增加构造函数 --> <property name="constructorBased" value="true"/> <!-- 是否清理从数据库中查问出的字符串左右两边的空白字符 --> <property name="trimStrings" value="true"/> <!-- 建设modal对象是否不可扭转 即生成的modal对象不会有setter办法,只有构造方法 --> <property name="immutable" value="false"/> </javaModelGenerator> <!-- targetPackage 和 targetProject:生成的 mapper 文件的包和地位 --> <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources"> <!-- 针对数据库的一个配置,是否把 schema 作为字包名 --> <property name="enableSubPackages" value="false"/> </sqlMapGenerator> <!-- targetPackage 和 targetProject:生成的 interface 文件的包和地位 --> <javaClientGenerator type="XMLMAPPER" targetPackage="pers.dao" targetProject="src/main/java"> </javaClientGenerator> <!-- tableName是数据库中的表名,domainObjectName是生成的JAVA模型名,前面的参数不必改,要生成更多的表就在上面持续加table标签 --> <table tableName="user" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false" /> </context></generatorConfiguration>
6.3 生成代码
双击生成即可:
生成了实体类、dao
接口以及mapper
文件。
7 参考源码
Java
版:
- Github
- 码云
- CODE.CHINA
Kotlin
版:
- Github
- 码云
- CODE.CHINA
8 参考链接
- 简书-IDEA应用mybatis-generator
- Github-mybatis-generator-plugin