oracle:
thin:
@xxx.xxx.xxx.xxx:
xxxx:
xxxxxx"/>
20
21
22
23
24
25
26
--RegisterMapper-->
27
28
--SQLMapper-->
29
30
31
32
mybatis-config.xml
既然有了配置的xml,下一步就需要让Mybatis加载它了。
首先以输入流的形式加载xml
以“SqlSessionFactoryBuilder-> SqlSessionFactory-> SqlSession”的流程最后构建出SqlSession。
SqlSession,顾名思义,是一次会话,是应用程序与数据库交互的会话,所以,其生命周期应在一次数据库连接之间,当然,此次数据库连接可以包含一次或多次数据库操作。
SqlSessionFactory,顾名思义,是SqlSession的工厂类,用于产出SqlSession。
我们知道,SqlSession主要用于数据库操作,而数据库操作又是贯穿于应用程序整个生命周期当中的,那么,"产出SqlSession"这个动作也应当贯穿于应用程序整个生命周期当中,所以,SqlSessionFactory的生命周期一般为应用程序的整个生命周期,一般为单例/static的形式存在。
SqlSessionFactoryBuilder,由代码可见,其主要作用是从配置文件中获取配置信息,然后构建SqlSessionFactory,所以其生命周期可以是临时的,局部的。
通过SqlSession获取UserMapper接口,再调用该接口的数据操纵方法。
packagecom.nicchagil.mybatisonly;
importjava.io.IOException;
importjava.io.InputStream;
importorg.apache.ibatis.io.Resources;
importorg.apache.ibatis.session.SqlSession;
importorg.apache.ibatis.session.SqlSessionFactory;
importorg.apache.ibatis.session.SqlSessionFactoryBuilder;
importcom.nicchagil.mybatisonly.bean.User;
importcom.nicchagil.mybatisonly.mapper.UserMapper;
publicclassCall{
publicstaticSqlSessionFactorysqlSessionFactory=null;
publicstaticvoidmain(String[]args)throwsIOException{
//QueryUser
/*
kickStartMybatis();
queryUser("nick");
*/
//InserUser
kickStartMybatis();
insertUser("user004","helloworld.");
}
publicstaticvoidkickStartMybatis()throwsIOException{
Stringresource="com/nicchagil/mybatisonly/mybatis-config.xml";
InputStreaminputStream=Resources.getResourceAsStream(resource);
sqlSessionFactory=newSqlSessionFactoryBuilder().build(inputStream);
}
/**
*QueryUser
*@paramusername
*@return
*/
publicstaticUserqueryUser(Stringusername){
Useruser=null;
SqlSessionsession=sqlSessionFactory.openSession();
try{
/*Un-recommendedMethod*/
/*
user=(User)session.selectOne("com.nicchagil.mybatisonly.mapper.UserMapper.queryUser",username);
*/
/*RecommendedMethod*/
UserMapperuserMapper=session.getMapper(UserMapper.class);
user=userMapper.queryUser(username);
System.out.println("username-"+user.getUsername()+",password-"+user.getPassword());
}finally{
session.close();
}
returnuser;
}
/**
*InsertUser
*@paramusername
*@parampassword
*/
publicstaticvoidinsertUser(Stringusername,Stringpassword){
SqlSessionsession=sqlSessionFactory.openSession();
try{
UserMapperuserMapper=session.getMapper(UserMapper.class);
Useruser=newUser();
user.setUsername(username);
user.setPassword(password);
userMapper.insertUser(user);
//Flushesbatchstatementsandcommitsdatabaseconnection.
//Notethatdatabaseconnectionwillnotbecommittedifnoupdates/deletes/insertswerecalled.
mit();
System.out.println("username-"+user.getUsername()+",password-"+user.getPassword());
}catch(Exceptione){
session.rollback();
e.printStackTrace();
//TODOPrinttheexceptionlogs
//TODOPromptsfailtoexecuteforuser
}finally{
session.close();
}
}
/**
*InsertUser
*@paramusername
*@parampassword
*/
publicstaticvoidinsertUserBySQL(Stringusername,Stringpassword){
SqlSessionsession=sqlSessionFactory.openSession();
try{
Useruser=newUser();
user.setUsername(username);
user.setPassword(password);
session.insert("com.nicchagil.mybatisonly.mapper.UserMapper.insertUser",user);
//Flushesbatchstatementsandcommitsdatabaseconnection.
//Notethatdatabaseconnectionwillnotbecommittedifnoupdates/deletes/insertswerecalled.
mit();
}catch(Exceptione){
session.rollback();
e.printStackTrace();
//TODOPrinttheexceptionlogs
//TODOPromptsfailtoexecuteforuser
}finally{
session.close();
}
}
}
Call
UserMapper是一个DAO的接口,是定义作哪些数据库操作的。
1packagecom.nicchagil.mybatisonly.mapper;
2
3importcom.nicchagil.mybatisonly.bean.User;
4
5publicinterfaceUserMapper{
6
7publicUserqueryUser(Stringusername);
8
9}
UserMapper.java
UserMapper只是供调用的接口,那么具体的实现逻辑在哪里呢?
我们可见UserMaper.xml,它定义的SQL就是用于定义UserMapper接口的实现。
我们需在mybatis-config.xml注册UserMaper.xml,可见mybatis-config.xml的mappers节点。
我们可以看到id为queryUser,与接口的方法名对应;
SQL我们很熟悉了,就是一个简单的SQL,而#{username},就是接口方法的入参;
resultType为"user",这个user是一个别名,具体对应com.nicchagil.mybatisonly.bean.User这个类,我们可以看到在mybatis-config.xml文件的typeAliases节点中已经注册它们的映射关系。
xmlversion="1.0"encoding="UTF-8"?
>
DOCTYPEmapper
PUBLIC"-//mybatis.org//DTDMapper3.0//EN"
":
//mybatis.org/dtd/mybatis-3-mapper.dtd">
select*fromt_user_test_1407twheret.username=#{username}
INSERTINTOt_user_test_1407T(T.USERNAME,T.PASSWORD)VALUES(#{username},#{password})
UserMapper.xml
而com.nicchagil.mybatisonly.bean.User是实体类,用于装载数据。
1packagecom.nicchagil.mybatisonly.bean;
2
3publicclassUser{
4
5privateStringusername;
6privateStringpassword;
7
8publicStringgetUsername(){
9returnusername;
10}
11
12publicvoidsetUsername(Stringusername){
13this.username=username;
14}
15
16publicStringgetPassword(){
17returnpassword;
18}
19
20publicvoidsetPassword(Stringpassword){
21this.password=password;
22}
23
24@Override
25publicinthashCode(){
26finalintprime=31;
27intresult=1;
28result=prime*result
29+((password==null)?
0:
password.hashCode());
30result=prime*result
31+((username==null)?
0:
username.hashCode());
32returnresult;
33}
34
35@Override
36publicbooleanequals(Objectobj){
37if(this==obj)
38returntrue;
39if(obj==null)
40returnfalse;
41if(getClass()!
=obj.getClass())
42returnfalse;
43Userother=(User)obj;
44if(password==null){
45if(other.password!
=null)
46returnfalse;
47}elseif(!
password.equals(other.password))
48returnfalse;
49if(username==null){
50if(other.username!
=null)
51returnfalse;
52}elseif(!
username.equals(other.username))
53returnfalse;
54returntrue;
55}
56
57}
User.java
最后,我们运行Call.java,将能成功查询、插入数据库。
我们可通过打印的信息和查询数据库,以查看是否成功查询、插入数据。
3)事务说明
对于数据库有写操作的应用程序,一般来说,事务是不可或缺的一部分。
因为未使用其他框架,这里使用编程式事务,即使用SqlSmit()和SqlSession.rollback()方法,可见Call.java。
由于本程序对事务有异常回滚的要求,所以,需要获取非自动提交的SqlSession
如程序执行正常,则最后执行mit()以提交事务。
mit()有个需注意的地方,参考其如下注释,即如果当前会话中不涉及updates/deletes/insert等写数动作则不提交事务。
所以,如果要触发Mybatis提交事务,就需执行明确的触发动作,如“执行session.insert(...)方法”或“执行对应的SQLMapper配置中的insert、update、delete等标签”等操作。
(本人曾尝试在SQLMapper配置中用select标签包含INSERT的SQL,使用SqlSmit()后,执行正常,但没有提交事务,可见并未触发,所以,需规范使用标签)。
如需强制提交,可用SqlSmit(boolean)。
Flushesbatchstatementsandcommitsdatabaseconnection.Notethatdatabaseconnectionwillnotbecommittedifnoupdates/deletes/insertswerecalled.ToforcethecommitcallSqlSmit(boolean)
如程序执行异常,则回滚事务,session.rollback()
单独搭建Mybaits完毕!
二、 Mybatis与Spring的整合
一个项目中,单独使用Mybatis的情况并不多;更多的情况下,我们需要将Mybatis与其他框架进行整合,以便更好地使用。
比如Mybatis+Spring,就是一个流行的整合组合。
1)环境准备、版本说明
本次用Mybatis3+Spring3进行整合。
注意,并不包含MVC框架的配置,因为本文的目的是学习Mybatis,所以尽量不引用其他框架,以避免影响代码的理解。
需引入的类库详情如下:
junit
junit
3.8.1
test
org.springframework
spring-context
3.2.10.RELEASE
org.springframework.webflow
spring-webflow
2.4.0.RELEASE
org.springframework.data
spring-data-oracle