8.2 MyBatis入门 MyBatis
的用法非常简单,我们只要在Java
项目中引入 MyBatis
框架,就能以面向对象的方式操作关系数据库 。
8.2.1 MyBatis下载和安装 下载mybatis 进入mybatis在github上的仓库 ,进入releases ,找到最近发布版本,展开Assets
下拉列表,然后点击mybatis-3.5.2.zip
超链接,下载连接即可.
mybatis目录结构 下载后,解压mybatis
的压缩包,进入解压后的目录,目录结构如下:
D:\Desktop\随书源码\库文件\mybatis-3.5.2
├─lib\
│ ├─ant-1.10.3.jar
│ ├─ant-launcher-1.10.3.jar
│ ├─asm-7.0.jar
│ ├─cglib-3.2.10.jar
│ ├─commons-logging-1.2.jar
│ ├─javassist-3.24.1-GA.jar
│ ├─log4j-1.2.17.jar
│ ├─log4j-api-2.11.2.jar
│ ├─log4j-core-2.11.2.jar
│ ├─ognl-3.2.10.jar
│ ├─slf4j-api-1.7.26.jar
│ └─slf4j-log4j12-1.7.26.jar
├─LICENSE
├─mybatis-3.5.2.jar
├─mybatis-3.5.2.pdf
└─NOTICE
我们需要的是,当前目录下的mybatis-3.5.2.jar
这个文件.
提示 由于MyBatis
的底层依然是基于JDBC
的,因此在应用程序中使用MyBatis
执行持久化时同样少不了JDBC
驱动。本示例程序底层采用了MySQL
数据库,因此还需要将MySQL
数据库驱动添加到应用程序的类加载路径中 。
下载MySQL的Java驱动 进入这个站点 ,即可下载mysql
驱动。在写这篇文章的时候,最新的驱动版本是8.0
版本的驱动。8.0版本的驱动支持MySQL5.5
开始的后续MySQL
版本。下载最新版本即可.
MySQL的Java驱动目录结果 展开/折叠
D:\Desktop\随书源码\库文件\mysql-connector-java-8.0.17
├─build.xml
├─CHANGES
├─INFO_BIN
├─INFO_SRC
├─LICENSE
├─mysql-connector-java-8.0.17.jar
├─README
└─src\
下载log4j 使用log4j来输出日志,如打印运行的SQL命令等. 进入log4j下载站点 ,然后选择镜像
,在镜像的HTTP 几个大字下,点击log4j对应的链接,即可下载.
log4j目录结构 展开/折叠
D:\Desktop\随书源码\库文件\apache-log4j-2.13.3-bin
├─LICENSE.txt
├─log4j-1.2-api-2.13.3-javadoc.jar
├─log4j-1.2-api-2.13.3-sources.jar
├─log4j-1.2-api-2.13.3.jar
├─log4j-api-2.13.3-javadoc.jar
├─log4j-api-2.13.3-sources.jar
├─log4j-api-2.13.3.jar
├─log4j-appserver-2.13.3-javadoc.jar
├─log4j-appserver-2.13.3-sources.jar
├─log4j-appserver-2.13.3.jar
├─log4j-cassandra-2.13.3-javadoc.jar
├─log4j-cassandra-2.13.3-sources.jar
├─log4j-cassandra-2.13.3.jar
├─log4j-core-2.13.3-javadoc.jar
├─log4j-core-2.13.3-sources.jar
├─log4j-core-2.13.3-tests.jar
├─log4j-core-2.13.3.jar
├─log4j-couchdb-2.13.3-javadoc.jar
├─log4j-couchdb-2.13.3-sources.jar
├─log4j-couchdb-2.13.3.jar
├─log4j-docker-2.13.3-javadoc.jar
├─log4j-docker-2.13.3-sources.jar
├─log4j-docker-2.13.3.jar
├─log4j-flume-ng-2.13.3-javadoc.jar
├─log4j-flume-ng-2.13.3-sources.jar
├─log4j-flume-ng-2.13.3.jar
├─log4j-iostreams-2.13.3-javadoc.jar
├─log4j-iostreams-2.13.3-sources.jar
├─log4j-iostreams-2.13.3.jar
├─log4j-jcl-2.13.3-javadoc.jar
├─log4j-jcl-2.13.3-sources.jar
├─log4j-jcl-2.13.3.jar
├─log4j-jdbc-dbcp2-2.13.3-javadoc.jar
├─log4j-jdbc-dbcp2-2.13.3-sources.jar
├─log4j-jdbc-dbcp2-2.13.3.jar
├─log4j-jmx-gui-2.13.3-javadoc.jar
├─log4j-jmx-gui-2.13.3-sources.jar
├─log4j-jmx-gui-2.13.3.jar
├─log4j-jpa-2.13.3-javadoc.jar
├─log4j-jpa-2.13.3-sources.jar
├─log4j-jpa-2.13.3.jar
├─log4j-jul-2.13.3-javadoc.jar
├─log4j-jul-2.13.3-sources.jar
├─log4j-jul-2.13.3.jar
├─log4j-liquibase-2.13.3-javadoc.jar
├─log4j-liquibase-2.13.3-sources.jar
├─log4j-liquibase-2.13.3.jar
├─log4j-mongodb2-2.13.3-javadoc.jar
├─log4j-mongodb2-2.13.3-sources.jar
├─log4j-mongodb2-2.13.3.jar
├─log4j-mongodb3-2.13.3-javadoc.jar
├─log4j-mongodb3-2.13.3-sources.jar
├─log4j-mongodb3-2.13.3.jar
├─log4j-slf4j-impl-2.13.3-javadoc.jar
├─log4j-slf4j-impl-2.13.3-sources.jar
├─log4j-slf4j-impl-2.13.3.jar
├─log4j-slf4j18-impl-2.13.3-javadoc.jar
├─log4j-slf4j18-impl-2.13.3-sources.jar
├─log4j-slf4j18-impl-2.13.3.jar
├─log4j-spring-cloud-config-client-2.13.3-javadoc.jar
├─log4j-spring-cloud-config-client-2.13.3-sources.jar
├─log4j-spring-cloud-config-client-2.13.3.jar
├─log4j-taglib-2.13.3-javadoc.jar
├─log4j-taglib-2.13.3-sources.jar
├─log4j-taglib-2.13.3.jar
├─log4j-to-slf4j-2.13.3-javadoc.jar
├─log4j-to-slf4j-2.13.3-sources.jar
├─log4j-to-slf4j-2.13.3.jar
├─log4j-web-2.13.3-javadoc.jar
├─log4j-web-2.13.3-sources.jar
├─log4j-web-2.13.3.jar
├─NOTICE.txt
└─RELEASE-NOTES.md
MyBatis的数据库操作入门 项目结构 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 D:\Desktop \随书源码\Spring +Mybatis 企业应用实战(第2版)\codes \08\MyBatisQs ├─src \ │ ├─log4j.properties │ ├─mybatis -config.xml │ └─org \ │ └─fkit \ │ ├─domain \ │ │ ├─crateDatabase.sql │ │ ├─createTable.sql │ │ ├─test.sql │ │ ├─User.java │ │ └─user_inf.sql │ ├─mapper \ │ │ └─UserMapper.xml │ └─test \ │ └─MyBatisTest.java └─WebContent \ ├─META -INF \ │ └─MANIFEST.MF └─WEB -INF \ ├─lib \ │ ├─commons -logging -1.2.jar │ ├─log4j -1.2.17.jar │ ├─log4j -api -2.3.jar │ ├─log4j -core -2.3.jar │ ├─mybatis -3.4.5.jar │ ├─mysql -connector -java -5.1.44-bin.jar └─web.xml
引入jar文件到lib目录 引入mybatis的jar文件 进入mybatis目录,使用如下copy
命令把mybatis
的jar
包复制到web
项目的lib
目录中.
1 copy mybatis-3 .5 .2 .jar E:\workspacne_JDK8Tomcat8.5 \MyBatisTest\WebContent\WEB-INF\lib
复制效果如下:
D:\Desktop\随书源码\库文件\mybatis-3.5.2>copy mybatis-3.5.2.jar E:\workspacne_JDK8Tomcat8.5\MyBatisTest\WebContent\WEB-INF\lib
已复制 1 个文件。
引入mysql驱动 进入解压后的mysql驱动目录,打开cmd,输入如下命令进行复制:
1 copy mysql-connector-java-8 .0 .17 .jar E:\workspacne_JDK8Tomcat8.5 \MyBatisTest\WebContent\WEB-INF\lib
复制效果如下:
D:\Desktop\随书源码\库文件\mysql-connector-java-8.0.17>copy mysql-connector-java-8.0.17.jar E:\workspacne_JDK8Tomcat8.5\MyBatisTest\WebContent\WEB-INF\lib
已复制 1 个文件。
引入log4j的jar包 解压下载好的log4j
压缩包,我发现有好多jar
包啊,官网上给出的消息如下:
Using Log4j on your classpath To use Log4j 2 in your application make sure that both the API and Core jars are in the application’s classpath. Add the dependencies listed below to your classpath.
log4j-api-2.13.3.jar
log4j-core-2.13.3.jar
You can do this from the command line or a manifest file.
所以,复制log4j-api-版本号.jar
,和log4j-core-版本号.jar
这两个文件到web
项目的lib
目录下即可.
1 2 copy log4j-api-2 .13 .3 .jar E:\workspacne_JDK8Tomcat8.5 \MyBatisTest\WebContent\WEB-INF\libcopy log4j-core-2 .13 .3 .jar E:\workspacne_JDK8Tomcat8.5 \MyBatisTest\WebContent\WEB-INF\lib
D:\Desktop\随书源码\库文件\apache-log4j-2.13.3-bin>copy log4j-api-2.13.3.jar E:\workspacne_JDK8Tomcat8.5\MyBatisTest\WebContent\WEB-INF\lib
已复制 1 个文件。
D:\Desktop\随书源码\库文件\apache-log4j-2.13.3-bin>copy log4j-core-2.13.3.jar E:\workspacne_JDK8Tomcat8.5\MyBatisTest\WebContent\WEB-INF\lib
已复制 1 个文件。
创建数据库 mybatis 1 2 # 创建一个数据库,指定数据库的字符为真正的utf-8 编码 create database `mybatis` default character set utf8;
创建数据表 tb_user 1 2 3 4 5 6 7 8 9 10 11 # 使用刚才创建的数据库 use mybatis; # 创建表格tb_user drop table if exists tb_user;create table tb_user( id int (11 ) not null auto_increment, name varchar (18 ) default null , sex char (2 ) default null , age int (11 ) default null , primary key (id) );
创建成功效果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 mysql> # 创建一个数据库,指定数据库的字符为真正的utf-8 编码 create database `mybatis` default character set utf8; Query OK, 1 row affected (0 .02 sec) mysql> # 使用刚才创建的数据库 use mybatis; # 创建表格tb_user drop table if exists tb_user; create table tb_user( id int(11 ) not null auto_increment, name varchar(18 ) default null, sex char(2 ) default null, age int(11 ) default null, primary key (id) ); Query OK, 0 rows affected (0 .00 sec) Query OK, 0 rows affected (0 .00 sec) Query OK, 0 rows affected (0 .04 sec)
好了,有了数据表,现在来创建对应的持久化类.
创建持久化类 User.java 持久化对象 PO 在所有的ORM
框架中都有一个非常重要的媒介:PO
(持久化对象)。持久化对象的作用就是完成持久化操作 ,简单地说,就是通过持久化对象来对数据库执行增、删、改的操作,以面向对象的方式操作数据库 应用程序无须直接访问数据库,甚至无须理会底层数据库采用何种数据库,应用程序只需创建、修改、删除持久化对象即可 ;与此同时**MyBatis
则负责把这种操作转换为对指定数据库表的操作**。MyBatis
完全采用普通的Java
对象作为持久化对象使用
User.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 public class User implements Serializable { private static final long serialVersionUID = 1L ; private Integer id; private String name; private String sex; private Integer age; public User () { super (); } public User (String name, String sex, Integer age) { super (); this .name = name; this .sex = sex; this .age = age; } @Override public String toString () { return "User [id=" + id + ", name=" + name + ", sex=" + sex + ", age=" + age + "]" ; } }
POJO 仔细看上面这个类的代码,会发现这个类与普通的JavaBean
没有任何区别。实际上,MyBatis
直接采用了POJO
(普通的、传统的Java
对象)作为持久化类 ,这就是MyBatis
被称非低侵入式设计的原因。 MyBatis不要求持久化类继承任何父类,或者实现任何接口 ,这样可保证代码不被污染。
UserMapper.xml 映射持久化类和数据表 MyBatis
是通过XML
文件去完成持久化类和数据库表之间的映射关系的.
1 2 3 4 5 6 7 8 9 10 11 12 13 <?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 ="org.fkit.mapper.UserMapper" > <insert id ="save" parameterType ="org.fkit.domain.User" useGeneratedKeys ="true" > insert into tb_user(name,sex,age) values(#{name},#{sex},#{age}) </insert > </mapper >
mapper标签的namespace属性 上面的XML
配置中定义了一条insert
语句,详细解释如下<mapper namespace="org.fkit.mapper.UserMapper">
: 为这个mapper
指定一个唯一的namespace
,namespace
的值习惯上设置成包名+SQL映射文件名
,这样就能够保证namespace
的值是唯一的,例如namespace="org.fkit.mapper.UserMapper"
就是org.fkit.mapper
(包名)+UserMapper
(UserMapper.xml
去除后缀后的文件名)
mapper标签的子标签insert详解 1 2 3 4 5 <insert id ="save" parameterType ="org.fkit.domain.User" useGeneratedKeys ="true" > insert into tb_user(name,sex,age) values(#{name},#{sex},#{age})</insert >
id属性 在insert
标签中编写了SQL
插入语句,设置insert
标签的id
属性值为save
。id属性值必须是唯一的,不能够重复 。
parameterType属性 使用parameterType
属性指明插入时使用的参数类型,属性值设置为持久化对象的全限定名 。
useGeneratedKeys属性 使用useGeneratedKeys="true"
表示使用数据库的自动增长策略 ,这需要底层数据库的支持。
insert语句 insert
标签中只有一条标准的insert
语句,用来向tb_user
表插入一条数据,#{name}
表示取参数中的对象的name
属性值。
mybatis-config.xml Mybatis根配置文件 对于MyBatis
来说,现在还不知道需要连接哪个数据库,以及连接数据库时所用的连接池
、用户名
和密码
等详细信息。这些信息对于所有的持久化类都是通用的,MyBatis
把这些通用信息称为根配置信息
,根配置信息需要使用配置文件指定。MyBatis
根配置文件默认被命名为mybatis-config.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 <?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 > <settings > <setting name ="logImpl" value ="LOG4J" /> </settings > <environments default ="mysql" > <environment id ="mysql" > <transactionManager type ="JDBC" /> <dataSource type ="POOLED" > <property name ="driver" value ="com.mysql.jdbc.Driver" /> <property name ="url" value ="jdbc:mysql://127.0.0.1:3306/mybatis" /> <property name ="username" value ="root" /> <property name ="password" value ="root" /> </dataSource > </environment > </environments > <mappers > <mapper resource ="org/fkit/mapper/UserMapper.xml" /> </mappers > </configuration >
配置文件详解 XML文件声明 MyBatis
配置文件是一个XML
文件,该文件第一行是XML
文件声明,指定该XML
文件的版本和存储该文件所用的字符集:
1 <?xml version="1.0" encoding="UTF-8" ?>
根元素 configuration MyBatis
配置文件的根元素是configuration
,
settings子元素
根元素configuration
中有settings
子元素,该元素有很多子元素,本示例只是配置了日志信息,之后可以在控制台看到输出的SQL
语句,其在调试中非常有用。
environments子元素
根元素configuration
中还有environments
子元素,用来配置MyBatis
的环境,即连接的数据库,该子元素用于将SQL
映射应用于多种数据库中。每个数据库对应一个SqlsessionFactory
,可以配置多种环境,但只能为SqlsessionFactory
实例选择一个环境,default
属性表示选择的环境。
environment子元素
environments
元素的environment
子元素用于配置一个环境,
environment
的transactionManager
子元素用来配置MyBatis
当中的事务管理,JDBC
属性表示直接简单使用JDBC
的提交和回滚设置。
environment
的**datasource
子元素用来配置数据源**,MyBatis
并不推荐采用DriverManager
来连接数据库,而是推荐使用薮据源来管理数据库连接,这样能保证最好的性能。
datasource
元素依次有很多property
子元素,这些property
子元素用于配置MyBatis
连接数据库的必要信息,如连接数据库的驱动、URL
、用户名、密码等信息
mapper子元素
根元素configuration
中还有mappers
子元素,它可以支持多个mapper
子元素,每个mapper
子元素用于指定一个持久化配置文件 。
数据源介绍 数据源是一种用来提高数据库连接性能的常规手段 ,数据源会负责维持一个数据库连接池,当程序创建数据源实例时,系统会一次性地创建多个数据库连接,并把这些数据库连接保存在连接池中 。当程序需要进行数据库访问时,无须重新获得数据库连接,而是从连接池中取出一个空闲的数据库连接,当程序使用数据库连接访问数据库结束后无须关闭数据库连接,而是将数据库连接归还给连接池即可。通过这种方式,就可避免频繁地获取数据库连接、关闭数据库连接所导致的性能下降 。
MyBatisTest.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 public class MyBatisTest { public static void main (String[] args) { SqlSession sqlSession = null ; try ( InputStream is = Resources.getResourceAsStream("mybatis-config.xml" );) { SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder ().build(is); sqlSession = sqlSessionFactory.openSession(); User user = new User ("admin" , "男" , 26 ); sqlSession.insert("org.fkit.mapper.UserMapper.save" , user); sqlSession.commit(); } catch (Exception e) { sqlSession.rollback(); e.printStackTrace(); } finally { try { if (sqlSession != null ) sqlSession.close(); } catch (Exception e) { e.printStackTrace(); } } } }
上面持久化操作的代码非常简单。程序先创建一个User
对象,再使用SqlSession
的insert()
方法来保存User
对象即可 ,这是完全对象化的操作方式,可以说非常简单明了。当Java
程序以面向对象的方式来操作持久化对象时,MyBatis
负责将这种操作转换为底层SQL
操作。
log4j.properties 显示执行的SQL语句 执行持久化操作之前,为了查看控制台输出的SQL
语句,需要加入日志框架log4j
的相关jar
包,在CLASSPATH
下增加一个log4.properties
文件:
# 全局的日志配置
log4j.rootLogger=ERROR, stdout
# Mybatis的日志配置:追踪SQL运行结果
log4j.logger.org.fkit.mapper.UserMapper =DEBUG
# 控制台输出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] %m%n
运行效果 运行MyBatisTest
类的main()
方法,运行完成后,可以看到mybatis
数据库中的TB_USER
表中包含了User
实例对应的记录,如下图所示: 控制台输出
1 2 3 DEBUG [main] ==> Preparing: insert into tb_user(name,sex,age) values(?,?,?) DEBUG [main] ==> Parameters: admin(String), 男(String), 26 (Integer) DEBUG [main] <== Updates: 1
使用MyBatis持久化操作步骤 在执行sqlSession.insert("org.fkit.mapper.UserMapper.save", user);
之前,先要获取SqlSession
对象。PO只有在SqlSession
的管理下才可完成数据库访问 。为了使用MyBatis
进行持久化操作,通常需要执行如下操作步骤
开发持久化类PO
和编写持久化操作的Mapper.xml
,在其中定义要执行的SQL
语句
获取SqlSessionFactory
。SqlSessionFactory
是数据库编译后的内存镜像,通常一个应用对应一个SqlSessionFactory
对象。SqlSessionFactory
对象通过加载mybatis-config.xml
配置文件生成.
获取SqlSession
。SqlSession
由SqlSessionFactory
工厂产生,对PO
的操作必须在SqlSession
的管理下才能同步到数据库。
用面向对象的方式操作数据库。
关闭事务,关闭SqlSession
。
MyBatis相较JDBC的优点 MyBatis
相较JDBC有如下两个显著优点
只需要在Mapper.xml
配置文件中编写SQL
语句,在应用程序中就可以采用PO
方式来访问数据库。
在JDBC
访问过程中大量的checked
异常被包装成MyBatis
的Runtime
异常,从而不再要求程序必须处理所有异常。