Mybatis入门

1. Mybatis架构

1.1 基本概念

  1. mybatis配置
    SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。
    mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。
  2. 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂
    由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。
  3. mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。
  4. Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。
  5. Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
  6. Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。

2 Mybatis入门程序

2.1 导入jar包

  • 加入mybatis核心包、依赖包、数据驱动包。

2.2 编写log4j.properties文件

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

2.3 编写SqlMapConfig.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>
    <!-- 和spring整合后 environments配置将废除-->
    <environments default="development">
        <environment id="development">
        <!-- 使用jdbc事务管理-->
            <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="root" />
            </dataSource>
        </environment>
    </environments>

</configuration>

SqlMapConfig.xml是mybatis核心配置文件,上边文件的配置内容为数据源、事务管理。

2.4 po类

Public class User {
    private int id;
    private String username;// 用户姓名
    private String sex;// 性别
    private Date birthday;// 生日
    private String address;// 地址
    //....
}

2.5 sql映射文件

<?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">
</mapper>

2.6 加载映射文件

<!-- 引入配置文件 -->
<mappers>
    <!-- <mapper resource="User.xml"/> -->
    <!-- 使用class属性引入接口的全路径名称
        使用规则:
            1.接口的名称和映射文件名称除扩展名外
            2.接口和映射文件要放在同一个目录下
     -->
    <!-- <mapper class="com.dml.mapper.UserMapper"/> -->

    <!-- 使用包扫描的方式批量引入 Mapper接口
        使用规则:
            1.接口的名称和映射文件名称除扩展名外
            2.接口和映射文件要放在同一个目录下
    -->
    <package name="com.dml.mapper"/>
</mappers>

2.7 根据id查询用户信息

在user.xml中添加:
<!-- 根据id获取用户信息 -->
<!-- 
    id:sql语句唯一标识符
    parameterType:指定传入参数类型
    resultType:返回结果集类型
    #{}:占位符:起到占位作用,如果传入的是基本类型(String,long,double,boolean,float等)
    那么#{}中的变量名称可以任意写
 -->
<select id="findUserById" parameterType="java.lang.Integer" resultType="com.dml.pojo.User">
    select * from user where id=#{id}
</select>
测试程序
public class Mybatis_first {

    //会话工厂
    private SqlSessionFactory sqlSessionFactory;

    @Before
    public void createSqlSessionFactory() throws IOException {
        // 配置文件
        String resource = "SqlMapConfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);

        // 使用SqlSessionFactoryBuilder从xml配置文件中创建SqlSessionFactory
        sqlSessionFactory = new SqlSessionFactoryBuilder()
                .build(inputStream);

    }

    // 根据 id查询用户信息
    @Test
    public void testFindUserById() {
        // 数据库会话实例
        SqlSession sqlSession = null;
        try {
            // 创建数据库会话实例sqlSession
            sqlSession = sqlSessionFactory.openSession();
            // 查询单个记录,根据用户id查询用户信息
            第一个参数:所调用的sql语句=namespace.sql的id
            User user = sqlSession.selectOne("test.findUserById", 10);
            // 输出用户信息
            System.out.println(user);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }

    }
}

2.8 根据用户名查询用户信息

在user.xml中添加:
<!-- 自定义条件查询用户列表 -->
<!-- 如果返回结果集合,可以调用selectList方法,这个方法返回的结果就是一个集合,
    所以映射文件中应该配置成集合泛型的类型
    select * from user where username like #{name}
    ${}拼接符:字符串原样拼接,如果传入的参数是基本类型(String,long,double,boolean,float等)
    那么${}中的变量名称必须是value
    注意:拼接符有sql注入风险,所以慎重使用

 -->
<select id="findUserByName" parameterType="java.lang.String" resultType="com.dml.pojo.User">
    select * from user where username like '%${value}%'
</select>
测试程序
// 根据用户名称模糊查询用户信息
@Test
public void testFindUserByUsername() {
    // 数据库会话实例
    SqlSession sqlSession = null;
    try {
        // 创建数据库会话实例sqlSession
        sqlSession = sqlSessionFactory.openSession();
        // 查询单个或多个记录,根据用户name查询用户信息,所以使用selectList
        List<User> list = sqlSession.selectList("test.findUserByName", "张");
        System.out.println(list.size());
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (sqlSession != null) {
            sqlSession.close();
        }
    }

}

2.9 添加用户

映射文件User.xml
<!-- 插入数据 
    #{}:如果传入的是pojo类型,那么#{}中的变量名称必须是pojo中对应的属性.属性.属性

    如果要返回数据库自增主键:可以使用select LAST_INSERT_ID()
-->
<insert id="insertUser" parameterType="com.dml.pojo.User" >
    <!-- 执行select LAST_INSERT_ID()数据库函数,返回自增的主键 
        keyProperty:将返回的主键放入传入参数的id中保存
        order:当前函数相对于insert语句的执行顺序
        resultType:id的类型,也就是keyProperty属性的类型
    -->
    <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
        select LAST_INSERT_ID()
    </selectKey>
    insert into user (username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
</insert>
测试程序
// 添加用户信息
@Test
public void testInsert() {
    // 数据库会话实例
    SqlSession sqlSession = null;
    try {
        // 创建数据库会话实例sqlSession
        sqlSession = sqlSessionFactory.openSession();
        // 添加用户信息
        User user = new User();
        user.setUsername("嘟嘟");
        user.setBirthday(new Date());
        user.setSex("1");
        user.setAddress("广西柳州");
        sqlSession.insert("test.insertUser", user);
        //提交事务mybatis会自动开启事务,所以需要手动提交
        sqlSession.commit();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (sqlSession != null) {
            sqlSession.close();
        }
    }
}

2.10 Mysql使用 uuid实现主键

需要增加通过select uuid()得到uuid值

<insert  id="insertUser" parameterType="com.dml.pojo.User">
<selectKey resultType="java.lang.String" order="BEFORE" 
keyProperty="id">
select uuid()
</selectKey>
insert into user(id,username,birthday,sex,address) 
         values(#{id},#{username},#{birthday},#{sex},#{address})
</insert>
注意这里使用的order是“BEFORE”

2.11 删除用户

映射文件
<!-- 删除 -->
<delete id="delUserById" parameterType="java.lang.Integer">
    delete from user where id=#{id}
</delete>
测试程序
// 根据id删除用户
@Test
public void testDelete() {
    // 数据库会话实例
    SqlSession sqlSession = null;
    try {
        // 创建数据库会话实例sqlSession
        sqlSession = sqlSessionFactory.openSession();
        // 删除用户
        sqlSession.delete("test.delUserById",18);
        // 提交事务
        sqlSession.commit();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (sqlSession != null) {
            sqlSession.close();
        }
    }
}

2.12 修改用户

映射文件
<!-- 更新 -->
<update id="updateUserById" parameterType="com.dml.pojo.User">
    update user set username=#{username} where id=#{id}
</update>
测试程序
@Test
public void testUpdate() {
    // 数据库会话实例
    SqlSession sqlSession = null;
    try {
        // 创建数据库会话实例sqlSession
        sqlSession = sqlSessionFactory.openSession();
        // 添加用户信息
        User user = new User();
        user.setUsername("哈哈");
        user.setId(26);
        sqlSession.update("test.updateUserById", user);
        // 提交事务
        sqlSession.commit();

    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (sqlSession != null) {
            sqlSession.close();
        }
    }
}

Mybatis解决jdbc编程的问题

  1. 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
    解决:在SqlMapConfig.xml中配置数据链接池,使用连接池管理数据库链接。
  2. Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。
    解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离。
  3. 向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。
    解决:Mybatis自动将java对象映射至sql语句,通过statement中的parameterType定义输入参数的类型。
  4. 对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。
    解决:Mybatis自动将sql执行结果映射至java对象,通过statement中的resultType定义输出结果的类型。

User.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:命名空间,做sql隔离 -->
<mapper namespace="test">
    <!-- 
        id:sql语句唯一标识符
        parameterType:指定传入参数类型
        resultType:返回结果集类型
        #{}:占位符:起到占位作用,如果传入的是基本类型(String,long,double,boolean,float等)
        那么#{}中的变量名称可以任意写
     -->
    <select id="findUserById" parameterType="java.lang.Integer" resultType="com.dml.pojo.User">
        select * from user where id=#{id}
    </select>

    <!-- 如果返回结果集合,可以调用selectList方法,这个方法返回的结果就是一个集合,
        所以映射文件中应该配置成集合泛型的类型
        select * from user where username like #{name}
        ${}拼接符:字符串原样拼接,如果传入的参数是基本类型(String,long,double,boolean,float等)
        那么${}中的变量名称必须是value
        注意:拼接符有sql注入风险,所以慎重使用

     -->
    <select id="findUserByName" parameterType="java.lang.String" resultType="com.dml.pojo.User">
        select * from user where username like '%${value}%'
    </select>


    <!-- 插入数据 
        #{}:如果传入的是pojo类型,那么#{}中的变量名称必须是pojo中对应的属性.属性.属性

        如果要返回数据库自增主键:可以使用select LAST_INSERT_ID()
    -->
    <insert id="insertUser" parameterType="com.dml.pojo.User" >
        <!-- 执行select LAST_INSERT_ID()数据库函数,返回自增的主键 
            keyProperty:将返回的主键放入传入参数的id中保存
            order:当前函数相对于insert语句的执行顺序
            resultType:id的类型,也就是keyProperty属性的类型
        -->
        <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
            select LAST_INSERT_ID()
        </selectKey>
        insert into user (username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
    </insert>

    <!-- 删除 -->
    <delete id="delUserById" parameterType="java.lang.Integer">
        delete from user where id=#{id}
    </delete>

    <!-- 更新 -->
    <update id="updateUserById" parameterType="com.dml.pojo.User">
        update user set username=#{username} where id=#{id}
    </update>
</mapper>

SqlMapConfig.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="db.properties"></properties>
    <!-- 和spring整合后 environments配置将废除-->
    <environments default="development">
        <environment id="development">
        <!-- 使用jdbc事务管理-->
            <transactionManager type="JDBC" />
        <!-- 数据库连接池-->
            <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="User.xml"/>
    </mappers>
</configuration>

db.properties文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值