• mybatis学习:二、 Mybatis的Dao开发、mybatis-config.xml文件的详情


    3. Mybatis的Dao开发

    ​ 使用Mybatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper接口开发方法。

    3.1 Mybatis的核心对象

    • SqlSessionFactoryBuilder

      ​ SqlSessionFactoryBuilder用于创建SqlSessionFacoty,SqlSessionFacoty一旦创建完成就不需要SqlSessionFactoryBuilder了,因为SqlSession是通过SqlSessionFactory生产,所以可以将SqlSessionFactoryBuilder当成一个工具类使用,最佳使用范围是静态代码块中的局部变量

    • SqlSessionFactory

      ​ SqlSessionFactory是一个接口,接口中定义了openSession的不同重载方法,SqlSessionFactory的最佳使用范围是整个应用运行期间,一旦创建后可以重复使用,通常以单例模式管理SqlSessionFactory。

    • SqlSession

    1. SqlSession是一个面向用户的接口, sqlSession中定义了数据库操作,默认使用DefaultSqlSession实现类。

    2. SqlSession的实现类即DefaultSqlSession,此对象中对操作数据库实质上用的是Executor

    3. 每个线程都应该有它自己的SqlSession实例。SqlSession的实例不能共享使用,它也是线程不安全的。因此最佳的范围是请求或方法范围。绝对不能将SqlSession实例的引用放在一个类的静态字段或实例字段中。
      4. 打开一个 SqlSession;使用完毕就要关闭它。通常把这个关闭操作放到 finally 块中以确保每次都能执行关闭。

    3.2 传统的DAO开发模式

    ​ 程序员需要写dao接口和dao实现类。

    ​ 需要向dao实现类中注入SqlSessionFactory,在方法体内通过SqlSessionFactory创建SqlSession

    步骤:

    1. 编写到接口以及实现类
    import java.util.List;
    
    public interface IUserDao {
    	/**
    	 * 根据ID查询User
    	 * @param id  用户Id
    	 * @return  用户信息
    	 * @throws Exception
    	 */
    	public User findUserById(int id) throws Exception;
    	
    	/**
    	 * 根据用户的名字模糊查询
    	 * @param name 用户的username
    	 * @return  一组用户
    	 * @throws Exception
    	 */
    	public List<User> findUserByName(String name) throws Exception;
    	
    	/**
    	 * 添加用户
    	 * @param user 用户信息
    	 * @return 包含主键的用户
    	 * @throws Exception
    	 */
    	public User addUser(User user) throws Exception;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    public class UserDaoImpl implements IUserDao {
    	//需要往UserDaoImpl注入SQLSessionFactory
    	private SqlSessionFactory sqlSessionFactory;
    	
    	//通过构造方法注入
    	public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
    		this.sqlSessionFactory = sqlSessionFactory;
    	}
    
    	@Override
    	public User findUserById(int id) throws Exception {
    		/**
    		 * 1.得到SqlSession
    		 * 2.调用SqlSession对应的方法(selectOne)来操作数据库
    		 * 3.关闭SqlSession
    		 * 4.返回结果
    		 */
    		SqlSession sqlSession = sqlSessionFactory.openSession();
    		User user = sqlSession.selectOne("test.findUserById", id);
    		sqlSession.close();
    		return user;
    	}
    
    	@Override
    	public List<User> findUserByName(String name) throws Exception {
    		/**
    		 * 1.得到SqlSession
    		 * 2.调用SqlSession对应的方法(selectList)来操作数据库
    		 * 3.关闭SqlSession
    		 * 4.返回结果
    		 */
    		SqlSession sqlSession = sqlSessionFactory.openSession();
    		List<User> users = sqlSession.selectList("test.findUserByName", "%"+name+"%");
    		sqlSession.close();
    		return users;
    	}
    
    	@Override
    	public void addUser(User user) throws Exception {
    		/**
    		 * 1.得到SqlSession
    		 * 2.调用SqlSession对应的方法(insert)来操作数据库
    		 * 3.提交事务
    		 * 4.关闭SqlSession
    		 */
    		SqlSession sqlSession = sqlSessionFactory.openSession();
    		sqlSession.insert("test.addUser", user);
    		sqlSession.commit();
    		sqlSession.close();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    1. 编写SQL映射文件

      
      <select id="findUserById" parameterType="int" resultType="org.csmf.mybatis.entity.User">
      		select * from t_user where id = #{id}
      select>
      
      <select id="findUserByName" parameterType="string" resultType="org.csmf.mybatis.entity.User">
      		select * from t_user where username like #{name}
      select>
      <!—添加用户-->
      <insert id="addUser" parameterType="org.csmf.mybatis.entity.User">
      		<selectKey order="AFTER" resultType="int" keyProperty="id">
      			select last_insert_id()
      		selectKey>
      		insert into t_user(username,password,sex,brithday,address) 
      			values(#{username},#{password},#{sex},#{brithday},#{address})
      insert>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16

    总结:

    原始Dao开发中存在以下问题:

    • Dao方法体存在重复代码:通过SqlSessionFactory创建SqlSession,调用SqlSession的数据库操作方法

    • 调用sqlSession的数据库操作方法需要指定statement的id,这里存在硬编码,不得于开发维护。

    3.3 Mapper代理模式

    ​ Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。

    Mapper接口开发需要遵循以下规范:

    1. 在mapper.xml中namespace写的是对应Mapper接口的全限定名

    >   [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vzXBi4kN-1669618738987)(assets/image-20220806114843395.png)]

    1. Mapper接口方法名和Mapper.xml中定义的每个statement的id相同

    2. Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
      在这里插入图片描述

    实现:

    UserMapper.xml:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ahqabpln-1669618738989)(assets/wps1.jpg)]

    UserMapper接口:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IwjOA0D4-1669618738991)(assets/wps2.jpg)]

    测试代码:

    import java.io.IOException;
    import java.io.InputStream;
    
    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.csmf.mybatis.entity.User;
    import org.junit.Before;
    import org.junit.Test;
    
    /**
     * 测试UserMapper的测试类
     * @author pactera
     *
     */
    public class UserMapperTest {
    	private SqlSessionFactory sqlSessionFactory;
    	@Before
    	public void setUp(){
    		InputStream inputStream = null;
    		try {
    			inputStream = Resources.getResourceAsStream("mybatis-config.xml");
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    	}
    	@Test
    	public  void testFindUserById() throws Exception{
    		SqlSession sqlSession = sqlSessionFactory.openSession();
    		//创建UserMapper的休息,Mybatis可以自动生成UserMapper接口的代理对象
    		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    		User user = userMapper.findUserById(2);
    		System.out.println(user);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    总结:

    • selectOne和selectList

    动态代理对象调用sqlSession.selectOne()和sqlSession.selectList()是根据mapper接口方法的返回值决定,如果返回list则调用selectList方法,如果返回单个对象则调用selectOne方法。

    • namespace

    mybatis官方推荐使用mapper代理方法开发mapper接口,程序员不用编写mapper接口实现类,使用mapper代理方法时,输入参数可以使用包装类或map对象,保证dao的通用性。

    4. mybatis-config.xml文件的详情

    mybatis的全局配置文件SqlMapConfig.xml,配置内容如下:

    properties(属性) 加载properties文件

    settings(全局配置参数) 缓存

    typeAliases(类型别名) 类型别名

    typeHandlers(类型处理器)

    objectFactory(对象工厂)

    plugins(插件) 通用Mapper 分页插件

    environments(环境集合属性对象)

    environment(环境子属性对象)

    transactionManager(事务管理)

    dataSource(数据源)

    mappers(映射器)

    4.1 properties属性

    ​ 在实际开发中,我们通常会将数据库连接参数单独配置在db.properties中,只需要在mybatis-config.xml中加载db.properties的属性值。这样我们在mybatis-config.xml中就不需要对数据库连接参数硬编码。

    ​ 将数据库连接参数只配置在db.properties中,原因:方便对参数进行统一管理,其它xml可以引用该db.properties。

    db.properties文件:

    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
    jdbc.username=root
    jdbc.password=root
    
    • 1
    • 2
    • 3
    • 4

    mybatis-config.xml引用properties文件:

    	
    	<properties resource="db.properties">properties>
    	
    	<environments default="development">
    		
    		<environment id="development">
    			
    			<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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    4.2 settings全局参数配置

    ​ mybatis框架在运行时可以调整一些运行参数。

    ​ 比如:开启二级缓存、开启延迟加载。

    全局参数将会影响mybatis的运行行为。

    配置选项描述可选值默认值
    cacheEnabled全局启用或禁用任何Mapper中配置的缓存true|falsetrue
    lazyLoadingEnabled全局启用或禁用延迟加载。当启用后,所有的关系都将被延迟加载。可以通过使用特定关系上的fetchType属性来取代该值。true|falsefalse
    aggressiveLazyLoading当启用时,具有惰性加载属性的对象将完全在调用任何惰性属性时加载。否则,每个属性都将按需加载。true|falsetrue
    multipleResultSetsEnabled允许或不允许从单个语句返回多个结果集(需要兼容的驱动程序)true|falsetrue
    useColumnLabe使用列标签,而不是列名称。不同的驱动程序在这方面的行为也有所不同。请参考驱动程序文档,或测试这两种模式,以确定驱动程序的行为方式。true|falsetrue
    useGeneratedKeys允许JDBC支持已生成的密钥。这时需要一个兼容的驱动程序。这个设置强制生成的键在设置为true时使用,因为一些驱动程序拒绝兼容性但仍然可以工作(例如Derby)。true|falsefalse
    autoMappingBehavior指定MyBatis是否以及如何自动将列映射到字段/属性。NONE禁用自动映射。PARTIAL只自动映射简单,非嵌套的结果集。FULL将自动映射任何复杂度的结果集(包含嵌套或非嵌套的)。NONE, PARTIAL, FULLPARTIAL
    defaultExecutorType配置默认的执行器(Executor):
    SIMPLE: 简单执行器
    REUSE:重用prepared statement的执行器
    BATCH:重用statement并且执行批量更新的执行器
    SIMPLE REUSE BATCHSIMPLE
    defaultStatementTimeout设置数据库超时时间(单位:秒)任何正数Not Set (null)
    safeRowBoundsEnabled允许在嵌套语句上使用行边界。true|falsefalse
    mapUnderscoreToCamelCase是否开启, 数据库列:A_COLUMN自动映射为属性:aColumntrue|falsefalse
    localCacheScopeMyBatis使用本地缓存来提高查询效率,本地缓存默认Scope是:SESSION, 在同一次SESSION期间执行的所有查询都将被缓存.
    localCacheScope=STATEME:本地会话将仅用于stateme的执行,对同一Sql会话的两个不同调用之间将不共享任何数据
    SESSION|STATEMENTSESSION
    jdbcTypeForNull指定空值的JDBC类型,当没有为参数提供特定的JDBC类型时。一些驱动程序需要指定列JDBC类型,常用的值:NULL,VARCHAR,OTHERJdbcType enumeration.Most common are: NULL,VARCHAR and OTHEROTHER
    lazyLoadTriggerMethods指定哪个对象的方法会触发延迟加载方法名列表,多个方法名之间使用逗号分割equlas,
    clone,
    hashCode,
    toString
    defaultScriptingLanguage指定动态SQL生成时默认使用的语言。一个类型的别名或完全限定的类名。
    callSettersOnNulls指定在检索到的值为空时,是否会调用设置器或映射的put方法。当您依赖于Map.keySet()或空值初始化时,它很有用。请注意原语,如(int、布尔值等)。将不会被设置为null。true|falsefalse
    logPrefix指定MyBatis将添加到日志记录器名称中的前缀字符串。任何字符串未设置
    logImpl指定MyBatis应该使用哪些日志记录实现类。如果此设置日志记录类不存在,则将自动发现日志记录实现。SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING为设置
    proxyFactory代理工厂指定MyBatis将用于创建能够实现延迟加载功能的对象的代理工具。CGLIB|JAVASSISTCGLIB

    4.3 typeAliases(类型别名)

    4.3.1 mybatis支持别名:
    别名映射的类型
    _bytebyte
    _longlong
    _shortshort
    _intint
    _integerint
    _doubledouble
    _floatfloat
    _booleanboolean
    stringString
    byteByte
    longLong
    shortShort
    intInteger
    integerInteger
    doubleDouble
    floatFloat
    booleanBoolean
    dateDate
    decimalBigDecimal
    bigdecimalBigDecimal
    4.3.2 自定义别名:

    在mybatis-config.xml中配置:

    <typeAliases>
    	
    	<typeAlias alias="user" type="org.csmf.mybatis.entity.User"/>
    	
    	<package name=" org.csmf.mybatis.entity "/>
    	<package name="其它包"/>
    typeAliases>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    使用别名:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nR6V6bm3-1669618738993)(assets/wps3.jpg)]

    4.4 mappers(映射器)

    Mapper配置的几种方法:

    使用相对于类路径的资源

    如:

    使用完全限定路径

    如:

    使用mapper接口类路径

    如:

    注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。

    注册指定包下的所有mapper接口

    如:

    注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。

  • 相关阅读:
    python开发api接口框架
    C语言--atoi函数详解及模拟实现
    网络请求urllib库使用总结
    微信小程序Jenkins持续集成打包发布流程
    刷题笔记22——二叉搜索树BST
    什么是扩散模型(Diffusion Models),为什么它们是图像生成的一大进步?
    paddle2.3和torch1.8在SentenceBert上的性能对比
    JVM【类加载与GC垃圾回收机制】
    echarts 折线图详细配置
    Linux nload显示当前的网络使用情况
  • 原文地址:https://blog.csdn.net/H215919719/article/details/128079926