[mybatis]一睹MyBatis的尊容
Posted 爱折腾的稻草
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[mybatis]一睹MyBatis的尊容相关的知识,希望对你有一定的参考价值。
No.1 mybatis简介
MyBatis是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
No.2 初体验
2.1、构建Maven项目
2.2、添加依赖
我们使用mybatis来操作mysql数据库数据,因此需要引入mybatis和mysql驱动相关的依赖包,具体代码如下:
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.18</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
2.3、数据库准备
新建一个数据库名为mybatis,在该库中创建一张系统用户表(sys_user),脚本如下:
-- ----------------------------
-- Table structure for sys_user
-- ----------------------------
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
`id` tinyint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`loginName` varchar(50) DEFAULT NULL COMMENT '登录账户',
`loginPwd` varchar(50) DEFAULT NULL COMMENT '登录密码',
`createTime` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
添加测试数据,具体代码如下:
INSERT INTO `mybatis`.`sys_user` (`id`, `loginName`, `loginPwd`, `createTime`) VALUES ('2', '肖继龙', '1', '2018-07-18 14:21:39');
2.4、编写java实体类
定义sys_user表所对应的实体类UserEntity,具体代码如下:
/**
* <p>Title: UserEntity</p>
*
* <p>Description: 用户实体类,对应数据库表sys_user</p>
*
* @author jilong.xiao
* @date 2018年7月18日
*/
public class UserEntity {
private long id ;
private String loginName;
private String loginPwd;
private Date createTime;
getter/setter方法略...
toString方法略...
}
2.5、定义SQL映射文件
mybatis是通过在一个 XML 映射文件,来定义要执行的SQL语句的,在本示例程序中,我们需要定一个sys_user表所对应的一个SQL操作映射文件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,namespace的值习惯上设置成包名+sql映射文件名,这样就能够保证namespace的值是唯一的
例如namespace="io.xiaojl.mapper.UserMapper"就是io.xiaojl.mapper(包名)+UserMapper(UserMapper.xml文件去除后缀) -->
<mapper namespace="io.xiaojl.mapper.UserMapper">
<!-- 在select标签中编写查询的SQL语句, 设置select标签的id属性为getUser,id属性值必须是唯一的,不能够重复 使用parameterType属性指明查询时使用的参数类型,resultType属性指明查询返回的结果集类型
resultType="io.xiaojl.entity.UserEntity"就表示将查询结果封装成一个User类的对象返回 User类就是users表所对应的实体类 -->
<!-- 根据id查询得到一个user对象 -->
<select id="selectById" parameterType="long" resultType="io.xiaojl.entity.UserEntity">
select * from sys_user where id=#{id}
</select>
</mapper>
2.6、构建SqlSessionFactory
在mybaits应用中都是以一个SqlSessionFactory实例为中心,通过SqlSessionFactory可以SqlSession实例,SqlSession 完全包含了面向数据库执行 SQL 命令所需的所有方法。
构建SqlSessionFactory主要有以下两种方式:
Mybatis配置文件的形式
从XML文件中构建SqlSessionFactory的实例非常简单,可以在classpath路径下添加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/mybatis" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
<mappers>
<!-- 注册Mapper文件 -->
<mapper resource="io/xiaojl/mapper/UserMapper.xml" />
</mappers>
</configuration>
XML配置文件(configuration XML)中包含了对 MyBatis 系统的核心设置,包含获取数据库连接实例的数据源(DataSource)和决定事务作用域和控制方式的事务管理器(TransactionManager)。本文中只是一个简单的示例程序。
然后编写构建SqlSessionFactory的方法,具体代码如下:
/**
* <p>Title: buildSqlSessionFactory</p>
*
* <p>Description: 从 XML 中构建 SqlSessionFactory</p>
*
* @return
*/
public static SqlSessionFactory buildSqlSessionFactory(){
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
return sqlSessionFactory;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
javaCode的形式
为了减少项目中出现xml配置文件,我们可以采用java编码的方式来构建SqlSessionFactory,我们创建一个configuration类,具体代码如下:
/**
* <p>Title: buildSqlSessionFactoryWithConfiguration</p>
*
* <p>Description: 从 configuration 中构建 SqlSessionFactory</p>
*
* @return
*/
public static SqlSessionFactory buildSqlSessionFactoryWithConfiguration(){
DataSourceFactory sdf = new PooledDataSourceFactory();
Properties props = new Properties();
props.put("driver", "com.mysql.jdbc.Driver");
props.put("url", "jdbc:mysql://localhost:3306/mybatis");
props.put("username", "root");
props.put("password", "root");
sdf.setProperties(props);
DataSource dataSource = sdf.getDataSource();
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("development", transactionFactory, dataSource);
Configuration configuration = new Configuration(environment);
//添加mapper接口类,它会自动关联并加载UserMapper.xml文件
configuration.addMapper(UserMapper.class);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
return sqlSessionFactory;
}
2.7、编写一个单元测试
经过上面一步步的搭建,基本工作已经完成,我们先编写一个单元测试,具体代码如下:
/**
* <p>Title: UserMapperTest</p>
*
* <p>Description: 单元测试类</p>
*
* @author jilong.xiao
* @date 2018年7月18日
*/
public class UserMapperTest {
@Test
public void test_selectById(){
//使用javacode的方法来构建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = MybaitsConfig.buildSqlSessionFactoryWithConfiguration();
//创建能执行映射文件中sql的sqlSession
SqlSession session = sqlSessionFactory.openSession();
//映射sql的标识字符串statement = mapper.xml文件中的namespace + select标签的id属性值
String statement = "io.xiaojl.mapper.UserMapper.selectById";
//执行查询返回一个唯一user对象的sql
UserEntity user = session.selectOne(statement, 2L);
System.out.println(user);
}
}
2.8、运行
运行上述单元测试,根据Id查询用户信息,执行结果如下:
UserEntity [id=2, loginName=肖继龙, loginPwd=1, createTime=Wed Jul 18 14:21:39 CST 2018]
看到打印出了用户数据,那恭喜您,这表示mybatis正常工作了。
No.3 总结
在上面的示例程序中,我们只是简单的构建起应用,但这并不是最佳实践。
3.1、命名空间
命名空间(Namespaces)在之前版本的 MyBatis 中是可选的,这样容易引起混淆因此毫无益处。现在命名空间则是必须的,且意于简单地用更长的完全限定名来隔离语句。
出于长远考虑,使用命名空间,并将它置于合适的 Java 包命名空间之下,你将拥有一份更加整洁的代码并提高了 MyBatis 的可用性。
3.2、命名解析
为了减少输入量,MyBatis 对所有的命名配置元素(包括语句,结果映射,缓存等)使用了如下的命名解析规则:
完全限定名(比如“io.xiaojl.UserMapper.selectById”)将被直接查找并且找到即用。
短名称(比如“selectById”)如果全局唯一也可以作为一个单独的引用。如果不唯一,有两个或两个以上的相同名称(比如“io.xiaojl.UserMapper.selectById”和“io.xiaojl.RoleMapper.selectById”),那么使用时就会收到错误报告说短名称是不唯一的,这种情况下就必须使用完全限定名。
3.3、作用域和生命周期
依赖注入框架(比如说Spring的IOC容器)可以创建线程安全的、基于事务的 SqlSession 和映射器(mapper)并将它们直接注入到你的 bean 中,因此可以直接忽略它们的生命周期。
SqlSessionFactoryBuilder
这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。
你可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但是最好还是不要让其一直存在以保证所有的 XML 解析资源开放给更重要的事情。SqlSessionFactory
SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由对它进行清除或重建。
使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种“坏代码”。
因此 SqlSessionFactory 的最佳作用域是应用作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。SqlSession
每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。
绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。也绝不能将 SqlSession 实例的引用放在任何类型的管理作用域中,比如 Servlet 架构中的 HttpSession。
如果你现在正在使用一种 Web 框架,要考虑 SqlSession 放在一个和 HTTP 请求对象相似的作用域中。换句话说,每次收到的 HTTP 请求,就可以打开一个 SqlSession,返回一个响应,就关闭它。
这个关闭操作是很重要的,你应该把这个关闭操作放到 finally 块中以确保每次都能执行关闭。下面的示例就是一个确保 SqlSession 关闭的标准模式:
SqlSession session = sqlSessionFactory.openSession();
try {
// do work
} finally {
session.close();
}
映射器实例(Mapper Instances)
映射器是一个你创建来绑定你映射的语句的接口。映射器接口的实例是从 SqlSession 中获得的。
因此从技术层面讲,任何映射器实例的最大作用域是和请求它们的 SqlSession 相同的。尽管如此,映射器实例的最佳作用域是方法作用域。也就是说,映射器实例应该在调用它们的方法中被请求,用过之后即可废弃。
并不需要显式地关闭映射器实例,尽管在整个请求作用域(request scope)保持映射器实例也不会有什么问题,但是很快你会发现,像 SqlSession 一样,在这个作用域上管理太多的资源的话会难于控制。
所以要保持简单,最好把映射器放在方法作用域(method scope)内。下面的示例就展示了这个实践:
SqlSession session = sqlSessionFactory.openSession();
try {
UserMapper mapper = session.getMapper(UserMapper.class);
// do work
} finally {
session.close();
}
小结
本文旨在带领大家快速构建一个使用Mybatis做持久层框架的应用,体验Mybatis给我们开发所带来的改变。
·end·
—如果喜欢,快分享给你的朋友们吧—
我们一起愉快的玩耍吧
以上是关于[mybatis]一睹MyBatis的尊容的主要内容,如果未能解决你的问题,请参考以下文章
SSM-MyBatis-05:Mybatis中别名,sql片段和模糊查询加getMapper