Mybatis框架-核心配置文件中标签设置,sqlSession工厂模式,mapper代理方式

mybatis 框架


概述

mybatis是一个优秀的基于 java 的持久层框架,它内部封装了 jdbc,使开发者只需要关注 sql 语句本身,而不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁杂的过程
面试题: mybatis是基于ORM思想的半自动持久层框架- ORM对象关系映射:让实体类与表产生映射关系,操作实体类等同于操作表

开发步骤

  1. 创建maven仓库工程,添加依赖
  2. 编写实体类
  3. 编写映射配置文件(同包同名)
  4. 编写核心配置文件
  5. 编写测试类
    • 加载配置文件
    • 创建sqlSessionFactory
    • 创建sqlSession
    • sqlSession调用方法
    • 释放资源,

      核心配置文件中的标签设置

      所有标签,且按照配置标签既定的顺序排列
      properties?, settings?, typeAliases?, typeHandlers?, objectFactory?, objectWrapperFactory?, reflectorFactory?, plugins?, environments?, databaseIdProvider?, mappers?

1. properties标签 : 加载外部properties配置文件 resource

两个属性:

  • resource属性:用于指定 properties 配置文件的位置,要求配置文件必须在类路径下resource="jdbcConfig.properties"
  • url属性: 统一资源定位符 http://localhost:8080/mystroe/CategoryServlet

    2. typeAliases标签: 自定义别名

    两种定义:
  • 单个别名定义
    <typeAlias alias="user" type="com.itheima.domain.User"/>
  • 批量别名定义,扫描整个包下的类,别名为类名(首字母大写或者小写都可以)
    <package name="com.itheima.domain"/>

    3. environments标签: 数据库环境的配置,支持多环境配置


<!--.数据源环境-->
    <environments default="development">
        <environment id="development">
            <!--事物类型 jdbc -->
            <transactionManager type="JDBC"></transactionManager>
            <!--使用mybatis提供的连接池-->
            <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>

<environments default="development"> 指定默认的环境名称
<environments id="development"> 指定当前环境的名称
<transactionManager type="JDBC"> 指定事务管理类型是jdbc
<dataSource type="POOLED"> 指定当前数据源类型是连接池
<proprety name= value=> 数据源配置的基本参数

事物管理器(transactionManager)类型,两种

  • JDBC: 这个配置就是直接使用了JDBC的提交和回滚设置,它依赖于从数据源得到的连接来管理事物作用域
  • managed: 这个配置几乎没做什么。它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。 默认情况下它会关闭连接,然而一些容器并不希望这样,因此需要将 closeConnection 属性设置为 false 来阻止它默认的关闭行为。
    数据源(dataSource)类型, 三种
  • unpooled: 这个数据源的实现只是每次被请求时打开和关闭连接。
  • POOLED: 实现利用“池”的概念将 JDBC 连接对象组织起来。
  • JNDI: 实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。

    4. mapper标签: 映射器,作用:加载映射

  • 方式一: 使用相对于类路径的资源引用
    <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
  • 方式二: 使用完全限定资源定位符(URL)
    <mapper url="file:///var/mappers/AuthorMapper.xml"/>
  • 方式三: 使用映射器接口实现类的完全限定类名
    <mapper class="org.mybatis.builder.AuthorMapper"/>
  • 方式四: 将包内的映射器接口实现全部注册为映射器,只能在mapper代理开发中使用,相当于扫包,指定包下的所有实现类. 常用的方式
    <package name="org.mybatis.builder"/>

MyBatis相应API介绍sqlSession

1.sqlSession工厂构建器(构建者模式)SqlSessionFactory build(InputSream inputStream)

通过加载mybatis的核心文件的输入流的形式构建一个SqlSessionFactory对象

//String resource = "org/mybatis/builder/mybatis-congfig.xml";
InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();//构建者设计模式
SqlSessionFactory factory = builder.build(inputStream);

2.sqlSession工厂对象(工厂模式)

工厂的作用就是造 sqlSession 会话对象. 工厂模式就是为了解耦和

SqlSessionFactory 有多个个方法创建SqlSession 实例。常用的有如下两个:
|方法|解释|
|:------:|:------------|
|openSession|会默认开启一个事务,但事务不会自动提交,也就意味着需要手动提交该事务,更新操作数据才会持久化到数据库中|
|openSession(boolean autoCommit)|参数为是否自动提交,true(自动提交)|

3.sqlSession会话对象(重要)

SqlSession 实例在 MyBatis 中是非常强大的一个类。在这里你会看到所有执行语句、提交或回滚事务和获取映射器实例的方法。

SqlSession sqlSession = sqlSessionFactory.openSession(true);

  • 执行sql语句方法:
//查询
<T> T selectOne(String statement, Object parameter) 
<E> List<E> selectList(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() 

mapper代理方式

1.Mybatis的Dao层实现有两种方式:

1-传统开发方式: 手动对Dao层进行实现,在Dao层编写接口,接口实现类,实现方法
2-代理开发方式: 编写Mapper 接口(相当于Dao 接口),由Mybatis 框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。

2.mapper代理开发要求(规范):

mapper接口开发需要遵循规范 示例
1-接口和映射文件要同包同名 java.cn.ppvir.dao.UserMapper.java和resources/cn/ppvir/dao/UserMapper.xml
2-持久层映射配置中mapper标签的namespace属性取值必须是持久层接口的全限定类名 public interface Usermapper{}---<mapper namespace=‘cn.ppvir.dao.UserMapper‘>
3-sql语句的配置标签<select><insert><delete><update>的id属性必须和持久层接口的方法名相同 User findById(Int id)---<select id="findById">
4-parameterType要和接口中的传入参数类型相同 User findById(int id)---<select parameterType="int">
5-resultType要和接口中的返回值结果类型相同 User findById(int id)---<select resultType="user">

3.代码演示(使用mapper代理开发)

模糊查询中${} 和 #{}的区别

#{}表示一个占位符
#{}可以实现prepareStatment向占位符中设置值,自动进行JDBC和java类型转换,防止sql注入
#{}可以接收简单类型值或pojo属性值,如果parameterType传输基本数据类型,值随便写

${}表示拼接sql串
${}是将传入的参数原样拼接在sql中,不进行jdbc类型转换
${}可以接收简单类型值或pojo属性值,如果parameterType传输基本数据类型,${}括号中只能是value

  1. pom
  2. 核心配置文件 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>
<!--1.引入配置文件-->
    <properties resource="jdbc.properties"/>
<!--2.别名typeAliases-->
    <typeAliases>
        <!--单个别名定义-->
        <typeAlias type="it.ppvir.domain.User" alias="user"></typeAlias>
        <!--批量别名定义-->
        <package name="it.ppvir.domain"/>
    </typeAliases>
<!--3.数据源环境-->
    <environments default="develop">
        <environment id="develop">
            <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.加载映射文件-->
    <mappers>
        <!--方式一:    使用相对于类路径的资源引用-->
        <mapper resource="it/ppvir/dao/UserMapper.xml"/>
        <!--方式四:将包内的映射器接口实现全部注册为映射器-->
        <!--<package name="it.ppvir.dao"/>-->
    </mappers>
</configuration>
  1. 实体类 get set toString
public class User {
    private int id;
    private String username;
    private String password;
  1. 映射配置文件 UserMapper.xml resources/it/ppvir/dao/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">
<!--命名空间-->
<mapper namespace="it.ppvir.dao.UserMapper">
<!--查询所有 List<User> findAll();-->
    <select id="findAll" resultType="user">
        select * from users;
    </select>
<!--通过id 查询用户User findUserById(int id);-->
    <select id="findUserById" parameterType="int" resultType="user">
        select * from users where id=#{id}
    </select>

<!--添加user void addUser(User user);-->
    <insert id="addUser" parameterType="user">
          <!--keyProperty:将添加成功后的id值查询出来封装到那个实体属性上
           resultType:主键类型
           order:SELECT LAST_INSERT_ID()执行时机是在insert后面-->
        <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
            SELECT LAST_INSERT_ID()
        </selectKey>
        insert into users VALUES (#{id},#{username},#{password})
    </insert>

<!--删除用户  void delUserById(int id);-->
    <delete id="delUserById" parameterType="int">
        DELETE FROM users where id=#{id}
    </delete>

<!--修改用户信息  void modUserById(int id);-->
    <update id="modUserById" parameterType="user">
        UPDATE  users SET username=#{username} where id=#{id}
    </update>

<!--模糊查询  List<User> findUserByLikeUsername(String username);-->
    <select id="findUserByLikeUsername" resultType="user" parameterType="String">
        select * from users where username like '${value}'
    </select>
</mapper>
  1. 接口 接口和映射同包同名 方法名和id值相同 返回值和resultType相同 形参和ParameterType相同
public interface UserMapper {
    //插入数据 addUser
    void addUser(User user);
    //查询所有用户 findAll
    List<User> findAll() throws IOException;
    //查询用户通过id findUserById
    User findUserById(int id);
    //通过Id删除用户 delUserById
    void delUserById(int id);
    //通过id修改用户信息 modUserById
    void modUserById(User user);
    //模糊查询
    List<User> findUserByLikeUsername(String username);
}
  1. 测试类
public class UserMapperTest {
    /**
     * 接口实现类测试 传统方法
     * @throws IOException
     */
    @Test
    public void test01() throws IOException {
        UserMapper userMapper = new UserMapperImpl();
        List<User> users = userMapper.findAll();
        System.out.println(users);
    }
    /**
     *   mapper代理方式 实现findAll方法
     */
    @Test
    public void test02() throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = factory.openSession();

        //使用mapper代理方式
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);//通过接口获取mapper代理对象
        List<User> users = mapper.findAll();//使用代理对象调用接口的方法
        System.out.println(users);
    }
    @Test
    /**
     *  mapper代理方式 实现 User findUserById(int id)
     */
    public void test03() throws IOException {
        InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //mapper代理
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.findUserById(19);
        System.out.println(user);
    }
    @Test
    /**
     *  mapper代理方式   添加用户void addUser(User user); 并且获取到添加后user 的id
     */
    public void test04() throws IOException {
        InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //封装实体类
        User user = new User();
        user.setUsername("euuruqwo");
        user.setPassword("123123");
        System.out.println("添加前"+user);

        //mapper代理
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        mapper.addUser(user);
        sqlSession.commit();
        System.out.println("添加后"+user);
    }
    @Test
    /**
     *  mapper代理方式 删除用户
     */
    public void test05() throws IOException {
        InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //mapper代理
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        mapper.delUserById(25);
    }
    @Test
    /**
     *  mapper代理方式 修改用户
     */
    public void test06() throws IOException {
        InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //封装实体类
        User user = new User();
        user.setId(2);
        user.setUsername("2222222");
        //mapper代理
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        mapper.modUserById(user);
    }
    //模糊查询测试
    @Test
    public void queryLike() throws IOException {
        InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession = build.openSession();

        //mapper代理对象
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> users = mapper.findUserByLikeUsername("%张%");
        for (User user : users) {
            System.out.println(user);
        }
    }
}

Mybatis框架-核心配置文件中标签设置,sqlSession工厂模式,mapper代理方式

上一篇:python基础01 Hello World


下一篇:从0系统学Android-2.5更多隐式Intent用法