【MyBatis】

静态代理

在运行之前,代理类与目标类之间的关系就已经产生了

MyBatis概述

MyBatis本是apache的一个开源项目iBatis,2010年这个项目由apache迁移到了google并更名为MyBatis,2013年迁移到GitHub。

MyBatis官网:https://github.com/mybatis

MyBatis对比Hibernate

Hibernate是“全自动”的ORM,MyBatis是“半自动”的ORM。

mybatis相比hibernate具有以下几个特点:

① 在XML文件中编写SQL语句,实现了SQL语句与代码的分离,为程序的维护带来便利

② 因为需要手动编写SQL语句,我们可以结合数据库的特点灵活控制SQL语句,因此能够实现比hibernate全自动的ORM框架更高的查询效率,能够完成复杂的查询

③ 简单,易于学习和使用,上手快

MyBatis体系结构

MyBatis工作原理


MyBatis主配置文件

mybatis主配置文件中主要配置:

1 数据库连接参数

2要注册的映射文件。注意:映射文件要放到最下面

主配置文件的各个元素以及各个元素常用的属性介绍
元素元素的属性对元素以及元素属性的说明
<properties>resource当db.properties文件有多个的时候,只需要更改resource属性的值,复制db.properties文件名到resource属性中,一般情况下,db.properties文件连接数据库四要素写好是不直接在这里面更改的,而是更改该元素的属性的值
<environments>default意思是在这个元素下可以有多个数据库连接的环境,比如oracle、mysql,也就是可有多个<environment>元素,default属性需要与其中一个<environment>元素的id属性值一致,表示默认使用的是哪个数据库连接环境
<environment>id意思是给这个元素起名,表示数据库连接环境,需见名知意
<transactionManager>type

type属性值有:

JDBC:表示事务管理默认JDBC的

<dataSource>type

type属性值有:

POOLED:数据源采用的是mybatis自带的数据库连接池技术

<property>

name

value

name:有固定的属性值,该属性值有driver、url、username、password。如果不知道去mybatis帮助文档可以查看到

 

value

第1个name属性的value值

如果忘记怎么编写,在项目的Referenced Libraries目录下找到mysql-connector-java-x.x.xx-bin.jar > com.mysql.jdbc > Driver.class,右击
复制全名,去掉.class即可

第2个name属性的value值

jdbc:mysql://127.0.0.1:3306/test,如果端口号3306没有更改,直接///,省略IP地址跟端口号,jdbc代表总协议,mysql代表子协议,跟http协议一样,包括电脑的任意文件目录,前面都有file://,只不过省略了

第3、4个name属性的value值省略

 
如果数据库连接四要素在db.properties文件中已经写好,value属性值写法是${db,properties文件的key值}

<mappers> 要注册的映射文件
<mapper>resource要注册的映射文件的路径,直接在项目路径下找到映射文件,右击复制即可

在主配置文件中,即使配置了dtd文件,也不会出现元素提示。可以将鼠标指针移动到根节点元素,按住F2键,如下图:

接下来根节点元素第一个子元素是<environments>,配好这个子元素以后还是报错的状态,移动到该元素上,F2键,提示这个子元素必须要有default属性,在根节点元素下还必须要有<environment>子元素,配置了这个子元素以后,还是报错的,同样,F2键,提示这个子元素必须要有id属性,在该子元素下必须要有<transactionManager>子元素和<dataSource>子元素。

关于元素后面的 (, + ? *) 的解释,以根节点元素<environments>举例:


MyBatis映射配置

映射文件的各个元素以及各个元素常用的属性介绍
元素元素的属性对元素以及元素属性的说明
<mapper>namespace

映射文件的根节点元素

namespace:映射文件的命名空间,必须配置,否则报错。同一包下的多个映射文件的namespace属性值不能相同

<insert>

id

parameterType

插入语句元素

id:给这个<insert>起的名称。对应SqlSession的insert()的第一个参数

 

parameterType:要插入对象,包括类对象所在的包。对应SqlSession的insert()的第二个参数。sql语句示例:

insert into student(name,age,score)

values(#{name}, #{age}, #{score})

values括号的值是:要插入对象的属性名称,不是成员变量,底层用的是反射机制,会将values括号的每一个值会组装成getXxx(),获取要插入对象的成员变量的值


DAO层保存一个对象示例

代码结构以及代码如下:

Student类,省略get() set()

public class Student {

    private Integer id;
    private String name;
    private int age;
    private double score;

}

mapper.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="test">
    <insert id="insertStudent" parameterType="net.csdn.entity.Student">
        insert into student(name,age,score) values(#{name},#{age},#{score})
    </insert>
</mapper>

mybatis.cfg.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="mysqlEnvironment">
        <environment id="mysqlEnvironment">
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql:///test" />
                <property name="username" value="root" />
                <property name="password" value="123456" />
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="net/csdn/dao/mapper.xml" />
    </mappers>
</configuration>

log4j.properties日志

log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Target=System.out
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%-5p] %m%n

#debug级别,控制台就会打印sql语句。test是映射文件<mapper>元素的namespace属性值
log4j.logger.test=debug, console

StudentDao接口

public interface StudentDao {
	
    public abstract void insertObj(Student student);

}

StudentDao接口实现类StudentDaoImpl

public class StudentDaoImpl implements StudentDao {

    private SqlSession sqlSession;

    @Override
    public void insertObj(Student student) {
        try {
            //1 加载mybatis主配置文件
            InputStream inputStream = Resources.getResourceAsStream("mybatis.cfg.xml");
            //2 得到SqlSessionFactory对象。是线程安全的
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            //3 得到Session
            sqlSession = sqlSessionFactory.openSession();
            //4 持久化操作
            sqlSession.insert("insertStudent", student); //insert(String statement, Object parameter); 方法的第一个参数是映射文件<insert>元素的id属性值,第二个参数是方法的形参
            //5 提交事务
            sqlSession.commit();
			
        } catch (IOException e) {
            e.printStackTrace();
        }
        finally{
            if(sqlSession != null){
                sqlSession.close();
            }
        }
    }

}

TestMybatis测试类。以保存为例

public class TestMybatis {
	
    private StudentDao dao;

    @Before
    public void before(){
        dao = new StudentDaoImpl();
    }

    @Test
    public void test() {
        Student student = new Student("张三三",25,77.5);
        dao.insertObj(student);
    }

}

执行test(),控制台打印如下:

查看数据库,插入成功!

接下来抽取工具类,在src下新建包:net.csdn.utils,新建如下类:

因为SqlSessionFactory一个应用程序只需要这一个对象,适合设计成单例模式,所以需要抽取出来。

public class SqlSessionFactoryUtils {
	
    private static SqlSessionFactory sqlSessionFactory;

    public SqlSessionFactoryUtils() {
    }

    public synchronized static SqlSession getSqlSession(){
        try {
            InputStream inputStream = Resources.getResourceAsStream("mybatis.cfg.xml");
            if (sqlSessionFactory == null) {
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            }
            return sqlSessionFactory.openSession();
        } catch (IOException e) {
            e.printStackTrace();
        }
		
        return null;
    }

}

在实现类StudentDaoImpl中,直接调用,直接省略1 2 3步骤,如下:

@Override
public void insertObj(Student student) {

    sqlSession = SqlSessionFactoryUtils.getSqlSession();
    //4 持久化操作
    sqlSession.insert("insertStudent", student);
     //5 提交事务
    sqlSession.commit();
			
    if(sqlSession != null){
        sqlSession.close();
    }

}

思考:在加载mybatis主配置文件的时候,为什么输入流没有关闭?

在输入流对象使用完毕后,不用手动进行流的关闭,因为 SqlSessionFactory对象的 build()会自动将输入流关闭。

鼠标移动到build()上,按住ctrl,点击Open Implementation,进入源码,如下:

SqlSession的方法解释:

提交commit()

为什么是SqlSession提交的事物?

 

关闭close()

只要SqlSession调用close(),就不需要调用SqlSession的rollback()

为什么调用了close()就不需要事物回滚了呢?

 

保存insert(String statement, Object parameter)

第一个参数statement是映射文件<insert>元素的id属性的值,为什么是该元素的id属性的值?因为该元素编写了sql语句,还有要插入的值;如果同一包下有多个映射文件,<insert>元素的id属性的值又一样,需要在第一个参数的前面加上<mapper>元素的namespace属性值

第二个参数是要插入的对象的变量名称。


执行insert(),就会把第二个参数,要插入的对象传入到映射文件的<insert>元素当中,前提这个对象需要通过构造方法给成员变量赋值,不然带到<insert>元素下sql语句是空的。

   
   

 

 

 


 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值