您的位置:首页 > 移动开发

Mapper映射语句——Mybatis的真正力量

2013-07-27 20:28 120 查看
之所以使用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}’的格式。


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息