Mybatis使用xml方式配置


1 Mybatis快速入门

1.1 框架介绍

  • 框架是一款半成品软件,我们可以基于这个半成品软件继续开发,来完成我们个性化的需求!

  • 如图:

在这里插入图片描述

1.2 ORM介绍

  • ORM(Object Relational Mapping): 对象关系映射

  • 指的是持久化数据和实体对象的映射模式,为了解决面向对象与关系型数据库存在的互不匹配的现象的技术。

  • 如图:

在这里插入图片描述

  • 具体映射关系如下图:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m07WW60L-1606834457333)(img/1590919824416.png)]

1.3 原始jdbc操作(查询数据)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DhhyTS49-1606834457339)(img/1590915350408.png)]
在这里插入图片描述

小插曲:
父类引用指向子类对象,不能子类引用指向父类对象,是经典的语法错误. 

1.4原始jdbc操作(插入数据)

在这里插入图片描述

1.5 原始jdbc操作的分析

  • 原始 JDBC 的操作问题分析

    1.频繁创建和销毁数据库的连接会造成系统资源浪费从而影响系统性能。
    
    1. sql 语句在代码中硬编码,如果要修改 sql 语句,就需要修改 java 代码,造成代码不易维护。
    2. 查询操作时,需要手动将结果集中的数据封装到实体对象中。
    3. 增删改查操作需要参数时,需要手动将实体对象的数据设置到 sql 语句的占位符。 
  • 原始 JDBC 的操作问题解决方案

    1.使用数据库连接池初始化连接资源。 
    
    1. 将 sql 语句抽取到配置文件中。
    2. 使用反射、内省等底层技术,将实体与表进行属性与字段的自动映射

1.6 什么是Mybatis

mybatis 是一个优秀的基于java的持久层框架,它内部封装了jdbc,使开发者只需要关注sql语句本身,而不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。

mybatis通过xml或注解的方式将要执行的各种 statement配置起来,并通过java对象和statement中sql的动态参数进行映射生成最终执行的sql语句。

最后mybatis框架执行sql并将结果映射为java对象并返回。采用ORM思想解决了实体和数据库映射的问题,对jdbc 进行了封装,屏蔽了jdbc api 底层访问细节,使我们不用与jdbc api 打交道,就可以完成对数据库的持久化操作。

MyBatis官网地址:http://www.mybatis.org/mybatis-3/

2 入门案例

2.1 目标

使用mybatis查询user表中的所有数据,并且将查询结果保存到List集合中

第一步:创建数据库表

CREATE TABLE `user`(
    uid INT PRIMARY KEY AUTO_INCREMENT,
    NAME VARCHAR(100) NOT NULL,
    PASSWORD VARCHAR(50) NOT NULL,
    email VARCHAR(50),
    birthday DATE 
);
INSERT INTO `user` (NAME,PASSWORD,email,birthday) VALUES("尼古拉斯赵四",'123456','[email protected]','1888-09-02');
INSERT INTO `user` (NAME,PASSWORD,email,birthday) VALUES("尼古拉斯赵五",'123456','[email protected]','1889-09-03');
INSERT INTO `user` (NAME,PASSWORD,email,birthday) VALUES("尼古拉斯赵六",'123456','[email protected]','1890-09-04');
INSERT INTO `user` (NAME,PASSWORD,email,birthday) VALUES("尼古拉斯赵七",'123456','[email protected]','1891-09-05');

第二步:导入jar包

  • mysql-connector-java-5.1.37-bin.jar
  • mybatis-3.5.3.jar
  • log4j-1.2.17.jar

第三步:创建实体类

package cn.oldlu.domain;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    
    
    private Integer uid;
    private String name;
    private String password;
    private String email;
    private String birthday;//数据库中是Date类型,java中可以是Date,也可以是String类型
}

第四步:创建mybatis配置文件

在src或者resource目录创建映射文件,名字叫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="UserMapper">
    <select id="selectAll" resultType="cn.oldlu.domain.User">
        SELECT * FROM `user`;
    </select>
</mapper>

在src或者resources目录创建主配置文件,名字叫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>

    <!--数据源环境-->
    <environments default="developement">
        <environment id="developement">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://192.168.254.128:3306/mysql03"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    

    <!--加载映射文件-->
    <mappers>
       <mapper resource="UserMapper.xml"></mapper>
    </mappers>
</configuration>

第五步:编写测试类

注意:

使用的是org.apache.ibatis包下的Resources类

package cn.oldlu;

import cn.oldlu.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 org.junit.Test;

import java.text.SimpleDateFormat;

public class UserMapperTest {
    
    
    @Test
    public void selectAll() throws Exception{
    
    
        /*1.读取配置文件并创建SqlSessionFactory*/
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("mybatis-config.xml"));

        /*2.获取sqlSession[这是mybatis的重要API, 使用它可以操作数据库crud*/
        SqlSession sqlSession = sqlSessionFactory.openSession();

        /*
            3.执行查询所有
            第一参数:指的是sql语句的位置,使用namespace.statementId表示
        */

        List<User> users =sqlSession.selectList("UserMapper.selectAll");
        for (User user : users) {
    
    
            System.out.println(user);
        }

        /*4.释放资源*/
        sqlSession.close();
    }
}

3 映射文件介绍

本案例中映射文件的名字叫UserMapper.xml

select 标签可以有id,parameterType,resultType属性
update,delete,insert标签只能有id和parameterType属性
如果SQL需要一个参数,parameterType可以是String,Integer,但是如果SQL中用到多个值,只能传入对象

img

4 主配置文件介绍

本案例中主配置文件的名字叫mybatis-config.xml

4.1 environments标签

数据库环境的配置,支持多环境配置

img

4.2 mapper标签

该标签的作用是加载映射的,加载方式有如下几种:

使用相对于类路径的资源引用,例如:

<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>

使用映射器接口实现类的完全限定类名,例如:

<mapper class="org.mybatis.builder.AuthorMapper"/>

将包内的映射器接口实现全部注册为映射器,例如:

<package name="org.mybatis.builder"/>

4.3 properties标签

4.3.1 介绍

实际开发中,习惯将数据源的配置信息单独抽取成一个properties文件,该标签可以加载额外配置的properties文件

img

4.3.2 使用步骤

目的

把XML中的数据库配置抽取到properties配置文件中

第一步:在src或者resources目录添加配置文件,名字叫jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://192.168.254.128:3306/mysql03
jdbc.username=root
jdbc.password=123456

第二步:在c3p0-config.xml配置文件中的configuration标签内引入jdbc.properties

<properties resource="jdbc.properties"></properties>

第三步:修改主配置文件中的数据库配置

<!--数据源环境-->
<environments default="developement">
    <environment id="developement">
        <transactionManager type="JDBC"></transactionManager>
        <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>

4.4 typeAliases标签

4.4.1 效果展示

使用别名前

img
使用别名后
img

4.4.2 使用步骤

第一步:配置别名,在mybatis-config.xml配置文件中添加如下代码

<typeAliases>
    <!--给指定类起别名,别名一般首字母小写-->
    <typeAlias type="cn.oldlu.domain.User" alias="user"></typeAlias>

    <!--如果类比较多,可以指定包,通过扫包的方式给包中的所有类起别名-->
    <package name="cn.oldlu.domain"/>
</typeAliases>

第二步:使用别名,比如之前mapper中的查询全部的resultType的值由之前的全类名改为user

<select id="selectAll" resultType="user">
    SELECT * FROM `user`;
</select>

4.4.3 内置的别名

1589723643236

4.5 settings标签

4.5.1 目标

配置log4j,在控制台输出日志信息,查看SQL语句

4.5.2 注意事项

该标签紧跟properties标签,否则报错

4.5.3 使用步骤

第一步:在主文件中配置log4j

<settings>
    <setting name="logImpl" value="log4j"/>
</settings>

第二步:导入log4j.properties到resources目录

### 设置###
log4j.rootLogger = debug,stdout,D,E

### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = E://logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

### 输出ERROR 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://logs/error.log 
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR 
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

5 API介绍

5.1 Resources

在 org.apache.ibatis 包中

功能:读取配置文件,获取输入流,等价于XX.class.getClassloader().getResourcesAsStream(“xx.xml”);

返回值 方法名 说明
Reader static getResourceAsReader() 通过类加载器返回指定资源的字节输入流
InputStream static getResourceAsStream()

示例

InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");

5.2 SqlSessionFactoryBuilder

功能:解析配置文件,创建SqlSessionFactory对象

返回值 方法名 说明
SqlSessionFactory build(InputStream is) 解析配置文件得到工厂类

示例

InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml"); 
SqlSessionFactory factory = new SqlSessionFactoryBuilder().builder.build(inputStream);

5.3 SqlSessionFactory

功能:获取SqlSession

方法 解释
openSession() 会默认开启一个事物,但事物不会自动提交,也就意味着需要手动提交该事物,增删改操作数据才会持久化到数据库中【如果仅仅是查询,不需要提交事务,用无参的】
openSession(boolean autoCommit) 参数为是否自动提交,如果设置为true,那么不需要手动提交事务【如果是增删改,需要提交事务,用有参的】

5.4 SqlSession

功能:执行SQL,管理事物、接口代理

返回值 方法名 说明
List selectList(String statement,Object parameter) 执行查询,返回List集合
T selectOne(String statement,Object parameter) 执行查询,返回一个结果对象
int insert(String statement,Object parameter) 执行新增,返回影响行数
int update(String statement,Object parameter) 执行更新,返回影响行数
int delete(String statement,Object parameter) 执行删除,返回影响行数
void commit() 提交事务
void rollback() 回滚事物
T getMapper(Class clazz) 获取指定接口的代理实现类对象
void close() 释放资源

6 增删改查演示

在这里插入图片描述

6.1 查询多条记录

UserMapper.xml配置

<select id="selectAll" resultType="cn.oldlu.domain.User">
    SELECT * FROM `user`;
</select>

测试方法

@Test
public void selectAll() throws Exception {
    
    
    /*1.读取配置文件并创建SqlSessionFactory*/
    InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

    /*2.获取sqlSession[这是mybatis的重要API, 使用它可以操作数据库crud*/
    SqlSession sqlSession = sqlSessionFactory.openSession();

    /*3.查询多条记录*/
    List<User> users = sqlSession.selectList("UserMapper.selectAll");

    /*4.释放资源*/
    sqlSession.close();

    /*测试查询结果*/
    for (User user : users) {
    
    
        System.out.println(user);
    }
}

6.2 查询一条记录

UserMapper.xml

<!--#{} 中的名字可以随便写,但是为了可读性最好见名知意-->
<select id="selectOne" resultType="cn.oldlu.domain.User" parameterType="int">
    SELECT * FROM `user` WHERE uid = #{uid};
</select>

测试方法

@Test
public void selectOne() throws Exception {
    
    
    /*1.读取配置文件并创建SqlSessionFactory*/
    InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

    /*2.获取sqlSession[这是mybatis的重要API, 使用它可以操作数据库crud*/
    SqlSession sqlSession = sqlSessionFactory.openSession();

    /*3.查询一条记录*/
    User u = (User) sqlSession.selectOne("UserMapper.selectOne", 1);

    /*4.释放资源*/
    sqlSession.close();

    /*测试查询结果*/
    System.out.println(u);
}

6.3 新增一条记录

UserMapper.xml

<!--#{}中的值和cn.oldlu.domain.User对象的属性名保持一致-->
<insert id="save" parameterType="cn.oldlu.domain.User">
    insert into `user` (name,password,email,birthday) values(
    #{name},
    #{password},
    #{email},
    #{birthday}
    );
</insert>

测试方法

如果openSession(true)传入true表示自动提交事务,则不需要手动调用commit()方法提交事务

@Test
public void save() throws Exception {
    
    
    /*1.读取配置文件并创建SqlSessionFactory*/
    InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

    /*2.获取sqlSession[这是mybatis的重要API, 使用它可以操作数据库crud*/
    SqlSession sqlSession = sqlSessionFactory.openSession();

    /*3.创建对象,并插入到数据库*/
    User u = new User(null, "tom", "123456", "[email protected]", "2016-09-08");
    int count = sqlSession.insert("UserMapper.save", u);

    /*4.提交事务*/
    sqlSession.commit();

    /*5.释放资源*/
    sqlSession.close();

    /*测试查询结果*/
    System.out.println("共"+count+"行收到影响");
}

6.4 更新一条记录

UserMapper.xml

<!--#{}中的值和cn.oldlu.domain.User对象的属性名保持一致-->
<update id="update" parameterType="cn.oldlu.domain.User">
    update `user` set name = #{name}, email = #{email}, birthday = #{birthday} 
    where uid = #{uid}
</update>

测试方法

如果openSession(true)传入true表示自动提交事务,则不需要手动调用commit()方法提交事务

@Test
public void update() throws Exception {
    
    
    /*1.读取配置文件并创建SqlSessionFactory*/
    InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

    /*2.获取sqlSession[这是mybatis的重要API, 使用它可以操作数据库crud*/
    SqlSession sqlSession = sqlSessionFactory.openSession();

    /*3.创建对象,并更新到数据库*/
    User u = new User(2, "TomCat", "123456", "[email protected]", "2016-09-08");
    int count = sqlSession.update("UserMapper.update", u);

    /*4.提交事务*/
    sqlSession.commit();

    /*5.释放资源*/
    sqlSession.close();

    /*测试查询结果*/
    System.out.println("共"+count+"行收到影响");
}

其他方式传值:
在这里插入图片描述
在这里插入图片描述

6.5 删除一条记录

UserMapper.xml

<!--#{} 中的名字可以随便写,但是为了可读性最好见名知意-->
<delete id="deleteByUid" parameterType="int">
    delete from `user` where uid = #{uid}
</delete>

测试方法

如果openSession(true)传入true表示自动提交事务,则不需要手动调用commit()方法提交事务

@Test
public void delete() throws Exception {
    
    
    /*1.读取配置文件并创建SqlSessionFactory*/
    InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

    /*2.获取sqlSession[这是mybatis的重要API, 使用它可以操作数据库crud*/
    SqlSession sqlSession = sqlSessionFactory.openSession();

    /*3.删除*/
    int count = sqlSession.delete("UserMapper.deleteByUid", 3);

    /*4.提交事务*/
    sqlSession.commit();

    /*5.释放资源*/
    sqlSession.close();

    /*测试查询结果*/
    System.out.println("共"+count+"行收到影响");
}

在这里插入图片描述

7 接口代理实现dao层代码

7.1 目标

通过配置让mybatis帮我们创建dao接口的实现类对象。

7.2 介绍

采用 Mybatis 的代理开发方式实现 dao层的开发,这种方式是我们后面进入企业的主流。

接口代理方式只需要程序员编写dao 接口(后期叫做mapper接口),由Mybatis 框架根据接口定义创建接口的动态代理对象。

需要遵循以下规范:

  1. 映射文件中的namespace与dao接口的全类名相同
  2. 映射文件中的增删改查标签的id属性与dao接口的方法名相同
  3. 映射文件中的增删改查标签的parameterType属性与dao接口中方法的参数类型匹配
  4. 映射文件中的增删改查标签的resultType属性与dao接口中方法的返回值类型匹配

1589770204634

记忆方式:以后映射文件就是描述mapper/dao接口的文件

7.3 代码实现

第一步:创建数据库表

CREATE TABLE `user`(
    uid INT PRIMARY KEY AUTO_INCREMENT,
    NAME VARCHAR(100) NOT NULL,
    PASSWORD VARCHAR(50) NOT NULL,
    email VARCHAR(50),
    birthday DATE 
);
INSERT INTO `user` (NAME,PASSWORD,email,birthday) VALUES("尼古拉斯赵四",'123456','[email protected]','1888-09-02');
INSERT INTO `user` (NAME,PASSWORD,email,birthday) VALUES("尼古拉斯赵五",'123456','[email protected]','1889-09-03');
INSERT INTO `user` (NAME,PASSWORD,email,birthday) VALUES("尼古拉斯赵六",'123456','[email protected]','1890-09-04');
INSERT INTO `user` (NAME,PASSWORD,email,birthday) VALUES("尼古拉斯赵七",'123456','[email protected]','1891-09-05');

第二步:导入jar包

第三步:创建实体类

package cn.oldlu.domain;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    
    
    private Integer uid;
    private String name;
    private String password;
    private String email;
    private String birthday;//数据库中是Date类型,java中可以是Date,也可以是String类型
}

第四步:创建dao接口

package cn.oldlu.dao;

import cn.oldlu.domain.User;

public interface UserDao {
    
    
    User findById(Integer id);
}

第四步:创建映射文件

在src或者resource目录创建映射文件,名字叫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的值是UserDao的类全名-->
<mapper namespace="cn.oldlu.dao.UserDao">
    <!--
    id的值和UserDao中的方法名保持一致
    parameterType和UserDao中的方法参数类型保持一致
    resultType和UserDao的方法返回值类型保持一致,这里用的是别名
    -->
    <select id="findById" parameterType="int" resultType="user">
        select * from `user` where uid= #{uid}
    </select>
</mapper>

第五步:创建主配置文件

在src或者resources目录创建主配置文件,名字叫mybatis-config.xml

settings、typeAliases、properties配置参考第一天的配置

<?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="jdbc.properties"></properties>
    <settings>
        <setting name="logImpl" value="log4j"/>
    </settings>
    <typeAliases>
        <!--如果类比较多,可以指定包,通过扫包的方式给包中的所有类起别名-->
        <package name="cn.oldlu.domain"/>
    </typeAliases>
    <!--数据源环境-->
    <environments default="developement">
        <environment id="developement">
            <transactionManager type="JDBC"></transactionManager>
            <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="UserMapper.xml"></mapper>
    </mappers>
</configuration>

第五步:编写测试方法

注意:

使用的是org.apache.ibatis包下的Resources类

@Test
public void testFindById()throws Exception{
    
    
    /*1.读取配置文件并创建SqlSessionFactory*/
    InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

    /*2.获取sqlSession[这是mybatis的重要API, 使用它可以操作数据库crud*/
    SqlSession sqlSession = sqlSessionFactory.openSession();

    /*3.由Mybatis框架创建UserDao的实现类对象,我们称为代理对象*/
    UserDao userDao = sqlSession.getMapper(UserDao.class);

    /*4.调用接口的方法*/
    User u = userDao.findById(1);

    /*5.释放资源*/
    sqlSession.close();

    //测试查询结果
    System.out.println(u);

}

7.4 小结

接口代理方式让我们只编写接口即可,而实现类对象由MyBatis生成
实现规则

  1. 映射文件中的namespace与dao接口的全类名相同
  2. 映射文件中的增删改查标签的id属性与dao接口的方法名相同
  3. 映射文件中的增删改查标签的parameterType属性与dao接口中方法的参数类型匹配
  4. 映射文件中的增删改查标签的resultType属性与dao接口中方法的返回值类型匹配

猜你喜欢

转载自blog.csdn.net/ZGL_cyy/article/details/110456064