Mybatis框架配置详解及简单应用

1、介绍

       Mybatis是一个应用于dao层框架(持久层框架)。持久层:数据访问层。

       他也是一个ORM框架(对象 关系 映射),相比于hibernate,他是一个半自动的框架。

2、优点

1.Jdbc的缺点:

       重复工作多,每次都要创建连接(连接池),获得执行sql语句的对象,执行sql语句,然后处理结果集,最后释放资源。

       为处理结果集,工作非常复杂,参数的处理比较麻烦。

2.Mybatis的优点:

       让程序员关注sql语句。

       参数的设置,结果集的处理,框架自动帮你生成。

       简单易学。

       灵活。

Mybatis入门

1、准备数据库

2、准备实体类

3、导包

    (1).Mybatis包


(2).数据库驱动包

4、书写配置文件

(1).核心配置文件

       sqlMapConfig.xml

①  .导入约束

       <?xmlversion="1.0" encoding="UTF-8" ?>

       <!DOCTYPEconfiguration
        PUBLIC "-//mybatis.org//DTDConfig 3.0//EN"
       "http://mybatis.org/dtd/mybatis-3-config.dtd">

②  .配置内容

<!--环境-->

<environmentsdefault="development">
    <environmentid="development">
        <transactionManagertype="JDBC"></transactionManager>
        <dataSourcetype="POOLED">
            <propertyname="driver"value="com.mysql.jdbc.Driver"></property>
            <propertyname="url"value="jdbc:mysql://localhost:3306/mybatis_demo"></property>
            <propertyname="username" value="root"></property>
            <propertyname="password" value="123"></property>
        </dataSource>
    </environment>
</environments>
<!--映射-->
<mappers>
    <mapperresource="cn/hd/pojo/UserMapper.xml"></mapper>
</mappers>

(2).映射文件

<?xml version="1.0"encoding="UTF-8" ?>


<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTDMapper 3.0//EN"
       "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="test">
    <selectid="findUserById" parameterType="int"resultType="cn.hd.pojo.User" >
        SELECT * FROM t_user WHERE id=  #{id}
    </select>

    <selectid="findUserByName" parameterType="String"resultType="cn.hd.pojo.User">
        SELECT * FROM t_user WHEREusername LIKE "%"#{username}"%"
    </select>
    <insert id="addUser"parameterType="cn.hd.pojo.User">
            <!--
            keyProperty:将查询到主键设置到parameterType指定的对象的哪个属性
            order:SELECT LAST_INSERT_ID()的执行顺序,相对于insert语句来说他的执行顺序。
        -->
            <selectKeykeyProperty="id" resultType="Integer" order="AFTER">
                SELECT LAST_INSERT_ID()
            </selectKey>
         INSERT INTOt_user(name,sex,address,balance) VALUES (#{name},#{sex},#{address},#{balance})
    </insert>

    <delete id="deleteUser"parameterType="Integer" >
        DELETE FROM t_user WHERE id = #{id}
    </delete>

    <update id="updateUser"parameterType="cn.hd.pojo.User">
        UPDATE t_user SET name = #{name}WHERE id = #{id}
    </update>

</mapper>

(3).log4j

# Global logging configuration

#在开发环境下日志级别设置为debug,生产环境下设置成info或error
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

5、配置介绍

1.SqlMapConfig

命名可以修改,位置任意。当然我们建议的名字是SqlMapConfig,位置放在目录下。

(1).environments

表示SqlMapConfig的运行环境。

(2)运行环境

数据库的基本信息,事务。

(3).mppers

表示数据源。

2.UserMapper.xml

       名字可以修改,位置任意。

名字建议User.xml(ibatis)       UserMpper.xml(Mybatis)我们建议命名为类名+Mapper.xml

所有的sql语句都写在USerMaper中。

mapper的namespace属性

       解决在不同表中查询的sql语句的名字冲突,比如:

User表 findById  order表 findById名字冲突,不识别,所以可以给不同的表的数据源加上一个前缀,对应的是namespace属性。

<select id="findUserById"parameterType="int" resultType="cn.hd.pojo.User" >

                     SELECT* FROM t_user WHERE id =  #{id}
</select>

id 给当前的sql语句起一个识别id,parameterType:参数类型

resultType:结果集封装的类型。

       #{id}:占位符    里面对的名字任意

简单实用的Mybatis的增删改查

1.查找一个用户

<!--
    mapper:映射
    namespace="test":确保调用方法的唯一性,避免多张表多个mapper调用方法重复
    parameterType:参数类型
    resultType:结果集封装的类型

-->
<mapper namespace="test">
    <selectid="findUserById" parameterType="int"resultType="cn.hd.pojo.User" >
        SELECT * FROM t_user WHERE id=  #{id}
    </select>

测试代码

@Test

public voidfun1() throws IOException {

    InputStream in =Resources.getResourceAsStream("sqlMapConfig.xml");
    /*获得SessionFactory,读取流*/
    SqlSessionFactory sessionFactory =new SqlSessionFactoryBuilder().build(in);

    SqlSession sqlSession =sessionFactory.openSession();
    User user =sqlSession.selectOne("test.findUserById", 1);
    System.out.println(user);
    sqlSession.close();
}

2.通过名字模糊查找用户

<!--
    #  占位符
    $  字符串拼接  sql注入(不建议使用)
        也可以使用占位符    1.直接将整个当成参数在代码中传递时手动拼接%%
                           2.sql提供的
   $和#区别:#里面的变量名随意 ${变量名} 不能随便写,如果是  常用类型  必须用value

-->
<select id="findUserByName" parameterType="String"resultType="cn.hd.pojo.User">
    SELECT * FROM  t_user WHERE name LIKE"%"#{name}"%"
</select>

测试代码

@Test

public void fun2() throws IOException {

    InputStream in =Resources.getResourceAsStream("sqlMapConfig.xml");
    /*获得SessionFactory,读取流*/
    SqlSessionFactory sessionFactory =new SqlSessionFactoryBuilder().build(in);
    SqlSession sqlSession =sessionFactory.openSession();
    List<User>list = sqlSession.selectList("test.findUserByName", "");
    System.out.println(list);
    sqlSession.close();
}

3.添加一个用户

<!--/*如果参数是引用类型 占位符的赋值方式为 ognl表达式的方式 #{属性名}*/-->

<insert id="addUser"parameterType="cn.hd.pojo.User">
     INSERT INTOt_user(name,sex,address,balance) VALUES (#{name},#{sex},#{address},#{balance})
</insert>

测试代码

@Test

public void fun3() throws IOException {
    InputStream in =Resources.getResourceAsStream("sqlMapConfig.xml");
    /*获得SessionFactory,读取流*/
    SqlSessionFactory sessionFactory =new SqlSessionFactoryBuilder().build(in);
    SqlSession sqlSession =sessionFactory.openSession();
    User user = new User();
    user.setName("杨二狗");
    user.setAddress("坑");
    user.setSex("nv");
    user.setBalance(1000);
    int insert =sqlSession.insert("test.addUser", user);
    System.out.println(insert);
    sqlSession.commit();
    System.out.println(insert);
    sqlSession.close();
}

这种操作并不会把新生成的记录中的主键保存到对象中,但是有一种需求,在保存用户的同时,要利用用户主键去保存一条新的记录。所以为满足该需求,提供了新的标签。

<!—

   keyProperty:将查询到主键设置到parameterType指定的对象的哪个属性
    order:SELECTLAST_INSERT_ID()的执行顺序,相对于insert语句来说他的执行顺序。
 -->
<!--如果参数是引用类型 占位符的赋值方式为 ognl表达式的方式  #{属性名}-->
<insert id="addUser" parameterType="cn.hd.pojo.User">
      <selectKeykeyProperty="id" order="AFTER"resultType="int">
          SELECT LAST_INSERT_ID()
      </selectKey>

     INSERT INTOt_user(name,sex,address,balance) VALUES (#{name},#{sex},#{address},#{balance})
</insert>

keyProperty:对应的是对象中的属性名KeyCloumn对应的是数据库中的字段名。

        resultType:对应的是返回值结果类型(intString)分别对应数据库生成代理主键的策略。Int 对应自动递增,String对应uuid。

        order 顺序跟数据库底层有关,自动递增默认先添加数据,再生成主键 。但是uuid就是先生成id再去添加数据。

如果是增删改,必须要提交事务才能持久化到数据库。

查询语法

       SELECT  LAST_INSERT_ID()适用于自动递增。

       SELECT  uuid()      适用于uuid。通过id删除用户

4.通过id删除用户

<delete id="deleteUser"parameterType="Integer">

   DELETE  FROM t_user WHERE id =#{id}
</delete>

测试代码

@Test

public void fun4() throws IOException {
    InputStream in =Resources.getResourceAsStream("sqlMapConfig.xml");
    /*获得SessionFactory,读取流*/
    SqlSessionFactory sessionFactory =new SqlSessionFactoryBuilder().build(in);
    SqlSession sqlSession =sessionFactory.openSession();
    int delete =sqlSession.delete("test.deleteUser", 5);
    sqlSession.commit();
    System.out.println(delete);
    sqlSession.close();
}

5.通过id修改用户

<update id="updateUser"parameterType="cn.hd.pojo.User">

    UPDATEt_user SET name = #{name},sex = #{sex},address = #{address},balance=#{balance}WHERE id = #{id}
</update>

测试代码

@Test

public void fun5() throws IOException {
    InputStream in =Resources.getResourceAsStream("sqlMapConfig.xml");
    /*获得SessionFactory,读取流*/
    SqlSessionFactory sessionFactory =new SqlSessionFactoryBuilder().build(in);
    SqlSession sqlSession =sessionFactory.openSession();
    User user = new User();
    user.setId(8);
    user.setName("杨二狗");
    user.setAddress("水");
    user.setSex("男");
    user.setBalance(1000);
    int update =sqlSession.update("test.updateUser", user);
    sqlSession.commit();
    System.out.println(update);
    sqlSession.close();
}

原始dao层开发

package cn.hd.dao.impl;


import cn.hd.dao.UserDao;
import cn.hd.pojo.User;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

public class UserDaoImpl implements UserDao {

    private SqlSessionFactory sqlSessionFactory;

    public UserDaoImpl(SqlSessionFactorysqlSessionFactory) {
        this.sqlSessionFactory =sqlSessionFactory;
    }

    @Override
    public User findUserById(Integer id){

        SqlSession sqlSession = sqlSessionFactory.openSession();
        User user = sqlSession.selectOne("test.findUserById",1);
        sqlSession.commit();
        sqlSession.close();
        return user;
    }

    @Override
    public Integer addUser(User user) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        int insert = sqlSession.insert("test.addUser",user);
        sqlSession.commit();
        sqlSession.close();
        return insert;
    }

    @Override
    public Integer deleteUser(Integer id){
        return null;
    }
}

测试代码

package cn.hd.dao;


import cn.hd.dao.UserDao;
import cn.hd.dao.impl.UserDaoImpl;
import cn.hd.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;

public class Demo {

    private UserDao userDao;

    @Before
    public void before() throws IOException{
        InputStream in = Resources.getResourceAsStream("cn/hd/mapper/sqlMapConfig.xml");
        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(in);
        userDao = new UserDaoImpl(build);
    }
    @Test
    public void fun1(){
        User userById = userDao.findUserById(1);
        System.out.println(userById);
    }

}

 

dao层的mapper开发

       不用去写实现类,他会使用代理的方式自动生成实现代码,想要使用mapper开发,必须遵循以下原则:

1、         接口的名字建议和mapper映射文件的名字保持一致,并且在同一目录下。

namespace必须和接口的完整路径名保持一致。

2、         接口中的方法名必须和mapper中的id保持一致。


3、         方法的返回值和配置文件中的resultType保持一致。

4、         参数的类型必须保持一致。

在代码中,就不需要关注SqlSession对象的方法调用了insert、update、delete、selectOne、selectList

sqlSession.getMapper(UserMapper.class);

       返回一个接口的代理对象,直接调用该对象的方法即可。

@Test

public void fun1() throws IOException {
    InputStream in =Resources.getResourceAsStream("cn/hd/dao/sqlMapConfig.xml");
    SqlSessionFactory build = newSqlSessionFactoryBuilder().build(in);
    SqlSession sqlSession = build.openSession();
    UserMapper mapper =sqlSession.getMapper(UserMapper.class);
    User userById =mapper.findUserById(1);
    System.out.println(userById);
}

注意:使用mapper开发,它的参数永远只有一个,如果有多个参数,需要将多的参数封装成pojo类。

Mybatis自动识别接口中的方法的返回值,从而调用session.selectOne和selectList方法。

SqlMapConfig配置详解

配置文件中的属性顺序不能更改。

1、properties

设置配置信息

<!--自动读取properties文件-->

<propertiesresource="db.properties"></properties>

2、settings

全局设置 mybatis的二级缓存 设置mybatis的加载属性。
 3、 typeAliases

别名    

<!--别名-->

<typeAliases>
    <!--单个别名-->
    <typeAliastype="cn.hd.pojo.User" alias="user"></typeAlias>
    <!--包的扫描方式,多个别名,别名不区分大小写 cn.hd.pojo.User 使用User/user-->
    <packagename="cn.hd.pojo"></package>
</typeAliases>

决定着mapper.xml文件中的数据类型可以使用简短的名字。

<select id="findUserById"parameterType="Integer" resultType="user" >
 • typeHandlers                                      

               类型控制器,将数据库中的数据类型和Java中的数据类型进行匹配。一般情况下不需要我们去书写。
 • objectFactory
 • plugins 
• environments
 • environment 
• transactionManager 
• dataSource 
• databaseIdProvider
 • mappers

           映射文件,书写方式一共有四种。

        1、mapper

<mapper resource="cn/hd/sqlmapconfig/UserMapper.xml"></mapper>

        2、通过接口来读取配置文件

           ①.接口的名字必须和配置文件保持一致

           ②.接口和配置文件必须在同一目录下

<mapperclass="cn.hd.sqlmapconfig.UserMapper"></mapper>

        3、通过绝对路径来读取

<mapper url=""></mapper>

        4、读取的是接口的包名,因此要求多有的接口和对应的配置文件都要保持一致(名字和位置)

<packagename="cn.hd.sqlmapconfig"></package>

总结:推荐使用的第四种,你的接口和配置文件同名且在同一个包下。


发布了87 篇原创文章 · 获赞 381 · 访问量 10万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章