如需转载,请根据 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 许可,附上本文作者及链接。
本文作者: 执笔成念
作者昵称: zbcn
本文链接: https://1363653611.github.io/zbcn.github.io/2019/10/09/myBatis_04Java_api/
MyBatis java API
SqlSession
SqlSession 由 SqlSessionFactory 创建. 而SqlSessionFactory 由 SqlSessionFactoryBuilder 创建.
SqlSessionFactoryBuilder
SqlSessionFactoryBuilder 有五个 build() 方法,每一种都允许你从不同的资源中创建一个 SqlSessionFactory 实例
1 | SqlSessionFactory build(InputStream inputStream)//最常用的方法 |
2 | SqlSessionFactory build(InputStream inputStream, String environment) |
3 | SqlSessionFactory build(InputStream inputStream, Properties properties) |
4 | SqlSessionFactory build(InputStream inputStream, String env, Properties props) |
5 | SqlSessionFactory build(Configuration config) |
从 mybatis-config.xml 文件创建 SqlSessionFactory 的示例:
1 | String resource = "org/mybatis/builder/mybatis-config.xml"; |
2 | InputStream inputStream = Resources.getResourceAsStream(resource); |
3 | SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); |
4 | SqlSessionFactory factory = builder.build(inputStream); |
5 | ``` |
6 | 如何手动配置 configuration 实例,然后将它传递给 build() 方法来创建 SqlSessionFactory |
7 | ```java |
8 | DataSource dataSource = BaseDataTest.createBlogDataSource(); |
9 | TransactionFactory transactionFactory = new JdbcTransactionFactory(); |
10 | |
11 | Environment environment = new Environment("development", transactionFactory, dataSource); |
12 | |
13 | Configuration configuration = new Configuration(environment); |
14 | configuration.setLazyLoadingEnabled(true); |
15 | configuration.setEnhancementEnabled(true); |
16 | configuration.getTypeAliasRegistry().registerAlias(Blog.class); |
17 | configuration.getTypeAliasRegistry().registerAlias(Post.class); |
18 | configuration.getTypeAliasRegistry().registerAlias(Author.class); |
19 | configuration.addMapper(BoundBlogMapper.class); |
20 | configuration.addMapper(BoundAuthorMapper.class); |
21 | |
22 | SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); |
23 | SqlSessionFactory factory = builder.build(configuration); |
SqlSessionFactory
SqlSession 有6个方法创建SqlSession 实例,通常要考虑如下几点:
- 事务处理:我需要在 session 使用事务或者使用自动提交功能(auto-commit)吗?(通常意味着很多数据库和/或 JDBC 驱动没有事务)
- 连接: 我需要依赖 MyBatis 获得来自数据源的配置吗?还是使用自己提供的配置?
- 执行语句:我需要 MyBatis 复用预处理语句和/或批量更新语句(包括插入和删除)吗?
基于以上需求,有下列已重载的多个 openSession() 方法供使用:
1 | SqlSession openSession() |
2 | SqlSession openSession(boolean autoCommit) |
3 | SqlSession openSession(Connection connection) |
4 | SqlSession openSession(TransactionIsolationLevel level) |
5 | SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level) |
6 | SqlSession openSession(ExecutorType execType) |
7 | SqlSession openSession(ExecutorType execType, boolean autoCommit) |
8 | SqlSession openSession(ExecutorType execType, Connection connection) |
9 | Configuration getConfiguration(); |
默认的 openSession()方法没有参数,它会创建有如下特性的 SqlSession:
- 会开启一个事务(也就是不自动提交)。
- 将从由当前环境配置的 DataSource 实例中获取 Connection 对象。
- 事务隔离级别将会使用驱动或数据源的默认设置。
- 预处理语句不会被复用,也不会批量处理更新。
SqlSession
执行语句方法(使用 SqlSesion中方法)
- 普通方法:
1
<T> T selectOne(String statement, Object parameter)
2
<E> List<E> selectList(String statement, Object parameter)
3
<T> Cursor<T> selectCursor(String statement, Object parameter)
4
<K,V> Map<K,V> selectMap(String statement, Object parameter, String mapKey)
5
int insert(String statement, Object parameter)
6
int update(String statement, Object parameter)
7
int delete(String statement, Object parameter)
- 带分页:
1
<E> List<E> selectList (String statement, Object parameter, RowBounds rowBounds)
2
<T> Cursor<T> selectCursor(String statement, Object parameter, RowBounds rowBounds)
3
<K,V> Map<K,V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowbounds)
4
void select (String statement, Object parameter, ResultHandler<T> handler)
5
void select (String statement, Object parameter, RowBounds rowBounds, ResultHandler<T> handler)
6
//RowBounds 类有一个构造方法来接收 offset 和 limit,另外,它们是不可二次赋值的
7
int offset = 100;
8
int limit = 25;
9
RowBounds rowBounds = new RowBounds(offset, limit);
批量立即更新方法
事物控制
本地缓存
使用映射器(Mapper)
- 映射器接口不需要去实现任何接口或继承自任何类。只要方法可以被唯一标识对应的映射语句就可以了。
- 映射器接口可以继承自其他接口。当使用 XML 来构建映射器接口时要保证语句被包含在合适的命名空间中。而且,唯一的限制就是你不能在两个继承关系的接口中拥有相同的方法签名(潜在的危险做法不可取)。
映射器注解
SQL语句构建器类
MyBatis 3提供了方便的工具类来帮助解决该问题。使用SQL类,简单地创建一个实例来调用方法生成SQL语句
1 | private String selectPersonSql() { |
2 | return new SQL() {{ |
3 | SELECT("P.ID, P.USERNAME, P.PASSWORD, P.FULL_NAME"); |
4 | SELECT("P.LAST_NAME, P.CREATED_ON, P.UPDATED_ON"); |
5 | FROM("PERSON P"); |
6 | FROM("ACCOUNT A"); |
7 | INNER_JOIN("DEPARTMENT D on D.ID = P.DEPARTMENT_ID"); |
8 | INNER_JOIN("COMPANY C on D.COMPANY_ID = C.ID"); |
9 | WHERE("P.ID = A.ID"); |
10 | WHERE("P.FIRST_NAME like ?"); |
11 | OR(); |
12 | WHERE("P.LAST_NAME like ?"); |
13 | GROUP_BY("P.ID"); |
14 | HAVING("P.LAST_NAME like ?"); |
15 | OR(); |
16 | HAVING("P.FIRST_NAME like ?"); |
17 | ORDER_BY("P.ID"); |
18 | ORDER_BY("P.FULL_NAME"); |
19 | }}.toString(); |
20 | } |
SQL 类
1 | // Anonymous inner class |
2 | public String deletePersonSql() { |
3 | return new SQL() {{ |
4 | DELETE_FROM("PERSON"); |
5 | WHERE("ID = #{id}"); |
6 | }}.toString(); |
7 | } |
8 | |
9 | // Builder / Fluent style |
10 | public String insertPersonSql() { |
11 | String sql = new SQL() |
12 | .INSERT_INTO("PERSON") |
13 | .VALUES("ID, FIRST_NAME", "#{id}, #{firstName}") |
14 | .VALUES("LAST_NAME", "#{lastName}") |
15 | .toString(); |
16 | return sql; |
17 | } |
18 | |
19 | // With conditionals (note the final parameters, required for the anonymous inner class to access them) |
20 | public String selectPersonLike(final String id, final String firstName, final String lastName) { |
21 | return new SQL() {{ |
22 | SELECT("P.ID, P.USERNAME, P.PASSWORD, P.FIRST_NAME, P.LAST_NAME"); |
23 | FROM("PERSON P"); |
24 | if (id != null) { |
25 | WHERE("P.ID like #{id}"); |
26 | } |
27 | if (firstName != null) { |
28 | WHERE("P.FIRST_NAME like #{firstName}"); |
29 | } |
30 | if (lastName != null) { |
31 | WHERE("P.LAST_NAME like #{lastName}"); |
32 | } |
33 | ORDER_BY("P.LAST_NAME"); |
34 | }}.toString(); |
35 | } |
36 | |
37 | public String deletePersonSql() { |
38 | return new SQL() {{ |
39 | DELETE_FROM("PERSON"); |
40 | WHERE("ID = #{id}"); |
41 | }}.toString(); |
42 | } |
43 | |
44 | public String insertPersonSql() { |
45 | return new SQL() {{ |
46 | INSERT_INTO("PERSON"); |
47 | VALUES("ID, FIRST_NAME", "#{id}, #{firstName}"); |
48 | VALUES("LAST_NAME", "#{lastName}"); |
49 | }}.toString(); |
50 | } |
51 | |
52 | public String updatePersonSql() { |
53 | return new SQL() {{ |
54 | UPDATE("PERSON"); |
55 | SET("FIRST_NAME = #{firstName}"); |
56 | WHERE("ID = #{id}"); |
57 | }}.toString(); |
58 | } |