准备数据库 mysql中执行下面sql:
代码语言:javascript复制/*创建数据库javacode2018*/
DROP DATABASE IF EXISTS `javacode2018`;
CREATE DATABASE `javacode2018`;
USE `javacode2018`;
/*创建表结构*/
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE t_user (
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键,用户id,自动增长',
`name` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '姓名',
`age` SMALLINT NOT NULL DEFAULT 1 COMMENT '年龄',
`salary` DECIMAL(12,2) NOT NULL DEFAULT 0 COMMENT '薪水',
`sex` TINYINT NOT NULL DEFAULT 0 COMMENT '性别,0:未知,1:男,2:女'
) COMMENT '用户表';
SELECT * FROM t_user;
上面我们创建了一个数据库:javacode2018,一个用户表t_user。
我们的需求
使用mybatis来实现对t_user表增删改查。
使用idea创建项目
我们在上一篇文章mybatis-series项目中创建另外一个模块chat02,过程如下:
选中mybatis-series,如下图:
点击右键->New->Module,如下图:
选中上图中的Maven,点击Next,如下图:
出现下面窗口:
上图中输入ArtifactId为chat02,点击Next,如下图:
点击上图中的Finish完成chat02模块的创建,项目结构如下图:
pom.xml中引入mybatis依赖
代码语言:javascript复制<dependencies>
<!-- mybatis依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
<!-- mysql 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- lombok支持 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- 单元测试junit支持 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<!-- 引入logback用来输出日志 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
</dependencies>
上面我们引入了依赖mybatis、mysql驱动、lombok支持、junit、logback支持,其实运行mybatis只需要引入下面这一个构件就行了:
代码语言:javascript复制<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
注意:上面pom引入的构建中没有写版本号,是因为构件的版本号在父pom.xml中已经声明了,所以chat03/pom.xml中就不需要再去写了。
配置mybatis全局配置文件
使用mybatis操作数据库,那么当然需要配置数据库相关信息,这个需要在mybatis全局配置文件中进行配置。
mybatis需提供一个全局配置的xml文件,可以在这个配置文件中对mybatis进行配置,如事务的支持,数据源的配置等等,这个属于配置文件,我们一般放在main/resource中。
在chat03/src/main/resource中创建mybatis-config.xml文件,内容如下:
代码语言:javascript复制<?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="chat03">
<!--
environment用来对某个环境进行配置
id:环境标识,唯一
-->
<environment id="chat03">
<!-- 事务管理器工厂配置 -->
<transactionManager type="org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory"/>
<!-- 数据源工厂配置,使用工厂来创建数据源 -->
<dataSource type="org.apache.ibatis.datasource.pooled.PooledDataSourceFactory">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/javacode2018?characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="root123"/>
</dataSource>
</environment>
</environments>
</configuration>
我们做一下解释。
configuration元素 这个是mybatis全局配置文件的根元素,每个配置文件只有一个
environments元素 用来配置mybatis的环境信息,什么是环境?比如开发环境、测试环境、线上环境,这3个环境中的数据库可能是不一样的,可能还有更多的环境。
environments元素中用来配置多个环境的,具体的一个环境使用environment元素进行配置,environment元素有个id用来标识某个具体的环境。
配置了这么多环境,那么mybatis具体会使用哪个呢?
environments元素有个default属性,用来指定默认使用哪个环境,如上面默认使用的是chat03。
environment元素 用来配置具体的环境信息,这个元素下面有两个子元素:transactionManager和dataSource。
- transactionManager元素 用来配置事务工厂的,有个type属性,type的值必须是org.apache.ibatis.transaction.TransactionFactory接口的实现类,TransactionFactory看名字就知道是一个工厂,用来创建事务管理器org.apache.ibatis.transaction.Transaction对象的,TransactionFactory接口默认有2个实现:
org.apache.ibatis.transaction.managed.ManagedTransactionFactory
org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory
一般情况下我们使用org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory这个,mybatis和其他框架集成,比如和spring集成,事务交由spring去控制,spring中有TransactionFactory接口的一个实现org.mybatis.spring.transaction.SpringManagedTransactionFactory,有兴趣的朋友可以去研究一下,这个到时候讲到spring的使用会详细说。
- dataSource元素
这个用来配置数据源的,type属性的值必须为接口org.apache.ibatis.datasource.DataSourceFactory的实现类,DataSourceFactory也是一个工厂,用来创建数据源javax.sql.DataSource对象的,mybatis中这个接口默认有3个实现类:
代码语言:javascript复制org.apache.ibatis.datasource.jndi.JndiDataSourceFactory
org.apache.ibatis.datasource.pooled.PooledDataSourceFactory
org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory
我们使用org.apache.ibatis.datasource.pooled.PooledDataSourceFactory,这个用来创建一个数据库连接池类型的数据源,可以实现数据库连接共用,减少连接重复创建销毁的时间。
配置数据源需要指定数据库连接的属性信息,比如:驱动、连接db的url、用户名、密码,这个在dataSource元素下面的property中配置,property元素的格式:
代码语言:javascript复制<property name="属性名称" value="值"/>
创建Mapper xml文件
我们需要对t_user表进行操作,需要写sql,sql写在什么地方呢?
在mybatis中一般我们将一个表的所有sql操作写在一个mapper xml中,一般命名为XXXMapper.xml格式。
创建文件chat02/src/main/resource/mapper/UserMapper.xml,内容如下:
代码语言:javascript复制<?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="com.javacode2018.chat02.UserMapper">
</mapper>
mapper xml根元素为mapper,这个元素有个namespace属性,系统中会有很多表,每个表对应一个Mapper xml,为了防止mapper文件重复,我们需要给每个mapper xml文件需要指定一个namespace,通过这个可以区分每个mapper xml文件,上面我们指定为com.javacode2018.chat02.UserMapper。
一会对t_user表的所有操作相关的sql,我们都会写在上面这个xml中。
mybatis全局配置文件中引入Mapper xml文件 UserMapper.xml我们写好了,如何让mybatis知道这个文件呢,此时我们需要在mybatis-config.xml全局配置文件中引入UserMapper.xml,在mybatis-config.xml加入下面配置:
代码语言:javascript复制<mappers>
<mapper resource="mapper/UserMapper.xml" />
</mappers>
mappers元素下面有多个mapper元素,通过mapper元素的resource属性可以引入Mapper xml文件,resource是相对于classes的路径。
上面说的都是一些配置文件,配置文件都ok了,下面我们就需要将mybatis跑起来了,此时需要使用到mybatis中的一些java对象了。
构建SqlSessionFactory对象
代码语言:javascript复制//指定mybatis全局配置文件
String resource = "mybatis-config.xml";
//读取全局配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
//构建SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSessionFactory是一个接口,是一个重量级的对象,SqlSessionFactoryBuilder通过读取全局配置文件来创建一个SqlSessionFactory,创建这个对象是比较耗时的,主要耗时在对mybatis全局配置文件的解析上面,全局配置文件中包含很多内容,SqlSessionFactoryBuilder通过解析这些内容,创建了一个复杂的SqlSessionFactory对象,这个对象的生命周期一般和应用的生命周期是一样的,随着应用的启动而创建,随着应用的停止而结束,所以一般是一个全局对象,一般情况下一个db对应一个SqlSessionFactory对象。
构建SqlSession对象 SqlSession相当于jdbc中的Connection对象,相当于数据库的一个连接,可以用SqlSession来对db进行操作:如执行sql、提交事务、关闭连接等等,需要通过SqlSessionFactory来创建SqlSession对象,SqlSessionFactory中常用的有2个方法来创建SqlSession对象,如下:
代码语言:javascript复制//创建一个SqlSession,默认不会自动提交事务
SqlSession openSession();
//创建一个SqlSession,autoCommit:指定是否自动提交事务
SqlSession openSession(boolean autoCommit);
SqlSession接口中很多方法,直接用来操作db,方法清单如下,大家眼熟一下:
代码语言:javascript复制<T> T selectOne(String statement);
<T> T selectOne(String statement, Object parameter);
<E> List<E> selectList(String statement);
<E> List<E> selectList(String statement, Object parameter);
<E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds);
<K, V> Map<K, V> selectMap(String statement, String mapKey);
<K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey);
<K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds);
<T> Cursor<T> selectCursor(String statement);
<T> Cursor<T> selectCursor(String statement, Object parameter);
<T> Cursor<T> selectCursor(String statement, Object parameter, RowBounds rowBounds);
void select(String statement, Object parameter, ResultHandler handler);
void select(String statement, ResultHandler handler);
void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler);
int insert(String statement);
int insert(String statement, Object parameter);
int update(String statement);
int update(String statement, Object parameter);
int delete(String statement);
int delete(String statement, Object parameter);
void commit();
void commit(boolean force);
void rollback();
void rollback(boolean force);
List<BatchResult> flushStatements();
void close();
void clearCache();
Configuration getConfiguration();
<T> T getMapper(Class<T> type);
Connection getConnection();
上面以select开头的可以对db进行查询操作,insert相关的可以对db进行插入操作,update相关的可以对db进行更新操作。
引入lombok支持(非必须) 声明一下:lombok不是mybatis必须的,为了简化代码而使用的,以后我们会经常使用。 Lombok能以简单的注解形式来简化java代码,提高开发人员的开发效率。例如开发中经常需要写的javabean,都需要花时间去添加相应的getter/setter,也许还要去写构造器、equals等方法,而且需要维护,当属性多时会出现大量的getter/setter方法,这些显得很冗长也没有太多技术含量,一旦修改属性,就容易出现忘记修改对应方法的失误。
Lombok能通过注解的方式,在编译时自动为属性生成构造器、getter/setter、equals、hashcode、toString方法。出现的神奇就是在源码中没有getter和setter方法,但是在编译生成的字节码文件中有getter和setter方法。这样就省去了手动重建这些代码的麻烦,使代码看起来更简洁些。
lombok的使用步骤
- 先在idea中安装lombok插件 打开idea,点击File->Settings->plugins,然后搜索Lombok Plugin,点击安装就可以了。
- maven中引入lombok支持
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
<scope>provided</scope>
</dependency>
- 代码中使用lombok相关功能
引入logback(非必须)
声明一下:日志框架mybatis中也不是必须的,不用配置也可以正常运行。
为了方便查看mybatis运行过程中产生的日志,比如:执行的sql、sql的参数、sql的执行结果等等调试信息,我们需要引入日志框架的支持,logback是一个很好的日志框架,此处我们就使用这个
mybatis中集成logback步骤
- maven中引入logback支持
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
- src/main/resources中创建logback.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<logger name="com.javacode2018" level="debug" additivity="false">
<appender-ref ref="STDOUT" />
</logger>
</configuration>
logback.xml具体的写法不是本文讨论的范围,有兴趣的朋友可以去研究一下logback具体的用法。
上面xml中配置了com.javacode2018包中所有的类,使用logback输出日志的时候,debug级别及以上级别的日志会输出到控制台,方便我们查看。
写一个测试用例
在chat02/src/test下创建一个类:
代码语言:javascript复制com.javacode2018.chat02.UserTest
内容如下:
代码语言:javascript复制package com.javacode2018.chat02;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
@Slf4j
public class UserTest {
private SqlSessionFactory sqlSessionFactory;
@Before
public void before() throws IOException {
//指定mybatis全局配置文件
String resource = "mybatis-config.xml";
//读取全局配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
//构建SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
this.sqlSessionFactory = sqlSessionFactory;
}
@Test
public void sqlSession() {
SqlSession sqlSession = this.sqlSessionFactory.openSession();
log.info("{}", sqlSession);
}
}
上面代码中有个@Slf4j注解,这个是lombok提供的,可以在这个类中生成下面代码:
代码语言:javascript复制private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(UserTest.class);
运行一下上面的用例:sqlSession方法,输出如下:
代码语言:javascript复制45:51.289 [main] INFO com.javacode2018.chat02.UserTest - org.apache.ibatis.session.defaults.DefaultSqlSession@1f021e6c