Mybatis学习记录(一)--Mybatis入门

一.传统数据库解决方案

对于数据库的连接,在java中简单的就是直接使用JDBC来控制数据库.传统的jdbc方式按照以下几步来操作数据库.

1.加载驱动 2. 创建并获取连接 3. 创建jdbc statement对象 4.设置sql语句 5.设置sql语句参数
6.执行sql并返回resultset结果 7.取出结果并释放连接

传统的方法存在以下几点问题:
1. 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
2. Sql语句在代码中硬编码,造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。
3. 使用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能多也可能少,修改sql还要修改代码,系统不易维护。
4. 对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成pojo对象解析比较方便。

那么mybatis等框架的出现就是用来解决这些问题,解决方案就是重新对jdbc进行封装.


二.mybatis介绍

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis,实质上Mybatis对ibatis进行一些改进。
MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。


三.mybatis整体结构

Mybatis学习记录(一)--Mybatis入门_第1张图片

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


四.mybatis下载

mybaits的代码由github.com管理,地址:https://github.com/mybatis/mybatis-3/releases
核心文件mybatis3.3.1.jar


五.mybatis入门程序

1.基本配置

首先导入mysql的包,mybatis的包,log4j的包

为了演示入门程序效果,所以在数据库中建立一张User表
Mybatis学习记录(一)--Mybatis入门_第2张图片

在代码中写上model类

public class User {
    private int id;
    private String username;
    private String password;
    private String nickname;
    private int status;

    //省略get和set方法

    @Override
    public String toString() {
        return "id:"+id+"username:"+username+"password:"+password+"nickname:"+nickname;
    }
}

2.配置log4j

使用log4j可以在调试mybatis的过程中省去很多麻烦,还可以直观的看到mybatis的sql语句.
首先把log4j的jar包导入到项目中,然后建立log4j.properties文件,按照官方文档写入配置


# Global logging configuration
#在开发环境中要设置为DEBUG,不然不会打印出信息
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

这样在运行过程中mybatis就会在控制台打出相应的日志了.

3.配置SqlMapConfig.xml

SqlMapConfig.xml配置很简单,从官方文档直接拷贝下来就可以了,具体在里面都有介绍



<configuration>
    
    <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/shopdemo?characterEncoding=utf-8" />
                <property name="username" value="root" />
                <property name="password" value="7946521" />
            dataSource>
        environment>
    environments>

    
    <mappers>
        <mapper resource="mapper/User.xml"/>
    mappers>

configuration>

4.根据id查询用户(精确查询单条数据)

根据mybatis整体流程,配置完SqlMapConfig.xml之后是创建相应的model类的映射.这里我们为User创建User.xml文件,并写上sql语句




<mapper namespace="test">
    
    <select id="findUserById" parameterType="int" resultType="com.aust.model.User">
        SELECT * FROM user WHERE id=#{id}
    select>
mapper>
  • id:标识当前sql,mybatis把sql语句封装到MappedStatement中,所以可以称为Statement的唯一标识
  • parameterType:指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中。
  • resultType:指定输出结果类型,mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。select下指定将单条数据映射成java对象

接下来在SqlMapConfig.xml中配置mapper映射,再其里面加入下面配置


    <mappers>
        <mapper resource="mapper/User.xml"/>
    mappers>

然后写junit测试

    //测试取出单个
    @Test
    public void findUserTest(){
        //用于加载mybatis配置文件的输入流
        InputStream is = null;
        try {
            is = Resources.getResourceAsStream("SqlMapperConfig.xml");

        } catch (IOException e) {
            System.out.println("加载mybatis配置文件出错");
            e.printStackTrace();
        }
        //获取会话工厂
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
        //获取会话
        SqlSession session = factory.openSession();
        //执行查询单条记录,返回的类型就是resultType
        //第一个参数命名规则为: 命名空间+Statement id
        User u = session.selectOne("test.findUserById",1);
        //查询完要释放会话
        session.close();
        System.out.println(u.toString());
    }

结果
Mybatis学习记录(一)--Mybatis入门_第3张图片

5.根据姓名查询用户(模糊查询多条数据)

和上面一样的操作,先写sql语句


    <select id="findUserByName" parameterType="java.lang.String" resultType="com.aust.model.User">
    
    SELECT * from user WHERE nickname LIKE '%美元符号{value}%'
    select>

这里和上面区别大的是使用了${}来配置,不过本质都是ognl来获取的

  • #{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。
  • 美元符号{}表示拼接sql串,通过美元符号{}可以将parameterType传入的内容拼接在sql中且不进行jdbc类型转换, 所以可能引起sql注入,美元符号{}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,美元符号{}括号中只能是value。

写junit测试类

    //测试取出多个
    @Test
    public void findUserByNameTest(){
        //用于加载mybatis配置文件的输入流
        InputStream is = null;
        try {
            is = Resources.getResourceAsStream("SqlMapperConfig.xml");

        } catch (IOException e) {
            System.out.println("加载mybatis配置文件出错");
            e.printStackTrace();
        }
        //获取会话工厂
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
        //获取会话
        SqlSession session = factory.openSession();
        //查询多条数据返回值为list集合,list里面的类型是resultType配置的类型
        List users = session.selectList("test.findUserByName","张");
        session.close();
        System.out.println(users);
    }

测试结果
Mybatis学习记录(一)--Mybatis入门_第4张图片

6.插入一个用户,并返回自增主键

自增主键的返回,可以使用mysql的SELECT last_insert_id()函数,不过该sql要在insert语句之后才能执行

    
    <insert id="insertUser" parameterType="com.aust.model.User">
      <selectKey keyProperty="id" resultType="java.lang.Integer" order="AFTER" >
          SELECT last_insert_id()
      selectKey>
        INSERT INTO user(username,password,nickname,status) VALUE (#{username},#{password},#{nickname},#{status})
    insert>
  • keyProperty:返回的主键存储在pojo中的哪个属性
  • order:selectKey的执行顺序,是相对与insert语句来说,由于mysql的自增原理执行完insert语句之后才将主键生成,所以这里selectKey的执行顺序为after
  • resultType:返回的主键是什么类型
  • LAST_INSERT_ID():是mysql的函数,返回auto_increment自增列新记录id值。

junit测试

//测试插入数据
    @Test
    public void insertUserTest(){
        //用于加载mybatis配置文件的输入流
        InputStream is = null;
        try {
            is = Resources.getResourceAsStream("SqlMapperConfig.xml");

        } catch (IOException e) {
            System.out.println("加载mybatis配置文件出错");
            e.printStackTrace();
        }
        //获取会话工厂
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
        //获取会话
        SqlSession session = factory.openSession();
        User u = new User();
        u.setUsername("niuli");
        u.setPassword("123456");
        u.setNickname("牛李");
        u.setStatus(2);
        //返回的是受影响的行数
        int a = session.insert("test.insertUser",u);
        System.out.println(a);
        //提交事务
        session.commit();
        session.close();
        //获取主键
        System.out.println("u id"+u.getId());
    }

测试结果
Mybatis学习记录(一)--Mybatis入门_第5张图片

7.mybatis对于非自增主键

非自增主键和自增主键差不多,只是获取的函数和方式不同

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

<insert  id="insertUser" parameterType="cn.itcast.mybatis.po.User">
"java.lang.String" order="BEFORE" 
keyProperty="id">
select uuid()

insert into user(id,username,birthday,sex,address) 
         values(#{id},#{username},#{birthday},#{sex},#{address})
insert>
注意这里使用的order是“BEFORE

8.更新和删除用户

更新和删除操作差不多,就一起写了


    <delete id="deleteUser" parameterType="int">
      DELETE FROM user WHERE id =#{id}
    delete>
    
    <update id="updateUser" parameterType="com.aust.model.User">
      UPDATE user SET username=#{username},password=#{password},nickname=#{nickname} WHERE id = #{id}
    update>

junit测试

//测试删除用户
    @Test
    public void deleteUserTest(){
        //用于加载mybatis配置文件的输入流
        InputStream is = null;
        try {
            is = Resources.getResourceAsStream("SqlMapperConfig.xml");

        } catch (IOException e) {
            System.out.println("加载mybatis配置文件出错");
            e.printStackTrace();
        }
        //获取会话工厂
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
        //获取会话
        SqlSession session = factory.openSession();
        //返回的是受影响的行数
        int a = session.delete("test.deleteUser",10);
        System.out.println(a);
        //提交事务
        session.commit();
        session.close();
    }

    //测试更新用户
    @Test
    public void updateUserTest(){
        //用于加载mybatis配置文件的输入流
        InputStream is = null;
        try {
            is = Resources.getResourceAsStream("SqlMapperConfig.xml");

        } catch (IOException e) {
            System.out.println("加载mybatis配置文件出错");
            e.printStackTrace();
        }
        //获取会话工厂
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
        //获取会话
        SqlSession session = factory.openSession();
        User u = new User();
        u.setId(1);
        u.setUsername("niuli");
        u.setPassword("123456");
        u.setNickname("牛李");
        u.setStatus(2);
        //返回的是受影响的行数
        int a = session.update("test.updateUser",u);
        System.out.println(a);
        //提交事务
        session.commit();
        session.close();
        //获取主键
    }

一个mybatis的基本入门程序结束,项目结构如下
Mybatis学习记录(一)--Mybatis入门_第6张图片


项目示例:

SSM框架整合: https://github.com/nl101531/JavaWEB

自己做的一个项目: https://github.com/nl101531/AUSTOJ

你可能感兴趣的:(mybatis,javaWEB实战)