美文网首页
MyBatis入门

MyBatis入门

作者: 磊_5d71 | 来源:发表于2018-10-14 10:09 被阅读0次

ORM模型简介

ORM:对象关系映射
O代表java中的对象,R代表数据库中的表,映射值Java实体类对象与数据库表的对应关系。


图片.png

MyBatis概述

Mybatis是支持定制化SQL、存储过程以及高级映射的优秀的持久层框架。

Mybatis使用场景

  • 更加关注SQL优化的项目(对生产环境进行sql语句优化)

  • 需求频繁更新改动的项目
    [图片上传失败...(image-110ecf-1539229088607)]

  • 案例

  • 创建mybatis.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>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <!--使用数据库连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///mytest"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <!--映射配置文件的路径-->
    <mappers>
        <!--<mapper resource="org/mybatis/example/BlogMapper.xml"/>-->
        <mapper resource="mapper/usersMapper.xml"></mapper>
    </mappers>
</configuration>
  • 创建具体实现的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">

<!--namespace命名空间
    通常情况下,命名空间的值,就是当前操作实体类的全名称(也可以设置为其他的名称)
-->
<mapper namespace="com.alan.entity.Users">
<!--id设置名称 resultType一定是实体类的全名称-->
<select id="userlist" resultType="com.alan.entity.Users">
        select  * from users
    </select>

</mapper>
  • 测试类 完成查询测试
import com.alan.entity.Users;
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 java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class TestDemo {

    /**
     * 通过junit进行单元测试
     */
    @Test
    public void testDemo1() throws IOException {

        //初始化mybatis配置环境
        String resource = "mybatis.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //打开和数据库之间的会话
        SqlSession sqlSession = sqlSessionFactory.openSession();

        //进行数据库操作 对应usersMapper.xml中配置的select中的id名称
        List<Users> usersList = sqlSession.selectList("userlist");

        for(Users users:usersList){
            System.out.println(users);
        }

        //关闭会话
        sqlSession.close();
    }
}
图片.png 图片.png

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配置,用户加载外部的properties配置文件
    resource配置具体的properties外部文件
    ${driver}用这种方式进行赋值
    -->
    <properties resource="db.properties" ></properties>

    <!--
        environments 主要用于数据源的配置
        可以配置多个数据源:例如测试,验证、生成等环境。
        default中配置的是当前选中的数据源
    -->
    <environments default="development">
        <!--
          environment 用户配置一个具体的独立的数据源
         id属性用于给当前数据源定义一个名称,方便我们的项目指定
        -->
        <environment id="development">
            <!--
                transactionManager用于配置事务管理,默认情况下使用的是JDBC事务管理
            -->
            <transactionManager type="JDBC"/>
            <!--
                dataSource具体数据源的链接信息:type属性用于指定是否使用连接池,POOLED代表使用连接池
            -->
            <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>
        <environment id="product">
            <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>
        <environment id="test">
            <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>

    <!--mapper主要用户配置外部的映射配置文件-->
    <mappers>
        <!--主要配置引入一个具体的配置文件,通过resource进行路径方式引入-->
        <mapper resource="mapper/usersMapper.xml"/>
    </mappers>
</configuration>

-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属性用来配置命名空间,主要进行session级别的缓存管理
    命名空间默认情况下,使用我们当前操作的实体类的全路径
-->
<mapper namespace="com.alan.entity.Users">
    <select id="findUsers" resultType="com.alan.entity.Users">
          select  * from users
          <if test="id != null">
              where id = #{id}
          </if>
    </select>


    <!--使用SQL动态语句实现-->
    <!--<select id="findById" resultType="com.alan.entity.Users">-->
        <!--select * from users where id = #{id}-->
    <!--</select>-->
</mapper>

resultMap配置

<?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属性用来配置命名空间,主要进行session级别的缓存管理
    命名空间默认情况下,使用我们当前操作的实体类的全路径
-->
<mapper namespace="com.alan.entity.Users">
    <!--<select id="findUsers" resultType="com.alan.entity.Users">-->
    <select id="findUsers" resultMap="forUsers">
          select  * from users
          <if test="id != null">
              where id = #{id}
          </if>
    </select>

    <!--自定义映射集合 主要包含对于一些自定义的操作配置,如不一致的属性和字段-->
    <resultMap id="forUsers" type="com.alan.entity.Users">
        <!--column数据库中的字段对应property实体类中的属性-->
        <result column="username" property="name"></result>
    </resultMap>


    <!--使用SQL动态语句实现-->
    <!--<select id="findById" resultType="com.alan.entity.Users">-->
        <!--select * from users where id = #{id}-->
    <!--</select>-->
</mapper>

log4j在mybatis中的使用

log.info 实现的效果和system.out.println()是一样的,但是开发的时候还是用日志,因为System.out.println输出的内容不能保存到文件中,只能在控制台上显示。

  • 在resources目录下配置log4j
#采用DEBUG模式,并增加日志源A1  配置为INFO DEBUG级别日志就不会输出了。
log4j.rootLogger=INFO, A1
# 在控制台进行输出
log4j.appender.A1=org.apache.log4j.ConsoleAppender
#使用固定的格式
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
#格式的具体设置
log4j.appender.A1.layout.ConversionPattern=%-4r %-5p [%t] %37c %3x - %m%n

  • 自动在控制台打印日志信息


    图片.png
  • 在类中具体使用方法

package com.alan.servlet;

import com.alan.dao.UsersDAO;
import com.alan.entity.Users;
import org.apache.log4j.Logger;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/detail")
public class UsersFindByIdServlet extends HttpServlet {

    /**
     * 创建对应的日志记录对象
     * 通过不同级别进行日志的记录【DEBUG\WARN\INFO\LOG】
     */
    private Logger log = Logger.getLogger(UsersFindByIdServlet.class);

    private UsersDAO usersDAO = new UsersDAO();

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String id  = request.getParameter("id");

        log.info("获取到查询参数id:"+id);

        Users user = usersDAO.findById(Integer.parseInt(id));

        request.setAttribute("user",user);

        log.info("查询数据完成,查询到的数据:"+user);

        request.getRequestDispatcher("detail.jsp").forward(request,response);


    }
}
  • 控制台数据输出


    图片.png

SQL片段动态语句,当sql语句太长的时候通过这种方式配置

    <sql id="user_fields">
        username,userpass,nickname,age,gender,email,phone,createTime,updateTime,lastLogin,userStatus,remark
    </sql>
    
    
    
    <!--keyProperty配置是自动生成主键放入表中的id字段中-->
    <insert id="addUser" useGeneratedKeys="true" keyProperty="id">
--         insert into users(username,userpass,nickname,age,gender,email,phone,createTime,updateTime,lastLogin,userStatus,remark)
        insert into users(<include refid="user_fields"></include>)
        values (#{name},#{userpass},#{nickname},#{age},#{gender},#{email},#{phone},#{createTime},#{updateTime},#{lastLogin},#{userStatus},#{remark})
    </insert>

set动态语句配置

    <update id="updateUser">
        update users
        <set>
            <if test="name != null">username = #{name},</if>
            <if test="userpass != null">userpass = #{userpass},</if>
            <if test="nickname != null">nickname = #{nickname},</if>
            <if test="age != null">age = #{age},</if>
            <if test="gender != null">gender = #{gender},</if>
            <if test="email != null">email = #{email},</if>
            <if test="phone != null">phone = #{phone},</if>
            <if test="createTime != null">createTime = #{createTime},</if>
            <if test="updateTime != null">updateTime = #{updateTime},</if>
            <if test="lastLogin != null">lastLogin = #{lastLogin},</if>
            <if test="userStatus != null">userStatus = #{userStatus},</if>
            <if test="remark != null">remark = #{remark},</if>
        </set>
        where id = #{id}
    </update>

蛋糕商城项目

包括三个模块common、site、management

  • common模块包括
    1、mybatis配置
    2、公共类
    3、Maven依赖
    4、filter配置(解决乱码问题)

配置pom.xml 添加依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>MybatisCakeProj</artifactId>
        <groupId>com.alan</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>MybatisCakeProj-common</artifactId>
    <packaging>jar</packaging>


    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.6</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.12</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

    </dependencies>

</project>
图片.png

通过注解方式配置

-cakeMapper

package com.alan.cake.mapper;

import com.alan.cake.entity.Cake;
import org.apache.ibatis.annotations.*;

import java.util.List;

/**
 * 蛋糕mapper (相当于DAO了)
 */
public interface CakeMapper {



    //通过results解决数据库字段名称与实体类属性名称不一致的问题。其中id = true 这行代表是主键
    // @Result 前面是数据库字段,后面为实体类属性名称
    /**
     * 分页查询蛋糕
     * @param skip 跳过对记录数,也就是从哪条开始查询
     * @param size 每页条数
     * @return 蛋糕List集合
     */
    @Select("select * from cake order by create_time desc limit #{skip},#{size}")
    @Results({
                @Result(id = true, column = "id" , property = "id"),
                @Result(column = "category_id" , property = "categoryId"),
                @Result(column = "name" , property = "name"),
                @Result(column = "level" , property = "level"),
                @Result(column = "price" , property = "price"),
                @Result(column = "create_time" , property = "createTime"),
                @Result(column = "update_time" , property = "updateTime"),
    })
    List<Cake> getCakes(@Param("skip") Integer skip, @Param("size") Integer size);


    /**
     * 根据分类ID查询蛋糕
     * @param categoryId 分类ID
     * @param skip 页码
     * @param size 每页条数
     * @return  蛋糕List集合
     */
    @Select("select * from cake where category_id = #{categoryId} order by create_time desc limit #{skip}, #{size}")
    @Results({
            @Result(id = true, column = "id" , property = "id"),
            @Result(column = "category_id" , property = "categoryId"),
            @Result(column = "name" , property = "name"),
            @Result(column = "level" , property = "level"),
            @Result(column = "price" , property = "price"),
            @Result(column = "create_time" , property = "createTime"),
            @Result(column = "update_time" , property = "updateTime"),
    })
    //多个参数时,需要对参数加上注解
    List<Cake> getCakesByCategoryId(@Param("categoryId") Long categoryId , @Param("skip") Integer skip , @Param("size") Integer size);

    /**
     * 根据分类ID查询总条数
     * @param categoryId 分类ID
     * @return 总共的条数
     */
    @Select("select count(*) from cake where category_id = #{categoryId}")
    int countCakesByCategoryId( Long categoryId);


    /**
     * 添加蛋糕信息
     * @param cake 蛋糕实体类
     */
    @Insert("insert into cake(category_id,name,level,price,small_img,create_time,update_time)" +
            "value (#{cake.categoryId} ,#{cake.name},#{cake.level},#{cake.price},#{cake.smallImg},#{cake.createTime},#{cake.updateTime})")
    void addCake(@Param("cake") Cake cake);


    /**
     * 返回蛋糕图片
     * @param id 蛋糕id
     * @return
     */
    @Select("select small_img smallImg from cake where id = #{id} for update")
    Cake getImg(Long id);


}
  • CategoryMapper
package com.alan.cake.mapper;

import com.alan.cake.entity.Category;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;

import java.util.List;

/**
 * 分类mapper
 */
public interface CategoryMapper {

    //这里面的注解配置对应mybatis XML的配置

    //数据库中的字段名称为create_time update_time,而实例类中为createTime updateTime,这里面查询通过别名方式
    @Select("select id ,name, create_time createTime , update_time updateTime from category")
    List<Category> getCategories();

    /**
     * 根据ID删除具体分类
     * @param id 要删除的分类ID
     */
    @Delete("delete from category where id = #{id}")
    void deleteById(Long id);

    /**
     * 增加分类
     * @param category 分类实体类
     */
    @Insert("insert into category(name,create_time,update_time) values(#{name},#{createTime},#{updateTime})")
    void addCategory(Category category);
}
  • CakeService
package com.alan.cake.service;


import com.alan.cake.common.MyBatisUtils;
import com.alan.cake.entity.Cake;
import com.alan.cake.mapper.CakeMapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.session.SqlSession;

import java.util.Date;
import java.util.List;

public class CakeService {


    /**
     * 根据分类ID查询蛋糕
     * @param categoryId 分类ID
     * @param page 页码
     * @param size 每页条数
     * @return  蛋糕List集合
     */
    public List<Cake> getCakesByCategoryId( Long categoryId , Integer page , Integer size){
        SqlSession sqlSession = MyBatisUtils.oppenSqlSession();
        try {
            CakeMapper cakeMapper = sqlSession.getMapper(CakeMapper.class);
            return cakeMapper.getCakesByCategoryId(categoryId,(page-1)*size,size);
        } finally {
            sqlSession.close();
        }
    }


    /**
     * 添加蛋糕信息
     * @param cake 蛋糕实体类
     */
    public void addCake(Cake cake){
        Date now = new Date();
        cake.setCreateTime(now);
        cake.setUpdateTime(now);
        SqlSession sqlSession = MyBatisUtils.oppenSqlSession();
        try {
            CakeMapper mapper = sqlSession.getMapper(CakeMapper.class);
            mapper.addCake(cake);
            //注意:这里需要commit
            sqlSession.commit();
        } finally {
            sqlSession.close();
        }
    }


    /**
     * 根据分类ID查询总条数
     * @param categoryId 分类ID
     * @return 总共的条数
     */
    public int countCakesByCategoryId( Long categoryId){
        SqlSession sqlSession = MyBatisUtils.oppenSqlSession();
        try {
            CakeMapper mapper = sqlSession.getMapper(CakeMapper.class);
            return  mapper.countCakesByCategoryId(categoryId);
        } finally {
            sqlSession.close();
        }
    }



    /**
     * 返回蛋糕图片
     * @param id 蛋糕id
     * @return
     */
    public Cake getImg(Long id){
        SqlSession sqlSession = MyBatisUtils.oppenSqlSession();
        try {
            CakeMapper mapper = sqlSession.getMapper(CakeMapper.class);
            return  mapper.getImg(id);
        } finally {
            sqlSession.close();
        }

    }
}
  • CategoryService
package com.alan.cake.service;

import com.alan.cake.common.MyBatisUtils;
import com.alan.cake.entity.Category;
import com.alan.cake.mapper.CategoryMapper;
import org.apache.ibatis.session.SqlSession;

import java.util.Date;
import java.util.List;

public class CategoryService {

    /**
     * 返回所有分类信息
     * @return
     */
    public List<Category> getCategories(){
        SqlSession sqlSession = MyBatisUtils.oppenSqlSession();
        try {
            //CakeMapper.class获取类CakeMapper的Class类的对象。然后通过sqlSesson的getMapper方法获取到CakeMapper的对象。这个是MyBatis中通过SqlSession获取mapper对象的方式
            CategoryMapper mapper = sqlSession.getMapper(CategoryMapper.class);
            return  mapper.getCategories();
        } finally {
            sqlSession.close();
        }
    }


    /**
     * 增加分类
     * @param category 分类实体类
     */
     public  void addCategory(Category category){
         Date now = new Date();
         category.setCreateTime(now);
         category.setUpdateTime(now);
         SqlSession sqlSession = MyBatisUtils.oppenSqlSession();

         try {
             CategoryMapper mapper = sqlSession.getMapper(CategoryMapper.class);
             mapper.addCategory(category);
             sqlSession.commit();
         } finally {
             sqlSession.close();
         }

     }


}
  • MyBatisUtils.java
package com.alan.cake.common;

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;

/**
 * MyBatis工具类
 */
public class MyBatisUtils {
    private static final String resource =  "config.xml";
    private static  SqlSessionFactory sqlSessionFactory;
    static {
        try {
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static SqlSession oppenSqlSession(){
        return  sqlSessionFactory.openSession();
    }
}

相关文章

  • MyBatis

    MyBatis学习总结(一)——MyBatis快速入门 超详细MyBatis入门讲解

  • 深入浅出Mybatis-Mybatis-Generator

    目录 入门 Mybatis Generator 是什么 Mybatis Generator是Mybatis的代码生...

  • Mybatis的入门

    一.Mybatis介绍 二.Mybatis的架构 三.Mybatis入门程序开发 下载mybatis 导包核心+依...

  • Mybatis快速入门

    Mybatis 学习内容 Mybatis框架的简单入门 Mybatis框架基本的使用 Mybatis框架的深入和多...

  • MyBatis之快速入门

    title: MyBatis之快速入门tags: MyBatiscategories: MyBatis 若图片无法...

  • 1.Mybatis - 搭建

    参考 Mybatis 官方 MyBatis学习总结(一)——MyBatis快速入门 安装 说明基于Maven 步骤...

  • Intellij 第三章 测试Spring整合MyBatis

    0、如需查看Spring整合MyBatis知识请访问 MyBatis入门【十二】 Spring整合MyBatis基...

  • Mybatis源码解读

    Mybatis入门 Mybatis构成 SqlSessionFactoryBuilder(构造器):根据配置信息或...

  • Mybatis入门

    目的:入门,熟悉mybatis是什么,怎么用。 1. 初识Mybatis 1.1 Mybatis介绍 MyBati...

  • MyBatis入门 Day10 2018-11-28

    MyBatis mybatis-3.4.6 jdk1.8+ 一、mybatis入门 1.依赖jar包 pom.xm...

网友评论

      本文标题:MyBatis入门

      本文链接:https://www.haomeiwen.com/subject/gjsmaftx.html