mybatis是一款支持自定义SQL、存储过程和高级映射的持久化框架。通过封装几乎消除了使用者编写JDBC、手动设置参数和检索结果的代码,其底层实现通过XML配置文件、Java注解的方式来配置,将Mapper接口和POJO类映射到数据库,而且与springboot框架集成特别方便
介绍使用mybatis的基本配置、一些基本用法以及介绍事务在mybatis中是怎么实现的,最后说一下如何集成到springboot中。
CREATE TABLE `user` ( `id` bigint(11) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(20) DEFAULT NULL, `password` varchar(255) DEFAULT NULL, `status` tinyint(1) DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 复制代码
mybatis支持XML配置、Java代码配置两种方式
// 加载外部的properties配置文件 Properties properties = new Properties(); properties.load(Resources.getResourceAsStream("db.properties")); String connectUrl = properties.getProperty("db.connectionURL"); String driverClass = properties.getProperty("db.driverClass"); String userName = properties.getProperty("db.userName"); String password = properties.getProperty("db.password"); // 定义数据源,这里使用HikariCP数据源 HikariDataSource dataSource = new HikariDataSource(); dataSource.setDriverClassName(driverClass); dataSource.setJdbcUrl(connectUrl); dataSource.setUsername(userName); dataSource.setPassword(password); // 事务相关配置 TransactionFactory transactionFactory = new JdbcTransactionFactory(); // 配置Environment、Configuration。 // 在mybatis中,Configuration作为一个配置对象,包含了数据源对象、Environment对象、TransactionFactory对象等等, // 使用组合的方式,封装了以上提到的各种对象,提供统一接口来使用这些对象。 Environment environment = new Environment("development", transactionFactory, dataSource); Configuration configuration = new Configuration(environment); 复制代码
@Data public class User { private Long id; private String name; private String password; private Boolean status; } 复制代码
@Mapper public interface UserMapper { @Insert("<script>insert into user(name, password, status) values(#{name}, #{password}, #{status})</script>") @SelectKey(statement = "SELECT LAST_INSERT_ID()", keyProperty = "id", keyColumn = "id", before = false, resultType = Long.class) int insert(User user); @Results(id = "user", value = { @Result(column = "name", property = "name"), @Result(column = "password", property = "password"), @Result(column = "status", property = "status"), }) @Select("select * from user") List<User> selectAll(); @ResultMap("user") @Select("select * from user where id = #{id}") User selectByPrimaryKey(Long id); @Delete("delete from user where id = #{id}") int deleteByPrimaryKey(Long id); } 复制代码
// 通过之前的配置,得到的Configuration配置类的实例,通过它来添加Mapper接口 configuration.addMapper(UserMapper.class); // 在使用mapper接口来进行数据库操作前,需要构造一个SqlSession实例。mybatis通过这个接口与开发者交互来实现数据库操作 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration); SqlSession sqlSession = sqlSessionFactory.openSession(); // 通过SqlSession实例,获取为我们执行数据库操作的mapper接口 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); // 执行插入记录 User user = new User(); user.setName("测试"); user.setPassword("测试"); user.setStatus(Boolean.FALSE); userMapper.insert(user); // 由于在mybatis事务中,默认为「非自动提交」的,此处需要手动提交,才能保证数据真正插入到数据库中,否则在代码运行结束后将被回滚 sqlSession.commit(); // 查询所有记录 List<User> users = userMapper.selectAll(); // 根据主键ID进行查询 User u = userMapper.selectByPrimaryKey(user.getId()); // 删除记录 userMapper.deleteByPrimaryKey(user.getId()); 复制代码
可以看出,mybatis内部通过Environment这个类组合了DataSource、TransactionFactory来封装数据库的连接、事务这两个功能。之后通过Enviroment构造出配置类对象Configuration,封装了管理配置、获取配置的接口。之后由Configuration构造出的SqlSessionFactory,由SqlSessionFactory生产出的SqlSession对象跟开发者打交道,从而实现数据库操作。我们可以做出假设:
基于以上两个假设,我们来分析一下mybatis中是否真的如此?
解析、绑定SQL的过程 configuration.addMapper(UserMapper.class)
执行SQL的过程
我们都知道在Java中执行SQL需要经过:预编译SQL、绑定SQL参数、处理结果集这三步。在mybatis中同样体现了这一流程,而且将每一个流程委托给不同的类进行处理,之后通过一些门面类封装暴露了比较简洁的接口连接起来整个流程。这样每个子流程之间无需理会其内部如何工作,只需要关心接口如何使用。
在当前的开发来说,我们不太可能单独使用mybatis。一般都会在基于spring框架开发的项目中集成mybatis,使这一类项目可以方便的操作数据库来达成业务开发要求。
由springboot自动化配置机制来加载该配置类