MyBatis入门

一、创建项目

二、导包

核心包
mybatis-3.2.1.jar
依赖包
asm-3.3.1.jar
cglib-2.2.2.jar
commons-logging-1.1.1.jar
javassist-3.17.1-GA.jar
log4j-1.2.17.jar
slf4j-api-1.7.2.jar
slf4j-log4j12-1.7.2.jar
数据库驱动包
mysql-connector-java-5.1.26-bin.jar

三、 准备数据

  • 数据库
    • 建库
    • 建表
    • 插入测试数据
  • 项目
    • 准备domain
    • 准备dao和测试类

四、配置

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文件 -->
    <!--
    resource 默认去classpath中寻找资源
    -->
    <properties resource="jdbc.properties"/>
   <!--
    配置自定义别名
        别名不区分大小写
        一个一个配置:
        typeAlias
            type 类型的完全限定名
            alias 别名
        统一为某个包下的所有类起别名
         package
            name : 包名   别名就是类名(不区分大小写)
    -->
    <typeAliases>
        <package name="cn.yun.mybatis.domain"/>
    </typeAliases>
 <!--
    environments : 环境的集合
        default: 默认使用哪个环境 值为环境的id
    -->
    <environments default="development">
     <!--
        environment : 一个环境,对应一个数据库
             id: 环境的标识
        -->
        <environment id="development">
        <!--
            transactionManager:事务管理器
                type="JDBC" 使用JDBC的事务进行提交和回滚
                type="MANAGED" 它从不提交和回滚,而是让容器进行事务的管理
            -->
            <transactionManager type="JDBC"/>
            <!--
                dataSource : 数据源
                    type="UNPOOLED" 不使用连接池
                    type="POOLED" 使用连接池
                    type="JNDI" 容器中使用
            -->
            <dataSource type="POOLED">
              <!--数据库连接属性-->
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--注册映射文件-->
        <mapper resource="ProductMapper.xml"/>
    </mappers>
</configuration>

jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///mybatis
jdbc.username=root
jdbc.password=root

log4j.properties

#log4j.properties(日志文件:)
log4j.rootLogger=ERROR, stdout
#log4j.rootLogger=NONE
log4j.logger.cn.itsource=TRACE

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p 

ProductMapper.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 : 命名空间
            今天写:domain的完全限定名+Mapper
            domain:cn.itsource.mybatis._01_hello.domain.Product
            namespace:cn.itsource.mybatis._01_hello.domain.ProductMapper

            namespace在老版本中时可以不写的,
            新版本中必须定义namespace属性
-->
<mapper namespace="cn.yun.mybatis.domain.ProductMapper">
 <!--
        select update insert delete :定义sql语句的地方
            id:sql的标识 同一个namespace下不能重复
            resultType:结果的类型
                每一个结果的类型,完全限定名

    -->
    <select id="selectAll" resultType="Product">
        select * from product
    </select>
    
    <!--
        parameterType : 参数类型  完全限定名

        #{id} 等同于?
    -->
    <select id="selectfindOne"
            resultType="Product"
            parameterType="long">
        select * from product where id=#{id}
    </select>
    <!--删除-->
    <delete id="delete" parameterType="long" >
        delete FROM product WHERE  id=#{id}
    </delete>
    <!--添加-->
    <!--Mybatis获取主键:
     *  只需要在insert标签中添加几个属性
     *  useGeneratedKeys = "true"
     *  keyColumn  表中的主键列列名 - 可以省略
     *  keyProperty  domain中主键对应的成员变量-->

    <insert id="inertSave" parameterType="Product" useGeneratedKeys="true" keyProperty="id">
      INSERT INTO product(productName, dir_id,salePrice, supplier, brand,cutoff, costPrice)
      VALUES (#{productName},#{dir_id},#{salePrice},#{supplier},#{brand},#{cutoff},#{costPrice})
    </insert>
    <update id="update" parameterType="product">
        UPDATE product set productName=#{productName},dir_id=#{dir_id},salePrice=#{salePrice},
        supplier=#{supplier}, brand=#{brand},cutoff=#{cutoff},costPrice=#{costPrice}
        WHERE id=#{id}
    </update>
</mapper>

工具类

package cn.yun.mybatis.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;

public class MybatisUtil {

    private static SqlSessionFactory  factory = null;
    static {
        try {
            factory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("MyBatis-Config.xml"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取Sqlsession对象
     * @return
     */
    public static SqlSession getSqlSession(){
        SqlSession sqlSession = factory.openSession();
        return  sqlSession;
    }
    /**
     * 释放资源
     */
    public static  void  close(SqlSession sqlSession){
        if (sqlSession != null){
            sqlSession.close();
        }
    }


}

ProudentImpl

package cn.yun.mybatis.dao.imp;

import cn.yun.mybatis.dao.IProductDao;
import cn.yun.mybatis.domain.Product;
import cn.yun.mybatis.util.MybatisUtil;
import org.apache.ibatis.session.SqlSession;

import java.util.List;

public class ProudentImpl implements IProductDao {
    private final String  NAMESPACE = "cn.yun.mybatis.domain.ProductMapper.";
    @Override
    public void save(Product prodect) {
        SqlSession sqlSession =null;
        try {
            sqlSession = MybatisUtil.getSqlSession();
            int insert = sqlSession.insert(NAMESPACE + "inertSave",prodect);
            sqlSession.commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            MybatisUtil.close(sqlSession);
        }

    }

    @Override
    public void update(Product proudect) {
        SqlSession sqlSession =null;
        try {
           sqlSession = MybatisUtil.getSqlSession();
            sqlSession.update(NAMESPACE+"update",proudect);
            sqlSession.commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            MybatisUtil.close(sqlSession);
        }

    }

    @Override
    public void delete(Long id) {
        SqlSession sqlSession =null;
        try {
           sqlSession = MybatisUtil.getSqlSession();
            int delete = sqlSession.delete(NAMESPACE + "delete",id);
            sqlSession.commit();//提交事务,在数据库表选项引擎改成InnoDB
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            MybatisUtil.close(sqlSession);
        }

    }

    @Override
    public Product findOne(Long id) {
        SqlSession sqlSession =null;
        Product product =null;
        try {
            sqlSession = MybatisUtil.getSqlSession();
            product = sqlSession.selectOne(NAMESPACE + "selectfindOne",id);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            MybatisUtil.close(sqlSession);
        }
        return product;
    }

    @Override
    public List<Product> findAll() {
        SqlSession sqlSession =null;
        List<Product> list = null;
        try {
            sqlSession = MybatisUtil.getSqlSession();
            list = sqlSession.selectList(NAMESPACE+"selectAll");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            MybatisUtil.close(sqlSession);
        }

        return list;
    }
}

测试

 private IProductDao productDao = new ProudentImpl();
@Test
    public void  testSave() throws Exception{
        Product product = productDao.findOne(1L);
        product.setProductName("天华");
        productDao.save(product);
        获取新添加数据的主键,前提insert标签已经配置了那三个属性
        System.out.println(product.getId());//获取新添加数据的主键

    }

五、注意事项:

  • ① 我们的映射文件一般情况下是和它对应的domain实体类在同一个层级
  • ② 这个映射文件的名称一般叫做 XxxMapper.xml (Xxx代表的是实体类名称)
  • ③ namespace的名称为了确定唯一性,请大家根据我的要求取名
    如我们有一个类:
    cn.itsource.domain.Product / cn.itsource.domain.Student
    那这里取名应该是:
    cn.itsource.domain.ProductMapper /cn.itsource.domain.StudentMapper
  • ④ 类型都通通使用全限定名

六、三大核心对象

  • SqlSessionFactoryBuilder
    目的是创建SqlSessionFactory 用完就扔 写在方法内部 作为局部变量
    建造者模式
  • SqlSessionFactory
    重量级对象 作用域整个应用 单例模式使用 有二级缓存
  • SqlSession
    轻量级的 请求作用域,一个请求对应一个SqlSession对象 线程不安全的 有一级缓存
  • Executor 数据库的操作都是调用的Executor接口的方法
    update
    query

#{}的使用

  • (1)如果传入的是一个简单参数 基本数据类型(包装类型)、字符串类型
    #{xxx} xxx只是起到占位符的作用,内容可以随便写

  • (2)如果传入的是一个复杂参数 Map domain
    #{xxx} xxx必须和成员变量名称对象,底层调用该属性的get方法从参数对象中获取值

${}的使用

${} 不管是什么参数,都是调用属性的get方法,$中的内容必须是成员变量名称

#{}和${}的区别

  • $:
    INSERT INTO product ( productName, dir_id, salePrice, supplier, brand, cutoff, costPrice ) VALUES ( ‘ROG3’, 3, 182.0, ‘罗技’, ‘罗技’, 0.8, 80.0 )

  • #:
    INSERT INTO product ( productName, dir_id, salePrice, supplier, brand, cutoff, costPrice ) VALUES ( ?, ?, ?, ?, ?, ?, ? )

  • #的原理:预编译的sql语句 ==》 ?

  • $的原理: 字符串的拼接 拼接sql

什么时候选择哪种方式?

  • (1)能使用#就用#,不能用#的时候才选择使用$

  • ?不能代替表名和字段名 #{}
    select * from ? (X)
    select * from product where ?=? (X)

    select * from ${tableName}

.Log4j日志框架

  • 在使用MyBatis的很多时候,我们需要把日志打印出来,帮助我们进行分析与排错。
  • 打开后我们可以看到执行的SQL语句,可以看到我们传递的参数。
  • 而MyBatis中打印日志使用的是Log4j
  • Log4j简介:
    • Log4j有三个主要的组件:Loggers(记录器),Appenders (输出源)和Layouts(布局)。
    • 可简单理解为日志类别,日志要输出的地方和日志以何种形式输出。综合使用这三个组件可以轻松地记录信息的类型和级别,并可以在运行时控制日志输出的样式和位置。
  • .日志等级
等级从低到高
TRACE:详细
Debug:调试,类似于System.out.print
Info:信息,类似于JPA打印sql等级
Warn:警告,程序可以正常运行,出现提示
Error:错误,出现异常
  • og4j.properties
#log4j.properties(日志文件:)
log4j.rootLogger=ERROR, stdout
#log4j.rootLogger=NONE
log4j.logger.cn.yun=TRACE   把左边包名改成你自己的包名

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
  • 注意:在上面的标红部分是我们需要修改的,它大概表示为当前会打印哪些位置下面文件的日志。
    cn.yun:一定要根据自己的包名情况进行修改
    如果配置成功,那么在MyBatis运行操作数据时就可以看到相应的日志了。

MyBatis中为一个类取别名

  • 内置别名
    在这里插入图片描述如:
    parameterType=“long”
<!--删除-->
    <delete id="delete" parameterType="long" >
        delete FROM product WHERE  id=#{id}
    </delete>
  • 自定义别名
<typeAliases>
		<!-- 
			将一个包下面的所有类都取上别名:<package name="cn.yun.domain" />
			alias:取的别名
			type:这个别名所对应的Java类
				:别名使用的时候与大小写无关
		 -->
<typeAlias alias="product" type="cn.yun.domain.Product" />
<!-- 做项目的时候使用 -->
<package name="cn.yun.mybatis.domain" />
</typeAliases>

列名与属性名不对应的解决方案

  • .resultMap:在MyBatis中,提供了一个resultMap的标签,就是让咱们来完成返回结果的关系对应的
<!-- 
	返回的数据映射 
		type:代表是要映射的对象
		id:代表唯一(过会我们要拿到它)
-->
<resultMap type="cn.yun.domain.Product" id="productMap">
	<!-- 
		column:对应的列名
		property:对应的属性名
	 -->
	<id column="id" property="id"  />
	<result column="productName" property="name" />
</resultMap>	

<select id="queryOne" parameterType="long" resultMap="productMap">
	select * from product where id = #{id}
</select>
  • 传递一个Map对象
<select id="get" parameterType="map" resultType="cn.itsource.mybaits.domain.User">
		select * from t_user where name=#{name} and password=#{password}
	</select>

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值