Mybatis使用详解和入门案例(转)

https://blog.csdn.net/qq_32166627/article/details/70741729

前言
MyBatis和Hibernate一样,是一个优秀的持久层框架。已经说过很多次了,原生的jdbc操作存在大量的重复性代码(如注册驱动,创建连接,创建statement,结果集检测等)。框架的作用就是把这些繁琐的代码封装,这样可以让程序员专注于sql语句本身。

MyBatis通过XML或者注解的方式将要执行的sql语句配置起来,并通过java对象和sql语句映射成最终执行的sql语句。最终由MyBatis框架执行sql,并将结果映射成java对象并返回。

正文
一,MyBatis的执行流程

mybatis配置文件,包括Mybatis全局配置文件和Mybatis映射文件,其中全局配置文件配置了数据源、事务等信息;映射文件配置了SQL执行相关的 
信息。
mybatis通过读取配置文件信息(全局配置文件和映射文件),构造出SqlSessionFactory,即会话工厂。
通过SqlSessionFactory,可以创建SqlSession即会话。Mybatis是通过SqlSession来操作数据库的。
SqlSession本身不能直接操作数据库,它是通过底层的Executor执行器接口来操作数据库的。Executor接口有两个实现类,一个是普通执行器,一个是缓存执行器(默认)。
Executor执行器要处理的SQL信息是封装到一个底层对象MappedStatement中。该对象包括:SQL语句、输入参数映射信息、输出结果集映射信息。其中输入参数和输出结果的映射类型包括java的简单类型、HashMap集合对象、POJO对象类型。
二,MyBatis经典入门案例(原始DAO实现用户表的增删改查)

1,环境准备

Jdk环境:jdk1.7.0_72
Ide环境:eclipse indigo
数据库环境:MySQL 5.1
Mybatis:3.2.7
mysql建库:

CREATE TABLE `user4` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(20) ,
  `password` varchar(20) ,
  `age` int(11) ,
  PRIMARY KEY (`id`)
)

项目目录如下: 


下面一一讲解这些文件。

2,全局配置文件:SqlMapConfig.xml

主要是2个标签:

扫描二维码关注公众号,回复: 3729624 查看本文章

environments-用于获取连接池连接,将来与spring整合时,这个就不要啦,由spring来配置数据库连接。

mappers-用于引用映射文件。

<?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>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/user"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="User.xml"/>
    </mappers>
</configuration>

3,创建主体类:User.class

package com.jimmy.domain;

public class User {
    private Integer id;
    private String username;
    private String password;
    private Integer age;
    //get,set方法省略
}

4,创建映射文件:User.xml

映射文件就是框架的核心啦,下面这个文件就配置了java对象与数据库表之间的映射。

我们看到,其中4个标签:select,insert ,delete ,update 分别对应着“查,增,删,改”操作。每个标签中还有一些属性,下面来解释下:

id:给标签体内的sql操作起个名字,方便调用。
parameterType:传入参数的类型。传入java类型,转化为sql类型,添加到sql语句上。
resultType:返回结果类型。sql结果集转化为java类型并返回。
<?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属性,不然会报错,可看做包名-->
<mapper namespace="user">
    <select id="findUserById" parameterType="int" resultType="com.jimmy.domain.User">
        select * from user4 where id = #{id}
    </select>
    <select id="findUserAll" resultType="com.jimmy.domain.User">
        select * from user4 
    </select>
    <insert id="insertUser" parameterType="com.jimmy.domain.User">
        insert into user4(username,password,age) values(#{username},#{password},#{age})
    </insert>
    <delete id="deleteUserById" parameterType="int">
        delete from user4 where id=#{id}
    </delete>
    <update id="updateUserPassword" parameterType="com.jimmy.domain.User">
        update user4 set password=#{password} where id=#{id}
    </update>
</mapper>

5,创建dao接口和实现类

package com.jimmy.dao;

import java.util.List;

import com.jimmy.domain.User;

// 接口
public interface UserDao {  
    public User findUserById(int id) throws Exception ;
    public List<User> findAllUsers() throws Exception;
    public void insertUser(User user) throws Exception;
    public void deleteUserById(int id) throws Exception;
    public void updateUserPassword(User user) throws Exception;
}

package com.jimmy.dao.impl;

import java.io.InputStream;
import java.util.List;

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

import com.jimmy.dao.UserDao;
import com.jimmy.domain.User;

// 实现类
public class UserDaoImpl implements UserDao {

    public User findUserById(int id) throws Exception {
        String resource = "SqlMapConfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = factory.openSession();
        //---------------
        User user = session.selectOne("user.findUserById",id); //参数一:namespace.id           
        //--------------
        session.close();
        return user;
    }

    public List<User> findAllUsers() throws Exception {
        String resource = "SqlMapConfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = factory.openSession();
        //---------------------
        List<User> users = session.selectList("user.findUserAll");
        //----------------------
        session.close();
        return users;
    }

    public void insertUser(User user) throws Exception {
        String resource = "SqlMapConfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = factory.openSession();
        //---------------------
        session.insert("user.insertUser", user);
        session.commit();   //增删改,一定一定要加上commit操作
        //----------------------
        session.close();
    }

    public void deleteUserById(int id) throws Exception {
        String resource = "SqlMapConfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = factory.openSession();
        //---------------------
        session.delete("user.deleteUserById", id);
        session.commit();   //增删改,一定一定要加上commit操作
        //----------------------
        session.close();
    }

    public void updateUserPassword(User user) throws Exception {
        String resource = "SqlMapConfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = factory.openSession();
        //---------------------
        session.update("user.updateUserPassword", user);
        session.commit();   //增删改,一定一定要加上commit操作
        //----------------------
        session.close();
    }
}

6,编写测试类

package com.jimmy.test;

import java.util.List;
import org.junit.Test;
import com.jimmy.dao.UserDao;
import com.jimmy.dao.impl.UserDaoImpl;
import com.jimmy.domain.User;

public class Test3 {
    @Test
    public void testFindUserById() throws Exception{
        UserDao userDao = new UserDaoImpl();
        User user = userDao.findUserById(7);
        System.out.println(user);
    }
    @Test
    public void testFindAllUser() throws Exception{
        UserDao userDao = new UserDaoImpl();
        List<User> findAllUsers = userDao.findAllUsers();
        for (User user2 : findAllUsers) {           
            System.out.println(user2);
        }
    }
    @Test
    public void testInsertUser() throws Exception{
        UserDao userDao = new UserDaoImpl();
        User user = new User();
        user.setUsername("张三");
        user.setPassword("lalal");
        user.setAge(12);
        userDao.insertUser(user);
    }
    @Test
    public void testDeleteUserById() throws Exception{
        UserDao userDao = new UserDaoImpl();
        userDao.deleteUserById(3);
    }
    @Test
    public void testUpdateUserPassword() throws Exception{
        UserDao userDao = new UserDaoImpl();
        User user = new User();
        user.setId(9);
        user.setPassword("newpassword");
        userDao.updateUserPassword(user);
    }
}

至此,一个完整的Mybatis入门案例已经初步完成。

回过头来看DAO的实现类,原始dao开发存在一些问题:

存在一定量的模板代码。比如:通过SqlSessionFactory创建SqlSession;调用SqlSession的方法操作数据库;关闭Sqlsession。
存在一些硬编码。调用SqlSession的方法操作数据库时,需要指定statement的id,这里存在了硬编码。
三,Mapper代理开发模式

Mapper代理的开发方式,程序员只需要编写mapper接口(相当于dao接口)即可,而不同再写dao实现类啦。Mybatis会自动的为mapper接口生成动态代理实现类。不过要实现mapper代理的开发方式,需要遵循一些开发规范。

mapper接口的全限定名要和mapper映射文件的namespace的值相同。
mapper接口的方法名称要和mapper映射文件中的statement的id相同。
mapper接口的方法参数只能有一个,且类型要和mapper映射文件中statement的parameterType的值保持一致。
mapper接口的返回值类型要和mapper映射文件中statement的resultType值或resultMap中的type值保持一致。
上面4句话的意思是:接口的包名,类名,参数,返回值分别对应着映射文件的namespace,id,parameterType,resultType。

下面来改造上面的例子。

1,环境准备,同上。 
2,全局配置文件,同上。记得引用新的映射文件。 
3,创建主题类,同上。 
4,创建映射文件:UserMapper.xml。文件名一般加上“Mapper”。

下面这个文件跟原始dao编程只有一点不同,就是namespace值。

<?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属性,不然会报错,且mapper开发时设置为Mapper接口的全限定名-->
<mapper namespace="com.jimmy.dao.UserMapper">
    <select id="findUserById" parameterType="int" resultType="com.jimmy.domain.User">
        select * from user4 where id = #{id}
    </select>
    <select id="findUserAll" resultType="com.jimmy.domain.User">
        select * from user4 
    </select>
    <insert id="insertUser" parameterType="com.jimmy.domain.User">
        insert into user4(username,password,age) values(#{username},#{password},#{age})
    </insert>
    <delete id="deleteUserById" parameterType="int">
        delete from user4 where id=#{id}
    </delete>
    <update id="updateUserPassword" parameterType="com.jimmy.domain.User">
        update user4 set password=#{password} where id=#{id}
    </update>
</mapper>

5,创建Mapper接口,这里就没有实现类啦。

注意,函数一定要注意4点规范。

package com.jimmy.dao;

import java.util.List;

import com.jimmy.domain.User;

public interface UserMapper {
    public User findUserById(int id);
    public List<User> findUserAll();
    public void insertUser(User user);
    public void deleteUserById(int id);
    public void updateUserPassword(User user);
}

6,编写测试类

package com.jimmy.test;

import java.io.InputStream;
import java.util.List;

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

import com.jimmy.dao.UserMapper;
import com.jimmy.domain.User;

public class Test1 {
    @Test
    public void findUserByID() throws Exception{
        String resource = "SqlMapConfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = factory.openSession();
        //---------------
        UserMapper userMapper = session.getMapper(UserMapper.class);
        User user = userMapper.findUserById(2);
        System.out.println(user);
        //--------------
        session.close();
    }
    @Test
    public void findAll() throws Exception{
        String resource = "SqlMapConfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = factory.openSession();
        //---------------------
        UserMapper mapper = session.getMapper(UserMapper.class);
        List<User> user = mapper.findUserAll();
        for (User user2 : user) {           
            System.out.println(user2);
        }
        //----------------------
        session.close();
    }
    @Test
    public void insertTest() throws Exception{
        String resource = "SqlMapConfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = factory.openSession();
        //---------------------
        User user = new User();
        user.setUsername("lalala");
        user.setPassword("asdf");
        user.setAge(12);

        UserMapper mapper = session.getMapper(UserMapper.class);
        mapper.insertUser(user);
        session.commit();
        //----------------------
        session.close();
    }
    @Test
    public void deleteUserById() throws Exception{
        String resource = "SqlMapConfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = factory.openSession();
        //---------------------
        UserMapper mapper = session.getMapper(UserMapper.class);
        mapper.deleteUserById(2);
        session.commit();
        //----------------------
        session.close();
    }
    @Test
    public void updateUserPassword() throws Exception{
        String resource = "SqlMapConfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = factory.openSession();
        //---------------------
        User user = new User();
        user.setId(4);
        user.setPassword("newPassword3");

        UserMapper mapper = session.getMapper(UserMapper.class);
        mapper.updateUserPassword(user);
        session.commit();
        //----------------------
        session.close();
    }
}

我们看到,现在已经不需要再写dao接口的实现类啦,而是框架通过映射文件为我们生成代理类。而那些重复性的代码已经转移到测试代码中了,我们在整合spring和Mybatis时,这些重复性代码都会在配置文件中配置。
--------------------- 
作者:name_s_Jimmy 
来源:CSDN 
原文:https://blog.csdn.net/qq_32166627/article/details/70741729 
版权声明:本文为博主原创文章,转载请附上博文链接!

猜你喜欢

转载自blog.csdn.net/guogrowth/article/details/83239131