mybatis使用初探
简介:MyBatis 是一款持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects)为数据库中的记录。
mybatis全局配置文件
一个简单的例子:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<configuration>
<!--引入外部资源,注意路径,-->
<properties resource="db.properties"/>
<!--环境配置,可以配置多个环境,default选择哪一个环境,比如开发,测试,上线的环境可能不同-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!--引入映射文件-->
<mappers>
<mapper resource="mapper/manageMapper.xml"/>
</mappers>
</configuration>
properties标签
这些属性都是可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过 properties 元素的子元素来传递。
例如1
2
3
4<properties resource="org/mybatis/example/config.properties">
<property name="username" value="dev_user"/>
<property name="password" value="F2Fa3!33TYyg"/>
</properties>
如果属性在不只一个地方进行了配置,那么 MyBatis 将按照下面的顺序来加载:
- 在 properties 元素体内指定的属性首先被读取。
- 然后根据 properties 元素中的 resource 属性读取类路径下属性文件或根据 url 属性指定的路径读取属性文件,并覆盖已读取的同名属性。
- 最后读取作为方法参数传递的属性,并覆盖已读取的同名属性。
environments标签
可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中。例如,开发、测试和生产环境需要有不同的配置;或者想在具有相同 Schema 的多个生产数据库中 使用相同的 SQL 映射。有许多类似的使用场景。
尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。 所以,如果想连接两个数据库,就需要创建两个 SqlSessionFactory 实例,每个数据库对应一个。而如果是三个数据库,就需要三个实例,依此类推。
每个数据库对应一个 SqlSessionFactory 实例,为了指定创建哪种环境,只要将它作为可选的参数传递给 SqlSessionFactoryBuilder 即可。可以接受环境配置的两个方法签名是:1
2SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, properties);
如果忽略了环境参数,那么将会加载默认环境,如下所示:1
2SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, properties);
settings标签
这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。
内容很多,比如是否开启驼峰命名转换,延迟加载,日志,超时时长等等。
参考文档http://www.mybatis.org/mybatis-3/zh/configuration.html
typeAliases标签
类型别名是为 Java 类型设置一个短的名字。 它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余。可以不使用权限定名而使用简短的别名。
1 | <typeAliases> |
当然也可以使用注解:1
2
3
4"author") (
public class Author {
...
}
mybatis内置了一些常用的别名。包括java中基础类型以及它们的包装类型还有一些集合类。
mappers标签
需要告诉 MyBatis 到哪里去找到这些语句。 可以使用相对于类路径的资源引用,或完全限定资源定位符(包括 file:/// 的 URL),或类名和包名等。
plugins标签
允许在已映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:
- Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
- ParameterHandler (getParameterObject, setParameters)
- ResultSetHandler (handleResultSets, handleOutputParameters)
- StatementHandler (prepare, parameterize, batch, update, query)
mapper文件
将sql语句写在映射文件中,可以将sql与java代码分离,方便管理,并且可以。mybatis的映射文件具有很强大的功能。
参数问题
1 | <!--命名空间,类路径--> |
如果有多个参数呢:
1 | <select id="selectByIdAndName" resultType="entity.Manage"> |
直接这样写会失败
因为mybatis使用了一个map来存储参数,map< key,value >
- 使用#{arg0},#{arg1}…;或者#{param1},#{param2}…
- 在接口方法上使用注解@Param(“id),Param(“name”),这样就可以使用上述的方法
- 使用map,将参数封装到map中,也可以使用上述的方法
- 封装一个传输数据的类
# 和$的区别
mybatis支持#{}和${}动态绑定参数,但是它们之间有区别。
- #{}像是jdbc支持的占位符,只能用来为可以加引号’的参数(如参数值)设置动态参数,即用?占位,不可用于表名、字段名等。像是预编译,可以防止sql注入
- ${}是直接替换,可能导致不安全,比如sql注入。
一个例子:1
2
3
4
5
6<select id="selectByMap" resultType="entity.Manage">
select * from ${table}
where id=#{id} and name=#{name}
</select>
加入此时传入的参数,table=”manage ^&%FSUq345”,那么将会出错。
增删改查
增删改查操作都几乎一致
java代码调用方法
一个简单的例子1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public class ManageTest {
//获取mybatis配置文件,并根据配置文件加载一些环境
String resource= "mybatis-config.xml";
InputStream in= Resources.getResourceAsStream(resource);
//获取SqlSessionFactory
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(in);
public ManageTest() throws IOException {
}
public void querytOne() throws IOException {
//获取SqlSession,数据库的增删改查都需要SqlSession,但是它不是线程安全的,不能将它定义为对象的成员属性或者静态变量
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
//获取接口的代理对象,使用的动态代理
ManageMapper mapper = sqlSession.getMapper(ManageMapper.class);
Manage manage = mapper.selectById(1234567890L);
System.out.println(manage);
}finally {
//关闭资源
sqlSession.close();
}
}
public void insert(){
//不自动提交,如果需要自动提交:sqlSessionFactory.openSession(true);
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
ManageMapper mapper = sqlSession.getMapper(ManageMapper.class);
Manage manage=new Manage(996996996L,"spj","123");
int result=mapper.insert(manage);
System.out.println(result);
//提交
sqlSession.commit();
}finally {
sqlSession.close();
}
}
//省略其他测试
}
以上使用到的接口1
2
3
4
5
6
7
8
9
10
11
12
13
14
public interface ManageMapper {
Manage selectById(long id);
int insert(Manage manage);
Manage selectByIdAndName(long id,String name);
Manage selectByMap(Map map);
int update(Manage manage);
}
使用的实体类1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Manage {
private long id;
private String name;
private String password;
public Manage(){}
public Manage(long id, String name, String passWord) {
this.id = id;
this.name = name;
this.password = passWord;
}
//省略setter,getter,toString方法
}