mybatis基础知识——学习笔记(2)

    xiaoxiao2025-05-24  10

    1.1 SqlSessionFactoryBuilder 通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory 将SqlSessionFactoryBuilder当成一个工具类使用即可,不需要使用单例管理,在需要创建SqlSessionFactory的时候,只需要new一次SqlSessionBuilder。 1.2 SqlSessionFactory 通过SqlSessionFactory创建SqlSession,使用单例模式管理SqlSessionFactory(工厂一旦创建使用一个实例) mybatis和spring整合后,使用单例模式管理sqlSessionFactory 1.3 SqlSession SqlSession是一个面向用户(程序员)的接口 SqlSession中提供了很多操作数据库的方法,如:selectOne、selectList SqlSession是线程不安全的,在SqlSession实现类中除了有接口中的方法(操作数据库的方法)还有数据域属性 SqlSession最佳应用场合在方法体类,定义成局部变量使用 2.2 原始Dao层开发方法 需要写dao接口和dao实现类,需要向dao实现类中注入SqlSessionFactory创建Sqlsession 接口实现类: private SqlSessionFactory sqlSessionFactory;          public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {         this.sqlSessionFactory = sqlSessionFactory;     }          @Override     public User findUserById(int id) throws Exception {         // TODO Auto-generated method stub         SqlSession sqlSession = sqlSessionFactory.openSession();         User user = sqlSession.selectOne("test.findUserById", id);         sqlSession.close();         return user;     }     @Override     public List<User> findUserByName(String username) throws Exception {         // TODO Auto-generated method stub         SqlSession sqlSession = sqlSessionFactory.openSession();         List<User> list = sqlSession.selectList("test.findUserByName",username);         sqlSession.close();         return list;     }     @Override     public void deleteUser(int id) throws Exception {         // TODO Auto-generated method stub         SqlSession sqlSession = sqlSessionFactory.openSession();         sqlSession.delete("test.deleteUser", id);         sqlSession.commit();         sqlSession.close();              } 开发问题:  a.dao接口实现类中存在大量的模版方法             b.调用sqlSession方法时将statement的id硬编码了             c.调用sqlSession方法时传入的变量,由于sqlSession是泛型,即使变量类型传入错误,在编译阶段也不会报错,不利于开发 2.3 mapper代理方法 需要mapper接口,相当于dao接口, 还需要编写mapper映射文件,遵循开发规范,mybaties则可以自动生成mapper接口实现代理对象 规范: a.namespace等于mapper接口的地址 b.mapper.java接口中的方法名和mapper.xml中statement的id一致 c.mapper.java接口中的输入参数类型和mapper.xml中指定类型一致 d.mapper.java接口中返回值和mapper.xml中指定返回类型一致 使用mapper代理: public void testFindUserById() throws Exception {         SqlSession sqlSession = sqlSessionFactory.openSession();         //创建UserMapper对象,mybatis自动生成mapper代理对象         UserMapper userMapper = sqlSession.getMapper(UserMapper.class);         //调用userMapper方法         User user = userMapper.findUserById(2);         System.out.println(user);     } 增加了映射文件需要在SqlMapConfig.xml中配置 3.1 SqlMapConfig.xml properties(属性) settings(全局配置参数) typeAliases(类型别名) typeHandlers(类型处理器) objectFactory(对象工厂) plugins(插件) environments(环境集合属性对象)     environment(环境子属性对象)         transactionManager(事务管理)         dataSource(数据源) mappers(映射器) 3.2 properties属性 需求:将数据库连接参数单独配置在db.properties中,只需要在SqlMapConfig中加载db.properties的属性值,在SqlMapConfig中不用对数据库连接参数硬编码。 将数据库连接参数只配置在db.properties中的原因:方便对参数进行统一管理,其他xml文件可以引用db.properties 配置: <configuration>     <properties resource="db.properties"></properties>     <!-- 和spring整合后 environment配置将废除 -->     <environments default="development">     <!-- 使用JDBC事务管理 -->         <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>     <mappers >     <!-- 加载映射文件 -->         <mapper resource="sqlMap/UserMapper.xml"></mapper>     </mappers> </configuration> 注意:Mybatis将按照下面的顺序加载属性 1.在properties元素体内定义的属性首先被读取 2.然后会读取properties元素中resource或url加载的属性,会覆盖已读取的同名属性 3.最后读取parameterType传递的属性,会覆盖已读取的同名属性 因此,parameterType传递的属性具有最高优先级,#{name}传入的参数会覆盖之前的name属性 建议:不要在properties元素体内添加任何属性值,只将属性值定义在properties文件中,在properties文件中定义属性名要有一定的特殊性,如xxx.xxxx.xxx 3.3 setting全局参数配置 mybaties在运行时可以调整一些运行参数,如:开启二级缓存、开启延迟加载 全局参数会影响mybatis的运行行为 3.4 typeAliases别名 需求:在mapper.xml中定义了很多的statement,statement需要parameterType和resultType指定输入输出类型。如果在指定类型时输入类型的全路径,不便进行开发,可以针对输入输出参数定义一些别名。 mybaties默认支持别名,针对pojo需要自定义别名 配置:     <typeAliases>         <!-- 单个别名定义 -->         <typeAlias type="mybatis.po.User" alias="user"/>         <!-- 批量定义别名         指定报名,自动扫描包中的pojo类,自动定义别名,别名为类名,首字母可大写可小写 -->         <package name="mybatis.po"/>     </typeAliases>      3.5 typeHandlers类型处理器 mybatis中通过typeHandlers完成jdbc类型和java类似的转换 通常情况下,mybatis提供的类型处理器满足日常需要,不需要自定义 3.5 mappers     <mappers >     <!-- 加载映射文件 -->         <!-- 通过resource加载单个映射文件 -->         <mapper resource="sqlMap/UserMapper.xml"></mapper>         <!-- 通过mapper接口加载映射文件,需要将mapper接口类名和mapper.xml映射文件名称保持一致,并且在一个目录中         以上条件前提,使用mapper代理的方法 -->         <mapper class="mybatis.dao.UserMapper"></mapper>         <!-- 批量加载mapper 指定mapper接口的包名,自动扫描包中所有mapper进行加载         需要将mapper接口类名和mapper.xml映射文件名称保持一致,并且在一个目录中         以上条件前提,使用mapper代理的方法          -->         <package name="mybatis.dao"/>     </mappers> 推荐使用批量加载 3.6 输入映射(传递pojo的包装对象) 需求:完成用户信息的综合查询,需要传入很多查询条件(可能包括用户信息、商品信息、订单信息) 使用自定义包装类型的pojo,包装自己需要的复杂查询条件 在UserMapper.xml中定义用户信息综合查询(查询条件复杂,通过高级查询进行复杂关联查询) 3.7 输出映射 3.7.1 resultType 使用resultType进行映射,只有查询出来的列名和pojo的属性名一致,该列才可以映射成功 如果查询出来的列名和pojo的属性名完全不一致,则没有创建pojo对象 只要查询出来的列名和pojo的属性名有一个一致,就会创建pojo对象 3.7.2 resultMap 如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和属性名之间作一个映射关系 配置:         <!-- type result最终映射成的java对象类型,可以使用别名     id 对resultMap的唯一表示 -->     <resultMap type="user" id="userResultMap">         <!-- id查询结果集中的唯一标识         column :查询出来的别名         property:type指定的pojo类型中的属性名         最终resultMap对column和property作一个映射关系 -->         <id column="id_" property="id"/>         <!-- result:对普通列名映射定义 -->         <result column="username_" property="username"/>              </resultMap>          4 动态sql 4.1 什么是动态sql mybatis核心,对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接、组装 4.2 if判断     <select id="findUserList" parameterType="mybatis.po.User" resultType="mybatis.po.User">         select * from users         <where>         <!-- where自动去掉条件中的第一个and -->                              <if test="id!=null and id!=''">                     and id=#{id}                 </if>                 <if test="username!=null and username!=''">                     and username like #{username}                 </if>                      </where>     </select> 4.3 sql片段 将实现动态sql片段的代码抽取出来,组成一个sql片段,其他statement中可以引用该sql片段 配置: <!-- id:sql片段的唯一标识     是基于单表来定义的sql片段,这样可重用性高     在sql片段中不要包含where -->     <sql id="query_user_where">                                       <if test="id!=null and id!=''">                     and id=#{id}                 </if>                 <if test="username!=null and username!=''">                     and username like #{username}                 </if>     </sql> 引用:<select id="findUserList" parameterType="mybatis.po.User" resultType="mybatis.po.User">         select * from users         <where>         <!-- where自动去掉条件中的第一个and -->             <include refid="query_user_where"></include>             <!-- 引用的id不在本mapper中,需要在前面加namespace -->         </where>     </select>           4.4 foreach 向sql传递数组或list,使用foreach解析 配置: <!-- 使用foreach遍历传入ids             collection:指定输入对象中集合属性             item:每个遍历生成对象             open:开始遍历时拼接的串             close:结束遍历时拼接的串             separator:遍历的两个对象之间需要拼接的串 -->             <if test="ids!=null">             <!-- 实现以下sql拼接: AND (id=1 OR id=2 OR id=3) -->                 <foreach collection="ids" item="id" open="AND (" close=")" separator="OR" ></foreach>             </if>
    转载请注明原文地址: https://ju.6miu.com/read-1299221.html
    最新回复(0)