mybatis从0到1

20 篇文章 0 订阅
2 篇文章 0 订阅

mybatis介绍

mybatis是一个简化java操作数据的操作的,简化开发,增加小路的框架(JDBC的封装)

依赖的引入

主要是mybatis的依赖和mysql数据的依赖,本次测试是使用的mysql数据库

        <!-- mybatis的依赖 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.1</version>
        </dependency>

        <!-- mysql驱动的依赖 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
        </dependency>
        <!-- 单元测试可以不加入 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

配置数据库连接

在resouces目录里面创建mybatis-config.xml文件,里面用来配置数据库的链接数据文件内容如下:里面的具体配置需要自己进行修改,主要是driver url username password对应的value。

<?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>
    <!-- 给类起别名 -->
    <typeAliases>
        <typeAlias type="cn.pengpeng.domain.Order" alias="_Order"/>
    </typeAliases>
    <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/mybatis?characterEncoding=utf-8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!-- map映射文件 -->
    <mappers>
        <mapper resource="UserMapper.xml" />
        <mapper resource="OrderMapper.xml" />
    </mappers>
</configuration>

配置完后可以测试下,使用一下代码用来测试mybatis链接数据库

public class App {
    public static void main(String[] args) {

        try {
            //指定配置文件的路径(类路径)
            String resource = "mybatis-config.xml";
            //加载文件
            InputStream resourceAsStream = Resources.getResourceAsStream(resource);
            //创建会话工厂Builder,相当于连接池
            SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(resourceAsStream);
            //通过sf开启会话,相当于打开连接。
            SqlSession s = sf.openSession();
            //输出测试是否有异常
            System.out.println(s);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

单表的增删改查

创建数据库

mysql>create database mybatis ;
mysql>use mybatis ;
mysql>create table users(id int primary key auto_increment , name varchar(20) ,age int) ;

创建users表对应的javabean

package cn.pengpeng.domain;

import java.util.List;

/**
 * Created by root on 2018/12/25.
 */
public class User {
        private int id;
        private String name;
        private int age;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

创建Users.java跟数据库映射文件

创建UserMapper.xml,存放在resources/目录下

<?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="users">
				<!-- 定义insert语句 -->
				<insert id="insert">
				  insert into users(name,age) values(#{name},#{age})
				</insert>
			</mapper>

测试是否可用

package cn.pengpeng;

import cn.pengpeng.domain.User;
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;

/**
 * 测试javabean跟数据库的联通性,
 * 具体的sql是UserMapper.xml里面的写的
 */
public class App {
    public static void main(String[] args) {
        try {
            //指定配置文件的路径(类路径)
            String resource = "mybatis-config.xml";
            //加载文件
            InputStream resourceAsStream = Resources.getResourceAsStream(resource);
            //创建会话工厂Builder,相当于连接池
            SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(resourceAsStream);
            //通过sf开启会话,相当于打开连接。
            SqlSession s = sf.openSession();

            User u = new User();
            u.setName("明明");
            u.setAge(3);
            // users 是UserMapper.xml里面的   namespace="users"     insert 是<insert id="insert" >
            s.insert("users.insert",u);
            s.commit();
            s.close();
            System.out.println(s);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

运行后可以去数据库里面查看下,是否有数据插入,插入数据说明是可行的。

多表关联数据测试

创建表

创建三张表,items,orders,users表,并且给三张表进行插入数据。
表关系为:一个users会有多个orders,一个orders又会有多个items

use mybatis ;
-- 删除表
drop table if exists  items ;
drop table if exists  orders ;
drop table if exists  users ;

-- 创建表
create table users(id int primary key auto_increment , name varchar(20) , age int);
create table orders(id int primary key auto_increment , orderno varchar(20) , uid int);
create table items(id int primary key auto_increment , itemname varchar(20) , oid int);

-- 插入用户
insert into users(name,age) values('tom',12);
insert into users(name,age) values('tomas',13);

-- 插入订单
insert into orders(orderno,uid) values('No001',1);
insert into orders(orderno,uid) values('No002',1);
insert into orders(orderno,uid) values('No003',2);
insert into orders(orderno,uid) values('No004',2);

-- 插入订单项
insert into items(itemname,oid) values('item001',1);
insert into items(itemname,oid) values('item002',1);
insert into items(itemname,oid) values('item003',2);
insert into items(itemname,oid) values('item004',2);
insert into items(itemname,oid) values('item005',3);
insert into items(itemname,oid) values('item006',3);
insert into items(itemname,oid) values('item007',4);
insert into items(itemname,oid) values('item008',5);

select * from users ;
select * from orders ;
select * from items ;

创建数据库对应的javabean

users表对应的javabean

package cn.pengpeng.domain;

import java.util.List;

/**
 * 这里面需要注意的是 一个user对应多个order,所以这里面使用list来存放,
 * 需要注意UserMapper.xml里面的sql语法
 */
public class User {
        private int id;
        private String name;
        private int age;
        private List<Order> orders;

    public List<Order> getOrders() {
        return orders;
    }

    public void setOrders(List<Order> orders) {
        this.orders = orders;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", orders=" + orders +
                '}';
    }
}

表orders对应的javabean

package cn.pengpeng.domain;

/**
 * 这一需要注意的是数据库里面存储的是userid,这里面直接转换成user对象的,
 * 需要注意OrderMapper.xml里面的写法
 */
public class Order {
    private int id;
    private String orderNo;
    private User user;

    @Override
    public String toString() {
        return "Order{" +
                "id=" + id +
                ", orderNo='" + orderNo + '\'' +
                ", user=" + user +
                '}';
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getOrderNo() {
        return orderNo;
    }

    public void setOrderNo(String orderNo) {
        this.orderNo = orderNo;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
}

建立数据库跟javabean的映射关系

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="users">
        <!-- 插入数据 -->
        <insert id="insert" >
            insert into users(name,age) values(#{name},#{age})
        </insert>
        <!-- 更新操作 -->
        <update id="update" >
            update users set name = #{name} ,age = #{age} where id = #{id}
        </update>
        <!-- 根据id查询数据 这个没有使用关联查询,不能查出来表之外的数据-->
        <select id="selectOne" parameterType="int" resultType="cn.pengpeng.domain.User">
            select * from users where id = #{id}
        </select>
        <!-- 查询出来说有的数据 -->
        <select id="selectAll" resultType="cn.pengpeng.domain.User">
            select * from users
        </select>

        <!-- 多表关联的时候 一对多的时候进行配置 这个是多表关联的重点 -->
        <select id="findById" parameterType="int" resultMap="RM_user">
          select
            u.id uid,
            u.name uname,
            u.age uage,
            o.id oid,
            o.orderno oorderno
          from users u
            left outer join orders o on u.id = o.uid
            where u.id = #{id}
        </select>
        <!-- 结果是比较复杂的,需要自己去定义映射关系 -->
        <resultMap id="RM_user" type="cn.pengpeng.domain.User">
            <id property="id" column="uid"/>
            <result property="name" column="uname"/>
            <result property="age" column="uage"/>
            <!-- 映射一对多关联关系 -->
            <collection property="orders" ofType="cn.pengpeng.domain.Order">
                <id property="id" column="oid" />
                <result property="orderNo" column="oorderno"/>
            </collection>
        </resultMap>

        <!-- 查询所有的selectAll -->
        <select id="findAll" resultMap="RM_user">
            SELECT
              u.id uid,
              u.name uname,
              u.age uage,
              o.id oid,
              o.orderno oorderno
            FROM users u
              left outer JOIN orders o on u.id = o.uid
        </select>
    </mapper>

Orders表跟Order java类进行映射文件 OrderMapper.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="orders">
    <insert id="insert" >
        insert into orders(orderno,uid) values(#{orderNo},#{user.id})
    </insert>

    <!-- 返回中是属于类嵌套类的形式 -->
    <select id="selectOne" parameterType="int" resultMap="RM_order">
        select
          o.id oid,
          o.orderno oorderno,
          o.uid uid,
          u.name uname,
          u.age uage
        from orders o
          left outer join users u on o.id = u.id where o.id = #{id}
    </select>

    <!-- 自定义结果对象 -->
    <resultMap id="RM_order" type="cn.pengpeng.domain.Order">
        <id property="id" column="oid"/>
        <result property="orderNo" column="ooderno"/>
        <association property="user" javaType="cn.pengpeng.domain.User">
            <id property="id" column="uid"/>
            <result property="name" column="uname"/>
            <result property="age" column="uage"/>
        </association>
    </resultMap>

    <!-- 多个查询 -->
    <select id="selectAll" parameterType="int" resultMap="RM_order">
        select
          o.id oid,
          o.orderno oorderno,
          o.uid uid,
          u.name uname,
          u.age uage
        from orders o
          left outer join users u on o.id = u.id
    </select>
</mapper>

工具类

主要是对session进行的简单的封装

package cn.pengpeng.util;

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.InputStream;

/**
 * 工具类
 */
public class Util {
    static SqlSessionFactory sf =  null;
    static {
        try{
            //指定配置文件的路径(类路径)
            String resource = "mybatis-config.xml";
            //加载文件
            InputStream resourceAsStream = Resources.getResourceAsStream(resource);
            //创建会话工厂Builder,相当于连接池
            sf = new SqlSessionFactoryBuilder().build(resourceAsStream);
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 开启session
     * @return
     */
    public static SqlSession getSession(){
        return sf.openSession();
    }

    /**
     * 关闭session
     */
    public static void closeSeesion(SqlSession s){
        if(s !=null){
            s.close();
        }
    }

    /**
     * 事物回滚
     */
    public static void rollBackTx(SqlSession s){
        if(s!=null){
            s.rollback();
        }
    }
}

编写相对应的dao层

例如user的dao

package cn.pengpeng.dao;

import cn.pengpeng.domain.User;
import cn.pengpeng.util.Util;
import org.apache.ibatis.session.SqlSession;

/**
 * UserDao
 */
public class UserDao {
    /**
     * 插入操作
     */
    public void insert(User user){
        SqlSession s = null;
        try{
            s = Util.getSession();
            s.insert("user.insert",user);
            s.commit();
        }catch (Exception e){
            e.printStackTrace();
            if(s !=null){
                s.rollback();
            }
        }finally {
            if(s !=null){
                s.close();
            }
        }
    }

    public void updata(User user){
        SqlSession s = null;
        try{
            s = Util.getSession();
            s.update("users.update",user);
            s.commit();
        }catch (Exception e){
            e.printStackTrace();
            if(s !=null){
                s.rollback();
            }
        }finally {
            if(s !=null){
                s.close();
            }
        }
    }
}

这样写好dao层就可以对外提供使用了,但是会发现这里面有很多代码是冗余的,所以把相同的代码进行封装(使用接口的形式)。

接口设计(抽取公共代码)

主要是把重复使用的代码进行封装,减少重复的代码
下面是把重复性的代码写上,不同的代码使用接口给丢出去,不用的实现可以实现不同的接口

package cn.pengpeng.dao;

import cn.pengpeng.util.Util;
import org.apache.ibatis.session.SqlSession;

/**
 * 模板类
 */
public class DaoTemplate {
    /**
     * 执行,公共代码
     */
    public static Object execute(MybatisCallback cb){
        SqlSession s = null;
        try{
            s = Util.getSession();
            //中间的不同点 使用接口来实现
            Object ret = cb.doInMyBatis(s);
            //结束,给外面流接口
            s.commit();
            return ret;
        }catch(Exception e){
            Util.rollBackTx(s);
        }finally {
            Util.closeSeesion(s);
        }
        return null;
    }
}

定义接口,不用的操作只需要不用的实现

package cn.pengpeng.dao;

import org.apache.ibatis.session.SqlSession;

/**
 * 回调接口,不同的操作,实现只需要不同的实现就可以了
 */
public interface MybatisCallback {
    Object doInMyBatis(SqlSession s);
}

使用接口设计后的dao实现

使用接口设计后代码简洁了很多

package cn.pengpeng.dao;

import cn.pengpeng.domain.User;
import cn.pengpeng.util.Util;
import org.apache.ibatis.session.SqlSession;

/**
 * UserDao
 */
public class UserDao {
    /**
     * 插入操作
     */
    public void insert(User user){
        DaoTemplate.execute(new MybatisCallback() {
            @Override
            public Object doInMyBatis(SqlSession s) {
                s.insert("users.insert",user);
                return null;
            }
        });
    }
	
	 /**
     * 更新操作 
     */
    public void updata(User user){
        DaoTemplate.execute(new MybatisCallback() {
            @Override
            public Object doInMyBatis(SqlSession s) {
                s.update("users.update",user);
                return null;
            }
        });
    }
}

mybatis就介绍完了,后面还有spring,和springMVC,以及他们之间的整合。
mybatis的代码已经同步到git上
点击下载代码
看文档不给力?还有视频来讲解,提交信息,小姐姐会主动联系你为你奉上视频解答哦。
点我填写资料领取视频

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值