之所以使用MyBatis這個持久層框架,就是因爲MyBatis的Mapper映射,你會發現通過使用Mapper的映射語句,是你減少了95%以上的代碼量,當然,這些是相對於同等功能的JDBC語句來說的。
現在,我們將正式開始學習關於Mapper映射的相關內容。
我們將通過一系列的實例來展示Mapper的SQL映射。
先來了解一下關於Mapper的一些元素:
cache:配置給定命名空間的緩存。
cache-ref:從其他命名空間引用緩存配置。
resultMap:最複雜的標籤,Mapper的核心標籤,更深層次的會在之後講解。
sql:可以重用的SQL塊,減少代碼量是非常方便的。
insert、update、delete、select這四個標籤恐怕我們不需要說也知道它的作用了吧。
爲了更充分的體驗MyBatis,我們通過一個連貫的實例來使用這些標籤。
我們在前一個測試項目的基礎上進行改動:
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>
<properties resource="jdbc.properties"></properties>
<settings>
<setting name="cacheEnabled" value="true" />
<setting name="lazyLoadingEnabled" value="true" />
<setting name="multipleResultSetsEnabled" value="true" />
<setting name="useColumnLabel" value="true" />
<setting name="useGeneratedKeys" value="false" />
<setting name="autoMappingBehavior" value="PARTIAL" />
<setting name="defaultExecutorType" value="SIMPLE" />
<setting name="defaultStatementTimeout" value="25" />
<setting name="safeRowBoundsEnabled" value="false" />
<setting name="mapUnderscoreToCamelCase" value="false" />
<setting name="localCacheScope" value="SESSION" />
<setting name="jdbcTypeForNull" value="OTHER" />
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString" />
</settings>
<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>
</configuration>
jdbc.properties的配置爲:
driver=com.mysql.jdbc.Driver
url=jdbc\:mysql\://localhost\:3306/mybatis2
username=root
password=88308887
因爲是測試項目,也不需要一些web之類的,所以上面是一個很普通的java項目,我們現在要做的是一個登錄程序,通過這個登錄程序,我們可以進行登錄操作。而通過這個首頁,我們可以添加,修改,查詢,刪除用戶(不包括我們現在使用的這個用戶)。而通過這個例子,相信所有需要用到的標籤都很容易掌握:
我們先進行數據庫的設計,因爲我們所有的操作都是可以通過一張用戶表進行的。所以,我們可以設計這麼一張用戶表,它包括用戶ID,用戶密碼,用戶姓名。
drop database if exists mybatis2;
create database if not exists mybatis2;
use mybatis2;
drop table if exists user;
create table if not exists user(
userid varchar(100) primary key not null,
username varchar(100) not null,
password varchar(100) not null
);
insert into user values('admin','test','123456');
insert into user values('guest','guest','123456');
insert into user values('costomer','costomer','123456');
將該sql執行,我們mysql中就有了這個表,並且有了一些數據。
之後,我們修改User:
package net.mybatis.model;
import org.apache.ibatis.type.Alias;
@Alias("User")
public class User {
private String userid;
private String username;
private String password;
public String getUserid() {
return userid;
}
public void setUserid(String userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return this.getClass().getName() + ":[userid:" + this.userid
+ ",username:" + this.username + ",password:" + this.password
+ "]";
}
}
我們先做登錄功能:
登錄需要的操作是驗證用戶名和密碼。
在IUserDao接口類中,添加一個驗證用戶名密碼的抽象方法:
package net.mybatis.dao;
import net.mybatis.model.User;
public interface IUserDao {
public boolean login(User user);
}
在UserDaoImpl實現該方法:
package net.mybatis.dao.impl;
import org.apache.ibatis.session.SqlSession;
import net.mybatis.dao.IUserDao;
import net.mybatis.model.User;
public class UserDaoImpl implements IUserDao{
private SqlSession session;
public UserDaoImpl(SqlSession sqlSession){
this.session = sqlSession;
}
@Override
public boolean login(User user) {
user = this.session.selectOne("net.mybatis.mapper.UserMapper.login", user);
System.out.println(user);
if(user.getUsername()!=null&&(!user.getUsername().equals(""))){
return true;
}else{
return false;
}
}
}
在mybatis-config.xml中添加mapper的映射:
<mappers>
<mapper resource="net/mybatis/mapper/user.mapper.xml"/>
</mappers>
在user.mapper.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="net.mybatis.mapper.UserMapper">
<select id="login" parameterType="net.mybatis.model.User" resultType="net.mybatis.model.User">
select * from user where userid=#{userid} and password=#{password}
</select>
</mapper>
修改IuserService這個接口類的實現類:UserServiceImpl:
package net.mybatis.service.impl;
import org.apache.ibatis.session.SqlSession;
import net.mybatis.dao.IUserDao;
import net.mybatis.dao.impl.UserDaoImpl;
import net.mybatis.model.User;
import net.mybatis.service.IUserService;
public class UserServiceImpl implements IUserService{
private IUserDao dao;
public UserServiceImpl(SqlSession sqlSession){
this.dao = new UserDaoImpl(sqlSession);
}
@Override
public boolean login(User user) {
return this.dao.login(user);
}
}
修改UserProxy代理類爲:
package net.mybatis.proxy;
import java.io.IOException;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import net.mybatis.manager.SessionManager;
import net.mybatis.model.User;
import net.mybatis.service.IUserService;
import net.mybatis.service.impl.UserServiceImpl;
public class UserProxy {
private SqlSessionFactory sqlSessionFactory;
private SqlSession sqlSession;
private IUserService service;
public UserProxy(){
try {
this.sqlSessionFactory = SessionManager.getFactory();
} catch (IOException e) {
e.printStackTrace();
}
this.sqlSession = this.sqlSessionFactory.openSession();
this.service = new UserServiceImpl(this.sqlSession);
}
public boolean login(String userid,String password) throws Exception{
boolean flag = false;
User user = new User();
user.setUserid(userid);
user.setPassword(password);
try{
flag = this.service.login(user);
}catch(Exception e){
throw e;
}finally{
this.sqlSession.close();
}
return flag;
}
}
修改測試類Test:
package net.mybatis.test;
import java.util.Scanner;
import net.mybatis.proxy.UserProxy;
public class Test {
public static void main(String []args) throws Exception{
Scanner input = new Scanner(System.in);
UserProxy proxy = new UserProxy();
String userid = input.next();
String password = input.next();
System.out.println(proxy.login(userid, password));
}
}
運行JAVA程序:
輸入用戶名和密碼,可以很容易的發現我們的程序運行成功,輸入正確,會在控制檯中顯示true。
通過上述的例子,我們可以大概的瞭解到MyBatis中的select用法。
下面列出select元素所能包好的一些屬性:
屬性 |
描述 |
id |
唯一標識符,用來引用該條語句的憑證 |
parameterType |
將會傳入參數的完全限定名或別名 |
resultType |
返回的完全限定名或別名。注意:集合的時候返回的是集合包含的類型,而不是集合本身的類型 |
resultMap |
引用外部的Map,可以構造許多複雜的類型,譬如多表查詢和限定列查詢。注意:resultType和resultMap不能同時使用 |
flushCache |
不管語句什麼時候被調用,都會清空緩存 |
useCache |
使語句的結果緩存 |
timeout |
設置驅動的最長等待時間,並拋出時間異常,默認不處理 |
fetchSize |
每次返回結果行數 |
statementType |
STATEMENT,PREPARED或CALLBLE中的一種。選擇執行語句的使用的是statement,PreparedStatement還是CallableStatemtn? |
resultSetType |
FORWARD_ONLY,SCROLL_SENSITIVE,SCROLL_INSENSITIVE |
databaseId |
如果存在配置的dabaseIdProvider,MyBatis將會加載所有匹配當前databaseIdProvider的不存在databaseId和存在databaseId屬性的語句。如果發現兩個相同的語句,一個存在databaseId,另一個不存在,那麼後者將被拋棄。 |
resultOrdered |
這個只是用於嵌套語句,這個屬性的值爲真的時候: |
通過以下的標籤添加功能:
<select id="getAllUsers" parameterType="net.mybatis.model.User" resultType="net.mybatis.model.User" >
select * from user where userid != #{userid}
</select>
<insert id="addUser" parameterType="net.mybatis.model.User">
insert into user(userid,username,password) values(#{userid},#{username},#{password})
</insert>
<delete id="deleteUser" parameterType="net.mybatis.model.User">
delete from user where userid = #{userid}
</delete>
<update id="modifyUser" parameterType="net.mybatis.model.User">
update user set username = #{username}, password = #{password} where userid = #{userid}
</update>
<select id="searchUser" parameterType="string" resultType="net.mybatis.model.User">
select * from user where userid = '${_parameter}' and username = '{_parameter}'
</select>
上述需要說的是以下幾條:
1)傳入爲類的話(這個類必須要是用戶自己定義的,而不是
MyBatis提供的基本類型中的譬如Sring的類),參數名必須要和類的屬性名保持一致,如果沒有一致,那麼可能會發生無法找到列的錯誤。
2)傳入爲基本類型的時候,需要注意的是,參數只能有一個,多個參數會使得後面的參數無法做變更,而且,這個參數必須爲#{_parameter}的形式,不管它參數名爲什麼。而且,這個基本類型爲String的時候,在#{_parameter}的前面要加上單引號,就如:’#{_parameter}’的格式。