写在前面:
小弟入坑4年左右,一直浑浑噩噩,对很多知识理解的不是很透彻,知其然,不知其所以然。前段时间突然心血来潮,想着把Java方面的框架都重新学习一边,这是写这个系列的初衷
顺带着学习一下怎么写博客,刚工作的时候写过几篇,前两天打开一看,写得真是惨不忍睹、惨绝人寰,所以就都删除了,希望这个系列能够坚持写下来,不足之处望大家多多指正。
另外,如果哪天突然发现小弟不更新了,大家也不要意外,毕竟咱们这个系列叫从入门到放弃,说不定是我突然想通了,就放弃了
言归正传,接下来让我们一起见证MyBatis放弃之旅的心路历程
参考文档 MyBatis官方文档
什么是MyBatis?
官方文档原文:
MyBatis is a first class persistence framework with support for custom SQL, stored procedures and advanced mappings. MyBatis eliminates almost all of the JDBC code and manual setting of parameters and retrieval of results. MyBatis can use simple XML or Annotations for configuration and map primitives, Map interfaces and Java POJOs (Plain Old Java Objects) to database records.
什么意思呢, 谷歌翻译是这么和我说的
MyBatis是一流的持久性框架,支持自定义SQL,存储过程和高级映射。 MyBatis消除了几乎所有的JDBC代码以及参数的手动设置和结果检索。 MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
简单来说MyBatis想表达的意思就是:小伙子,和数据库交互这个事你就不用管啦,你就把SQL写好给我就行,少加点儿班,有那时间留出来找女朋友多好。
Getting started
添加 maven 依赖
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
<scope>runtime</scope>
</dependency>
</dependencies>
MyBatis 提供了两种配置方式:Xml 文件和 Java 代码
Xml 文件方式代码如下:
public class MyBatisUtil {
private MyBatisUtil() {
}
/**
* @param resourcePath 配置文件路径
* */
public static SqlSessionFactory getSqlSessionFactoryFromXmlFile(String resourcePath) throws IOException {
// Resources 是 MyBatis 提供的工具类,用于读取资源文件
InputStream inputStream = Resources.getResourceAsStream(resourcePath);
return new SqlSessionFactoryBuilder().build(inputStream);
}
...
}
public class Test {
public static void main(String[] args) {
testSelectByXmlConfig();
}
private static void testSelectByXmlConfig() {
String reource = "mybatis/config/mybatis-config.xml";
SqlSessionFactory sqlSessionFactory;
try {
sqlSessionFactory = MyBatisUtil.getSqlSessionFactoryFromXmlFile(reource);
} catch (IOException e) {
e.printStackTrace();
return;
}
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
User user = sqlSession.selectOne("org.gaipianer.mybatis.demo.mapper.UserMapper.selectUser", "1");
System.out.println(user);
}
}
}
User 就是普通的不能再普通的 Java Bean,只有几个属性和set get 方法 这里我就不贴出来了
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.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/gaipianer/mybatis/demo/mapper/UserMapper.xml"/>
</mappers>
</configuration>
接下来我们从mybatis-config.xml文件开始,看看我们都配置了什么玩意儿
根级是 configuration节点,configuration 节点在一个配置文件中只能有一个
然后是 environments 节点,从命名上来看,environments节点里可以配置多个environment,environments有一个default属性,用来指定默认的 environment是哪个
接下来 environment 节点,他有一个 id 属性,是他的唯一标识,毕竟 environment 节点可以有多个,总不能搞混了 分不清谁是谁,environments 节点的 default 属性 取的值就是这个 id
transactionManager 配置的是负责事务管理的类,MyBatis提供了两个实现类 ManagedTransaction 和 JdbcTransaction,这里配置的是 JDBC 实现类
dataSource 节点配置的是数据源,告诉MyBatis连接用哪种驱动,数据库地址是多少,用户名以及密码是啥,MyBatis 也提供了两种数据源实现类 PooledDataSource 和 UnpooledDataSource
最后就是 mappers 节点了,这里配置了你都有哪些 Mapper 文件
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="org.gaipianer.mybatis.demo.mapper.UserMapper">
<select id="selectUser" resultType="org.gaipianer.mybatis.demo.domain.User">
select * from user where id = #{id}
</select>
</mapper>
这个mapper文件里最主要的就是两部分 namespace="org.gaipianer.mybatis.demo.mapper.UserMapper" 和 select 节点
命名空间 namespace 是当前 Mapper 文件的唯一标识
select 节点配置了我们要执行的 SQL 语句,以及我们想要把查询回来的数据映射到哪个Java 类
运行程序,打印结果如下
User{id='1', username='kobe', name='科比', age=42, wage=5.11191110123E8}
简直完美!!!我们一行JDBC的代码都没有写,MyBatis就已经执行了我们写好的SQL语句,数据就查询并且输出到了控制台,而且还帮我们映射到了配置好的 Java Bean 对象,有没有觉得很神奇???
执行查询操作的代码就是这行:
User user = sqlSession.selectOne("org.gaipianer.mybatis.demo.mapper.UserMapper.selectUser", "1");
这个过程可以想象为,通过 org.gaipianer.mybatis.demo.mapper.UserMapper 命名空间找到了我们定义的 UserMapper.xml文件,通过selectUser 找到了我们定义的SQL语句 然后执行SQL, 把查询结果映射成一个 User 对象。
有的同学可能会有疑问,你上边代码里的 SqlSessionFactory 和 SqlSession 都是干嘛的?看起来很高级的样子
先看 SqlSessionFactory 顾名思义 他就是用来构建 SqlSession 对象的,接口定义如下(我这没下来源码包,大家将就着看吧):
public interface SqlSessionFactory {
SqlSession openSession();
SqlSession openSession(boolean var1);
SqlSession openSession(Connection var1);
SqlSession openSession(TransactionIsolationLevel var1);
SqlSession openSession(ExecutorType var1);
SqlSession openSession(ExecutorType var1, boolean var2);
SqlSession openSession(ExecutorType var1, TransactionIsolationLevel var2);
SqlSession openSession(ExecutorType var1, Connection var2);
Configuration getConfiguration();
}
可以看到 接口中定义了好多 openSession 方法,都是用来获取 SqlSession的
SqlSession 是我们用来与数据库进行交互的类, 与数据库交互的 CRUD 方法都在 SqlSession 里实现接口定义如下:
public interface SqlSession extends Closeable {
<T> T selectOne(String var1);
<T> T selectOne(String var1, Object var2);
<E> List<E> selectList(String var1);
<E> List<E> selectList(String var1, Object var2);
<E> List<E> selectList(String var1, Object var2, RowBounds var3);
<K, V> Map<K, V> selectMap(String var1, String var2);
<K, V> Map<K, V> selectMap(String var1, Object var2, String var3);
<K, V> Map<K, V> selectMap(String var1, Object var2, String var3, RowBounds var4);
<T> Cursor<T> selectCursor(String var1);
<T> Cursor<T> selectCursor(String var1, Object var2);
<T> Cursor<T> selectCursor(String var1, Object var2, RowBounds var3);
void select(String var1, Object var2, ResultHandler var3);
void select(String var1, ResultHandler var2);
void select(String var1, Object var2, RowBounds var3, ResultHandler var4);
int insert(String var1);
int insert(String var1, Object var2);
int update(String var1);
int update(String var1, Object var2);
int delete(String var1);
int delete(String var1, Object var2);
void commit();
void commit(boolean var1);
void rollback();
void rollback(boolean var1);
List<BatchResult> flushStatements();
void close();
void clearCache();
Configuration getConfiguration();
<T> T getMapper(Class<T> var1);
Connection getConnection();
}
SqlSessionFactory 和 SqlSession 的具体实现我们以后再讲,毕竟来日方长,能拖一天是一天。
通过 Java 代码配置方式如下:
public class MyBatisUtil {
private MyBatisUtil() {
}
...
public static SqlSessionFactory getSqlSessionFactoryFromJavaCode(String propertiesPath) throws IOException {
Properties properties = Resources.getResourceAsProperties(propertiesPath);
DataSourceFactory dataSourceFactory = new PooledDataSourceFactory();
dataSourceFactory.setProperties(properties);
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("develop", transactionFactory, dataSourceFactory.getDataSource());
Configuration configuration = new Configuration(environment);
configuration.addMapper(UserMapper.class);
return new SqlSessionFactoryBuilder().build(configuration);
}
}
public interface UserMapper {
@Select("SELECT * FROM user WHERE id = #{id}")
User selectOne(String id);
}
public class Test {
public static void main(String[] args) {
testSelectByJavaCode();
}
private static void testSelectByJavaCode() {
String propertiesPath = "datasource/database.properties";
SqlSessionFactory sqlSessionFactory;
try {
sqlSessionFactory = MyBatisUtil.getSqlSessionFactoryFromJavaCode(propertiesPath);
} catch (IOException e) {
e.printStackTrace();
return;
}
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.selectOne("1");
System.out.println(user);
}
}
}
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
username=root
password=123456
总的来讲Java代码也是在构建 Configuration Environment 这些类,唯一不太一样的地方就是 Java 配置没有写 UserMapper.xml文件,而是用的 UserMapper 接口
SQL 语句是通过 @Select 注解方式配置的,这种方式看起来更简洁,更优雅,而且也避免了命名空间书写错误所带来的问题
整个工程结构如下图
以上就是 MyBatis 的最基础的用法,今天的【从入门的放弃系列】就先到这里,后续咱们再接着学习怎么放弃。