MyException - 我的异常网
当前位置:我的异常网» MySQL » MyBatis容易使用和入门理解

MyBatis容易使用和入门理解

www.MyException.Cn  网友分享于:2013-08-14  浏览:0次
MyBatis简单使用和入门理解

本文记录第一次使用Mybatis时碰到的一些错误和简单理解,采用的示例是Eclipse中的JAVA工程,采用XML文件定义数据库连接。

 

可以使用Java JDBC API直接操作数据库,但使用框架会更便捷、高效而且还可以利用框架提供的某些强大的功能(比如事务管理),而Mybatis就是这样的一个框架。

Mybatis主要由四大部分组成:

①SqlSessionFactoryBuilder

②SqlSessionFactory

③SqlSession

④SQL Mapper

要想访问(操作)数据库:要建立数据库连接,要定义数据库操作方法(insert/update/delete...),要有具体的操作数据库中的表 的SQL语句,而SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession就是用来负责底层建立数据库连接、管理连接、释放连接等。对于业务层而言,关心的是:定义一个SQL语句,让Mybatis方便地把SQL语句执行后的结果 呈现给使用者,而这可以通过SQL Mapper来完成。

SQL Mapper由两部分组成,一是:JAVA 接口,该接口中定义了 业务层 要对数据库进行何种操作;另一部分是:XML配置文件,定义了具体的数据库操作语句和映射规则。

假设要操作数据库test中的表 t_role,t_role有三个字段:id ,role_name,和 note

+-----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| role_name | varchar(20) | YES | | NULL | |
| note | varchar(20) | YES | | NULL | |
+-----------+-------------+------+-----+---------+----------------+

该表对应的POJO类如下:

package chapter2.pojo;

public class Role {
    private Long id;
    private String roleName;
    private String note;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getRoleName() {
        return roleName;
    }
    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }
    public String getNote() {
        return note;
    }
    public void setNote(String note) {
        this.note = note;
    }
    
    @Override
    public String toString() {
        return "id:" + id + ", roleName:" + roleName + ", note:" + note;
    }
}
View Code

 

JAVA接口中定义的一些操作如下:

package chapter2.mapper;
import
java.util.List; import java.util.Map; import chapter2.pojo.Role; public interface RoleMapper { public Role getRole(Long id); public int deleteRole(Long id); public int insertRole(Role role); public List<Role> findRoleByMap(Map<String, String> params); }

 

与该接口对应,定义的具体操作数据库的配置文件RoleMapper.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="chapter2.mapper.RoleMapper">

<resultMap type="chapter2.pojo.Role" id="roleMap">
<id property="id" column="id"/><!-- primary key -->
<result property="roleName" column="role_name"/><!-- 普通列的映射关系 -->
<result property="note" column="note"/>
</resultMap>


    <select id="getRole" parameterType="long" resultType="Role">
        select id, role_name as roleName, note from t_role where id = #{id}
    </select>
    <insert id="insertRole" parameterType="Role">
        insert into t_role(role_name,note) values(#{roleName},#{note})
    </insert>
    <delete id="deleteRole" parameterType="long">
        delete from t_role where id = #{id}
    </delete>
    
    <select id="findRoleByMap" parameterType="map" resultMap="roleMap">
        select id,role_name,note from t_role
        where role_name like concat('%', #{roleName},'%')
        and note like concat('%',#{note},'%')
    </select>
</mapper>

 

然后,就可以用SqlSessionFactory创建SqlSession,SqlSession获取相应的RoleMapper实例,再使用RoleMapper实例调用RoleMapper接口中定义的方法,最终由Mybatis根据 RoleMapper.xml配置文件将 方法 与 映射成具体的数据库操作语句,最终访问数据库。

使用SqlSessionFactoryBuilder 根据 mybatisConfig.xml中配置的 dataSource创建SqlSessionFactory,再使用SqlSessionFactory创建SqlSession,代码如下:

package chapter2.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class SqlSessionFactoryUtil {
    private static SqlSessionFactory sqlSessionFactory = null;
    private static final Class CLASS_LOCK = SqlSessionFactoryUtil.class;
    private SqlSessionFactoryUtil() {}
    
    public static SqlSessionFactory initSqlSessionFactory() {
        String resource = "mybatisConfig.xml";
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
        }catch(IOException ex) {
            Logger.getLogger(SqlSessionFactoryUtil.class.getName()).log(Level.SEVERE, null, ex);
        }
        synchronized (CLASS_LOCK) {
            if(sqlSessionFactory == null) {
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            }
        }
        return sqlSessionFactory;
    }
    
    public static SqlSession openSqlSession() {
        if(sqlSessionFactory == null)
        {
            initSqlSessionFactory();
        }
        return sqlSessionFactory.openSession();
    }
}
View Code

 

用户程序根据SqlSession来获取RoleMapper(第20行),然后调用里面定义的方法操作数据库,从这里也可以看出,我们只需要定义好接口,在XML配置文件中定义SQL操作语句,就可以访问数据库了:代码如下:

package chapter2.main;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;

import chapter2.mapper.RoleMapper;
import chapter2.pojo.Role;
import chapter2.util.SqlSessionFactoryUtil;

public class Chapter2Main {
    public static void main(String[] args)throws IOException {
        SqlSession sqlSession = null;
        
        try {
            sqlSession = SqlSessionFactoryUtil.openSqlSession();
            RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
            
            Role role = new Role();
            role.setRoleName("testName");
            role.setNote("testNote");
            roleMapper.insertRole(role);
            //roleMapper.deleteRole(1L);
            sqlSession.commit();
            
            Map<String, String> paramsMap = new HashMap<>();
            paramsMap.put("roleName", "me");
            paramsMap.put("note", "no");//与sql语句中的 #{note} #{roleName}一致
            List<Role> result = roleMapper.findRoleByMap(paramsMap);
            for (Role role2 : result) {
                System.out.println(role2);
            }
            
        }catch(Exception e) {
            System.out.println(e);
            sqlSession.rollback();
        }finally {
            if(sqlSession != null)
                sqlSession.close();
        }
        
    }
}
View Code

 

Mybatis配置数据库连接: mybatisConfig.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"    
 3 "http://mybatis.org/dtd/mybatis-3-config.dtd">
 4 <configuration>
 5     <properties resource="jdbc.properties">
 6     </properties>
 7     <typeAliases>
 8         <typeAlias alias="Role" type="chapter2.pojo.Role" />
 9     </typeAliases>
10 
11     <environments default="development">
12         <environment id="development">
13             <transactionManager type="JDBC">
14                 <property name="autoCommit" value="false" />
15             </transactionManager>
16             <dataSource type="POOLED">
17                 <property name="driver" value="${driver}" />
18                 <property name="url" value="${url}" />
19                 <property name="username" value="${username}" />
20                 <property name="password" value="${password}" />
21             </dataSource>
22         </environment>
23     </environments>
24 
25     <mappers>
26         <mapper resource="chapter2\mapper\RoleMapper.xml" />
27     </mappers>
28 </configuration>

Mybatis的XML配置文件定义了许多配置标签:比如 <configuration> <properties> <settings> <typeAliases> ....等标签。

这些标签是有层次结构的,顺序不能乱。比如,<properties>标签应该放在 <typeAliases> 标签前面。

上面的第5行<properties>标签 通过  resource 指定一个外部jdbc配置文件,这样在16-21行配置 数据源 的时候,就可以使用 变量 来引用 外部jdbc配置文件中定义的值了,从而方便切换数据库配置。

外部jdbc配置文件如下:

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
username=root
password=xxxx

 

下面来重点解释:操作数据库的XML配置文件RoleMapper.xml 和 接口RoleMapper 以及POJO类RoleMapper之间的一些关系:

RoleMapper 接口中定义的getRole方法:

public Role getRole(Long id);

 

RoleMapper.xml配置文件中与该方法对应的SQL语句:

    <select id="getRole" parameterType="long" resultType="Role">
        select id, role_name as roleName, note from t_role where id = #{id}
    </select>

id 用来唯一标明这条 select 语句。它与RoleMapper.xml中 <mapper namespace>标签内容组合在一起,唯一标识了 这条 select 操作语句。这里的resultType="Role","Role"是在mybatisConfig.xml中定义的别名。

<mapper namespace="chapter2.mapper.RoleMapper">

public Role getRole(Long id);

<select id="getRole" parameterType="long" resultType="Role">


id 的值getRole 就是接口RoleMapper中 定义的 getRole方法名
parameterType 就是getRole方法的参数类型
resultType 就是执行SQL语句后返回的结果,把结果 封装 成POJO类 Role 类型---这也是getRole方法的返回类型。而方法的参数 会传递给#{id}

 

几种传 多个参数 给SQL语句的方法:

一,通过Map对象传参数

RoleMapper中定义的findRoleByMap方法

    public List<Role> findRoleByMap(Map<String, String> params);
    <select id="findRoleByMap" parameterType="map" resultMap="roleMap">
        select id,role_name,note from t_role
        where role_name like concat('%', #{roleName},'%')
        and note like concat('%',#{note},'%')
    </select>

当我们需要根据多个 参数 查找数据库时,且查找的结果也可能返回多条记录时,就使用上面的配置。

paramterType="map",传入一个map对象作为select语句的参数,其中map中的每个元素的key 对应 while子句中的#{roleName}#{note}

由于这里的while子句 只根据 两个参数 来查询,因此map的长度为2. 而map的value,则是 查询的条件的值。

            Map<String, String> paramsMap = new HashMap<>();
            paramsMap.put("roleName", "me");//value是要满足的条件值   while note = "me"
            paramsMap.put("note", "no");//Key与sql语句中的 #{note} #{roleName}一致
            List<Role> result = roleMapper.findRoleByMap(paramsMap);

select id,role_name,note from t_role   where role_name like concat('%', ?,'%')   and note like concat('%',?,'%')

比如:select id,role_name,note from t_role   where role_name like concat("me")   and note like concat("no")

 

resultMap指明了返回的“结果”的形式:resultMap=roleMap。resultMap的定义如下:(可理解为:resultMap的key是 属性名或者字段名,而value则是 相应的 结果值)

<resultMap type="chapter2.pojo.Role" id="roleMap">
<id property="id" column="id"/><!-- primary key -->
<result property="roleName" column="role_name"/><!-- 普通列的映射关系 -->
<result property="note" column="note"/>
</resultMap>

<id property="id" column="id" 表明 id 是 t_role表的主键,主键的列名是 "id"

<result property="roleName" colum="role_name"/> 表明:roleName是POJO类的属性名,"role_name"是数据库表t_role的列名,将二者对应起来。

 

二,使用参数注解的方式传递多个参数

或者使用更“易懂“的映射方法:----参数注解

RoleMapper接口里面定义的方法:

    public List<Role> findRoleByAnnotation(@Param("roleName")String roleName, @Param("note")String note);

 

RoleMapper.xml配置文件里面的定义的SQL语句:这里就没有 paramterType 来定义查询的参数了

        <select id="findRoleByAnnotation"resultMap="roleMap">
        select id,role_name,note from t_role
        where role_name like concat('%', #{roleName},'%')
        and note like concat('%',#{note},'%')
    </select>

 

客户端 调用方法:这里,就可以不用HashMap封装多个待查询的参数了。

List<Role> res = roleMapper.findRoleByAnnotation("me", "no");
for (Role role2 : res) {
    System.out.println(role2);
    }

 

三,使用JAVA Bean对象传递参数:

RoleMapper.xml配置文件里面的定义的SQL语句:

    <select id="findRoleByParam" parameterType="chapter2.pojo.RoleParam"
        resultMap="roleMap">
        select id,role_name,note from t_role
        where role_name like
        concat('%', #{roleName},'%')
        and note like concat('%',#{note},'%')
    </select>

 

RoleMapper.java接口方法:

    public List<Role> findRoleByParam(RoleParam role);

 

客户端调用执行:

            RoleParam rp = new RoleParam();
            rp.setNote("note");
            rp.setRoleName("test");
            List<Role> roles = roleMapper.findRoleByParam(rp);

 

批量插入操作:

RoleMapper.xml配置文件里面的定义的SQL语句:

    <insert id="insertBatch"  useGeneratedKeys="true" parameterType="java.util.List">
        insert into t_role(role_name, note)
        values
        <foreach collection="list" item="item" index="index"
            separator=",">
            (#{item.roleName},#{item.note})
        </foreach>
    </insert>

useGeneratedKeys="true" 表明使用数据库表中自带的主键自增策略。在文章所述的t_role表的结构中, id 是自增的主键,但是这里的批量插入操作,并不需要显示的插入 id 的值。

待插入的每条记录值 放在 java.util.List 对象中保存,通过 foreach 循环遍历,"item"代表遍历到的每条记录---即每个Role对象, 通过 #{item.roleName} 和 #{item.note} 取出Role对象属性值---即每个表的字段值。


RoleMapper.java接口方法:

    public void insertBatch(List<Role> roleList);

 

客户端调用执行:(记得最终 调用 commit() 方法进行提交)

            sqlSession = SqlSessionFactoryUtil.openSqlSession();
            RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
            
            Role role = new Role();
            role.setRoleName("testName");
            role.setNote("testNote");
            
            Role role2 = new Role();
            role2.setRoleName("xx");
            role2.setNote("notexx");
            
            List<Role> roleList = new ArrayList<>();
            roleList.add(role2);
            roleList.add(role2);
            
            roleMapper.insertBatch(roleList);
            System.out.println("insert finished");
            sqlSession.commit();

 

文章评论

程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
那些争议最大的编程观点
那些争议最大的编程观点
一个程序员的时间管理
一个程序员的时间管理
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
编程语言是女人
编程语言是女人
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
程序员和编码员之间的区别
程序员和编码员之间的区别
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
程序员应该关注的一些事儿
程序员应该关注的一些事儿
程序员都该阅读的书
程序员都该阅读的书
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
为什么程序员都是夜猫子
为什么程序员都是夜猫子
每天工作4小时的程序员
每天工作4小时的程序员
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
中美印日四国程序员比较
中美印日四国程序员比较
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
代码女神横空出世
代码女神横空出世
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
鲜为人知的编程真相
鲜为人知的编程真相
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
程序员的鄙视链
程序员的鄙视链
我是如何打败拖延症的
我是如何打败拖延症的
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
漫画:程序员的工作
漫画:程序员的工作
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
Java程序员必看电影
Java程序员必看电影
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
程序员必看的十大电影
程序员必看的十大电影
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
我的丈夫是个程序员
我的丈夫是个程序员
10个调试和排错的小建议
10个调试和排错的小建议
总结2014中国互联网十大段子
总结2014中国互联网十大段子
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
如何成为一名黑客
如何成为一名黑客
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有