Mybatis入门学习一

简介

什么是mybatis:mybatis是一款优秀的持久层框架,支持定制化SQL、存储过程以及高级映射,避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。Mybatis可以使用简单的XML或者注解来配置和映射原生类型、接口和Java的POJO为数据库中的记录。

mybatis开始

先去mybatis官网点了这里

第一步:引入maven

<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>x.x.x</version>
</dependency>

第二步:Building SqlSessionFactory from XML(搭建SqlSessionFactory环境):

<?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="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
    <mapper resource="org/mybatis/example/BlogMapper.xml"/>
  </mappers>
</configuration>

编写的工具类:
官网中要求必须在类中引入:
String resource = “org/mybatis/example/mybatis-config.xml”;
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory =
new SqlSessionFactoryBuilder().build(inputStream);
这是通过Builder获得SqlSessionFactory的方式。
工具类:

package com.mao.utils;

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 java.io.IOException;
import java.io.InputStream;

//sqlSessionFactory --> sqlSession
public class MybatisUtil {

    private static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            String resource = "mybatis.config.xml";
            InputStream inputStream = null;
            inputStream = Resources.getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory =
                    new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //既然有了SqlsessionFactory,顾名思义,我们可以从中得到SqlSession实例.
    //SqlSession包含了面向数据库执行SQL命令所需要的方法
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }

}

写一个实体类映射数据库中的表:

package com.mao.pojo;

import lombok.Data;

@Data
public class User {

    private int id;
    private String username;
    private String password;
}

有了实体类就可以去定义一个数据访问层接口:

package com.mao.dao;

import com.mao.pojo.User;

public interface UserDao {

    User getUser(Integer id);
}

其具体的实体类并不用写,而是通过指定的mapper配置文件来实现即可:

<?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="com.mao.dao.UserDao">
    <select id="getUser" resultType="com.mao.pojo.User">
    select * from user where id = #{id}
  </select>
</mapper>

注意:这里要指定mapper的命名空间,即是所对应的接口,select标签中的id对应指定的方法名,resultType就是返回值。

注意:当sqlSession用完的时候应当关闭,否则会造成内存的浪费。

CRUD

1.namespace

namespace中的包名要和Dao/Mapper中的接口的包名一致。

UserDao接口

package com.mao.dao;

import com.mao.pojo.User;

import java.util.List;


public interface UserDao {
    /**
     * 通过id返回User
     * @param id
     * @return
     */
    User getUserById(Integer id);

    /**
     * 返回所有User
     * @return
     */
    List<User> getUserList();

    /**
     * 添加用户
     * @param user
     * @return
     */
    int addUser(User user);

    /**
     * 更新用户
     * @param user
     * @return
     */
    int updateUser(User user);
    /**
     * 删除指定用户
     * @param id
     * @return
     */
    int deleteUser(int id);
}

UserMapper.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="com.mao.dao.UserDao">
    <select id="getUserById" resultType="com.mao.pojo.User">
    select * from user where id = #{id}
    </select>
    <select id="getUserList" resultType="com.mao.pojo.User">
        select * from study.user
    </select>
    <insert id="addUser" parameterType="com.mao.pojo.User">
        insert into study.user(id,username,password) values (#{id},#{username},#{password})
    </insert>
    <update id="updateUser" parameterType="com.mao.pojo.User">
        update study.user set username=#{username},password=#{password} where id=#{id}
    </update>
    <delete id="deleteUser">
        delete from study.user where id=#{id}
    </delete>
</mapper>

Junit测试

package com.mao.dao;

import com.mao.pojo.User;
import com.mao.utils.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

import static org.junit.Assert.*;

public class UserDaoTest {

    @Test
    public void getUserById() {
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        try {
            UserDao userDao = sqlSession.getMapper(UserDao.class);
            User user = userDao.getUserById(1);
            System.out.println(user);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            sqlSession.close();
        }
    }

    @Test
    public void getUserList() {
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        try {
            UserDao userDao = sqlSession.getMapper(UserDao.class);
            List<User> userList = userDao.getUserList();
            System.out.println(userList);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
    }

    @Test
    public void addUser() {
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        try {
            User user = new User();
            user.setId(4);
            user.setUsername("张天伟");
            user.setPassword("123456");
            UserDao userDao = sqlSession.getMapper(UserDao.class);
            int i = userDao.addUser(user);
            System.out.println(i);
            //这一步很关键,增删改等DML是需要提交事务的
            sqlSession.commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
    }

    @Test
    public void updateUser() {
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        try {
            User user = new User();
            user.setId(4);
            user.setUsername("张地瓜");
            user.setPassword("438");
            UserDao userDao = sqlSession.getMapper(UserDao.class);
            int i = userDao.updateUser(user);
            sqlSession.commit();
            System.out.println(i);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
    }
    @Test
    public void deleteUser(){
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        try {
            UserDao mapper = sqlSession.getMapper(UserDao.class);
            int i = mapper.deleteUser(3);
            sqlSession.commit();
            System.out.println(i);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sqlSession.close();
        }
    }
}

注意

注意,要知道mysql是支持事务的,所以增删改等DML语句需要在操作完成时提交一下事务,否则会因为事务的ACID特性导致操作未显示。

万能的Map

在mybatis中使用Map的时候只需要再接口中使用Map,而在xxMapper.xml中parameterType指定为map,就可以像一个对象一样去使用它了。注:
1.使用Map中的参数,直接在sql中取其key即可【parameterType=map】
2.使用对象中的属性,直接在sql中取其属性即可【parameterType=Object】
只有一个基本类型的时候直接取该基本类型即可,多个的话就要用到map,
或者用注解,用上述的getUserById来演示一下:

Dao层接口代码:

/**
     * 用Map来演示
     * @param map
     * @return
     */
    int getUserById2(Map<String,Object> map);

xxMapper.xml:

<select id="getUserById2" parameterType="map">
     select * from user where id = #{id}
</select>

junit:

@Test
    public void getUserById2() {
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        try {
            UserDao userDao = sqlSession.getMapper(UserDao.class);
            HashMap<String, Object> map = new HashMap<String, Object>();
            map.put("id",1);
            User user = userDao.getUserById(1);
            System.out.println(user);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            sqlSession.close();
        }
    }

输出结果:
在这里插入图片描述

注意

这里有两个注意点:
1.一般公司里如果用xml配置方式的话普遍推荐使用map,因为那时候将会遇到有很多属性的类,用map显然在灵活性上比对象更好操作
2.mybatis中是以方法名为id的,所以同一个Mapper是不支持重载的,这也是为什么我在上面中要将方法的名字改为getUserById2

Mybatis的配置优化

  • configuration(配置)
  • properties(属性):这些属性都是可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过 properties 元素的子元素来传递。相当于可以读取配置文件的值,还可以在其中设置值,如果存在和外部文件相同的值,优先取外部的值
  • settings(设置):对一些属性进行配置
  • typeAliases(类型别名):设置别名,可以减少包名的输入,增加开发效率。可以给包起别名,也可以给类取别名:下面是给类取别人
<typeAliases>
  <typeAlias alias="Author" type="domain.blog.Author"/>
  <typeAlias alias="Blog" type="domain.blog.Blog"/>
  <typeAlias alias="Comment" type="domain.blog.Comment"/>
  <typeAlias alias="Post" type="domain.blog.Post"/>
  <typeAlias alias="Section" type="domain.blog.Section"/>
  <typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>

给包取别名:

<typeAliases>
  <package name="domain.blog"/>
</typeAliases>

每一个在包 domain.blog 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如 domain.blog.Author 的别名为 author;若有注解,则别名为其注解值。
注意:如果实体类比较少推荐用第一种,如果比较多用第二种。第一种可以在配置中取别名,第二种不行,不过可以用注解来取别名。

@Alias("author")
public class Author {
    ...
}

如果同一个类注解和配置中都有,优先取注解。

  • typeHandlers(类型处理器):无需太了解
  • objectFactory(对象工厂):无需太了解
  • plugins(插件):无需太了解
  • environments(环境配置)
  • environment(环境变量)
  • transactionManager(事务管理器):分位jdbc和manager,服务于ejb,如果用spring完全不用配置。
  • dataSource(数据源):连接数据库所用,POOLED和UNPOOLED,有池和无池,如果是POOLED就在用完之后不会销毁,而是放回POOLED。
  • databaseIdProvider(数据库厂商标识)
  • mappers(映射器):注册绑定我们配置的mapper.xml文件

resultMap的引用

我们在开发中可能会遇到这样的一种情况,就是数据库中的表字段和对应实体类的属性名不一致,这时候查询就会发现该属性本来应该有值却没有,比如我把上面那对象中的User对象的password改为psd,再做一次查询得到:
在这里插入图片描述
这时候就要用到,resultMap了,该属性就是可以实现把数据库中的列名和属性名做一个映射的效果。

代码:

<mapper namespace="com.mao.dao.UserDao">
    <resultMap id="userMap" type="user">
        <result column="password" property="psd"></result>
    </resultMap>
    
    <select id="getUserById" resultType="user" resultMap="userMap">
        select * from user where id = #{id}
    </select>
</mapper>

实现效果:
在这里插入图片描述

发布了37 篇原创文章 · 获赞 10 · 访问量 746

猜你喜欢

转载自blog.csdn.net/weixin_41746577/article/details/103328963