mybatis基础知识(第三更)

来源:互联网 发布:dnf画质优化 编辑:程序博客网 时间:2024/05/22 09:01

mapper代理:

1.在mapper.xml中namespace等于mapper接口地址

<!-- namespace命名空间,作用就是对sql进行分类化管理,理解sql隔离      注意:使用mapper代理方法开发 namespace有特殊重要作用,namespace等于mapper接口 地址--><mapper namespace="cn.xbq.mybatis.mapper.UserMapper">

2.mapper.java接口中的方法名和mapper.xml中statement的id一致

3 - .mapper.java接口中的方法输入参数类型和mapper.xml中statement的parameterType指定类型一致

4.mapper.java接口中的方法返回值类型和mapper.xml中statement的resultType指定类型一致。

<select id="findUserById" parameterType="int" resultType="cn.xbq.po.User"></select>//根据id查询用户信息public User findUserById(int id) throws Exception;

5.总结:

           以上开发规范主要是对下边的代码进行统一生成:           User user = sqlSession.selectOne("test.findUserById",id);           sqlSession.insert("test.insertUser",user);           …………

6.测试:

记得加载mapper.xml

@Testpublic void testFindUserById() throws Exception {   SqlSession sqlSession = sqlSessionFactory.openSession();   //创建UserMapper对象,mybatis自动生成mapper代理对象   UserMapper userMapper = sqlSession.getMapper(UserMapper.class);   //调用userMapper的方法   User user = userMapper.findUserById(1);   System.out.println(user);}

整个的接口:

public interface UserMapper {   //根据id查询用户信息   public User findUserById(int id) throws Exception;   //根据用户名列查询用户列表   public List<User> findUserByName(String name) throws Exception;   //插入用户   public void insertUser(User user) throws Exception;   //删除用户   public void deleteUser(int id) throws Exception;  }

7.代理对象内部调用selectOne或selectList

如果mapper方法返回单个pojo对象(非集合对象),代理对象内部通过selectOne查询数据库。
如果mapper方法返回集合对象,代理对象内部通过selectList查询数据库

8.mapper接口方法参数只能有一个是否影响系统开发

mapper接口方法参数只能有一个,系统是否不利于扩展维护
系统框架中,dao层的代码是被业务层公用的。
即使mapper接口只有一个参数,可以使用包装类型的pojo满足不同的业务方法的需求。
注意:持久层方法的参数可以包装类型,map…,service方法中建议不要使用包装类型(不利于业务层的可扩展)

9.sqlMapConfig.xml

           mybatis的全局配置文件sqlMapConfig.xml,配置如下:           properties(属性)           setting(全局配置参数)           typeAliases(类型别名)           typeHandlers(类型处理器)           objectFactory(对象工厂)           plugins(插件)           environments(环境集合属性对象)           environment(环境子属性对象)           transactionManager(事务管理)           dataSource(数据源)           mappers(映射器)

10.properties属性:

需求:
将数据库连接参数单独配置在db.properties中,只需要在sqlMapConfig.xml中加载db.properties的属性值。
在sqlMapConfig.xml中就不需要对数据库连接参数硬编码。
将数据库连接参数只配置在db.properties中,原因:方便对参数进行统一管理,其他xml可以引用该db.properties。

<!-- jdbc.driver = com.mysql.jdbc.Driverjdbc.url = jdbc:mysql://localhost:3306/mybatisjdbc.username = rootjdbc.password = 123456--><!-- 加载属性文件--><properties resource="db.properties"></properties>

在sqlMapConfig.xml加载属性文件:

<!-- 使用jdbc事务管理,事务控制由mybatis--><transactionManager type="JDBC"/><!-- 数据库连接池,由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>

properties特性:
注意:mybatis将按照下面的顺序来加载属性:
在properties元素体内定义的属性首先被读取
然后会读取properties元素中resource或URL加载的属性,他会覆盖已读取的同名属性
最后读取parameterType传递的属性,他会覆盖已读取的同名属性
因此:
通过parameterType传递的属性具有最高优先级,resource或URL加载的属性次之,
最低优先级的是properties元素体内定义的属性。

<!-- 加载属性文件--><properties resource="db.properties">   <!-- properties中还可以配置一些属性名和属性值-->   <!-- <property name="jdbc.driver" value="" />--></properties>

建议:
不要在properties元素体内添加任何属性值,只将属性值定义在properties文件中。
在properties文件中定义属性名要有一定的特殊性,如:xxx.xxx.xxx
setting全局参数配置:
mybatis框架在运行时可以调整一些运行参数。
比如:开启二级缓存、开启延迟加载…..
全局参数将会影响mybatis的运行行为
typeAliases(别名)重点
1.需求:
在mapper.xml中,定义很多的statement,statement需要parameterType指定输入参数的类型,需要resultType指定输出结果的映射类型。
如果在指定类型时输入类型全路径,不方便进行开发,可以针对parameterType或resultType指定的类型定义一些别名,在mapper.xml中通过别名定义,方便开发。
2.mybatis默认支持别名:
3.单个别名定义:

<!-- 别名定义--><typeAliases>  <!-- 针对单个别名定义  type:类型的路径  alias:别名  -->  <typeAlias type="cn.xbq.mybatis.po.User" alias="User" /></typeAliases>

引用别名:

<select id="findUserById" parameterType="int" resultType="user">   select * from user where id=#{value}</select>

批量别名的定义(常用):

<!-- 批量别名定义指定包名,mybatis自动扫描包中的po类,自动定义别名,别名就是类名(首字母大写或小写)--><package name="cn.xbq.mybatis.po" />

typeHandlers(类型处理器)
mybatis中通过typeHandlers完成jdbc类型和Java类型的转换
通常情况下,mybatis提供的类型处理器满足日常需要,不需要自定义。
mappers(映射配置)
1.通过resource加载单个映射文件

<!-- 通过resource方法一次加载一个映射文件--><mapper resource="mapper/UserMapper.xml" />

2.通过mapper接口来加载

<!-- 通过mapper接口加载映射文件遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名保持一致,且在一个目录中上边的规范的前提是:使用的是mapper代理方法 --> <mapper class="cn.xbq.mybatis.mapper.UserMapper" />

按照上面的规范,将mapper.java和mapper.xml放在一个目录,且同名:

<!-- cn.xbq.mybatis.mapper  UserMapper.java  UserMapper.xml -->

3.批量加载mapper(推荐使用):

<!-- 批量加载mapper指定mapper接口的包名,mybatis自动扫描包下边所有的mapper接口进行加载遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录中上边规范的前提是:使用的是mapper代理方法--><package name="cn.xbq.mybatis.mapper" />

11.输入映射

通过parameterType指定输入参数的类型,类型可以是简单类型、hashmap、pojo的包装类型
1.传递pojo的包装对象
1.1:需求:
完成用户信息的综合查询,需要传入查询条件很复杂(可能包括用户信息、其他信息,比如商品、订单的)
1.2:定义包装类型pojo:
针对上边需求,建议使用自定义的包装类型的pojo
在包装类型的pojo中将复杂的查询条件包装进去。

public class UserQueryVo {   //在这里包装所需要的查询条件   //用户查询条件   private UserCustom userCustom;   public UserCustom getUserCustom() {      return userCustom;   }   public void setUserCustom(UserCustom userCustom) {      this.userCustom = userCustom;   }}

1.3 mapper.xml

<!-- 用户信息查询 #{userCustom.sex}:取出pojo包装对象中性别值 ${userCustom.username}:取出pojo包装对象中用户名称 --> <select id="findUserList" parameterType="cn.xbq.mybatis.po.UserQueryVo" resultType="cn.xbq.mybatis.po.UserCustom"> select * from user where user.sex=#{userCustom.sex} and user.username like '%${userCustom.username}%' </select>

1.4 mapper.java

//用户信息综合查询public List<UserCustom> findUserList(UserQueryVo userQueryVo) throws Exception;@Testpublic void testFindUserList() throws Exception {    SqlSession sqlSession = sqlSessionFactory.openSession();    //创建UserMapper对象,mybatis自动生成mapper对象    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);    //创建包装对象,设置查询条件    UserQueryVo userQueryVo = new UserQueryVo();    UserCustom userCustom = new UserCustom();    userCustom.setSex("1");    userCustom.setUsername("卡啦啦啦啦");    userQueryVo.setUserCustom(userCustom);    //调用userMapper的方法    List<UserCustom> list = userMapper.findUserList(userQueryVo);    System.out.println(list);}

1.5:小节:
查询出来的结果集只有一行且一列,可以使用简单类型进行输出映射。

12.输出pojo对象和pojo列表

不管是输出的pojo单个对象还是一个列表(list中包括pojo),在mapper.xml中resultType 指定的类型是一样的。
在mapper.java指定的方法返回值类型不一样。
1.输出单个pojo对象,方法返回值是单个对象类型。

//根据id查询用户信息public User findUserById(int id) throws Exception;

2.输出pojo对象list,方法返回值是List

//根据用户名列查询用户列表public List<User> findUserByName(String name) throws Exception;

生成的动态代理对象中是根据mapper方法的返回值类型确定是调用selectOne(返回单个对象调用)还是selectList(返回集合对象调用)

13. resultType:

使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。
如果查询出来的列名和pojo中的属性名全部不一致,没有创建pojo对象。
只要查询出来的列名和pojo中的属性有一个一致,就会创建pojo对象。

14. resultMap

mybatis中使用resultMap完成高级输出结果映射。
1.resultMap使用方法:
如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap列名和pojo属性名之间做一个映射关系。
1.1:定义resultMap:

<!-- 定义resultMap将select id id_,username username_ from user 和 user类中的属性作一个映射关系type:resultMap最终映射的Java对象类型,可以使用别名id:对resultMap的唯一标识--><resultMap type="user" id="userResultMap">   <!-- id表示查询结果集中唯一标识   column:查询出来的列名   property:type指定的pojo类型中的属性名   最终resultMap对column和property作一个映射关系(对应关系)   -->   <id column="id_" property="id">   <!--   result:对普通名映射定义   column:查询出来的列名   property:type指定的pojo类型中属性名   最终resultMap对column和property作一个映射关系(对应关系)   -->   <result column="username_" property="usrname" /></resultMap>

1.2使用resultMap作为statement的输出映射类型:

<!-- 使用resultMap进行输出映射resultMap:指定定义的resultMap的id,如果这个resultMap在其他的mapper文件,前边需要加namespace--><select id="findUserByIdResultMap" parameterType="int" resultMap="userResultMap">select id id_,username usernmae_ from user where id=#{value}</select>

1.3测试:

@Testpublic void testFindUserList() throws Exception {    SqlSession sqlSession = sqlSessionFactory.openSession();    //创建UserMapper对象,mybatis自动生成mapper对象    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);    //调用userMapper的方法    User user = userMapper.findUserByIdResultMap(1);    System.out.println(user);}

1.4:总结:
使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。
如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间做一个映射关系。

15:动态sql:

1.什么是动态sql:
mybatis核心对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接、组装。
2.需求:
用户信息综合查询列表和用户信息查询列表总数这两个statement的定义使用动态sql。
对查询条件进行判断,如果输入参数不为空才进行查询条件拼接。
3. mapper.xml

<!-- 用户信息综合查询#{userCustom.sex}:取出pojo包装对象中性别值${userCustom.username}:取出pojo包装对象中用户名称--><select id="findUserList" parameterType="cn.xbq.mybatis.po.UserQueryVo" resultType="cn.xbq.mybatis.po.UserCustom">select * from user<!-- where可以自动去掉条件中的第一个and--><where>  <if test="userCustom!=null">     <if test="userCustom.sex!=null and userCustom.sex!="">         and user.sex = #{userCustom.sex}     </if>     <if test="userCustom.username!=null and userCustom.username!="">         and user.username like '%${usrCustom.username}%'     </if>   </if></where>

4.测试代码:

//用户信息的综合查询@Testpublic void testFindUserList() throws Exception {    SqlSession sqlSession = sqlSessionFactory.openSession();    //创建UserMapper对象,mybatis自动生成mapper对象    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);    //创建包装对象,设置查询条件    UserQueryVo userQueryVo = new UserQueryVo();    UserCustom userCustom = new UserCustom();    userCustom.setSex("1");    userCustom.setUsername("卡啦啦啦啦");    userQueryVo.setUserCustom(userCustom);    //调用userMapper的方法    List<UserCustom> list = userMapper.findUserList(userQueryVo);    System.out.println(list);}

16.sql片段:

1.需求:
将上边实现的动态sql判断代码块抽取出来,组成一个sql片段,其他的statement中就可以引用sql片段。
方便程序员进行开发。
2.定义sql片段:

<!-- 定义sql片段id:sql片段的唯一标识经验:是基于单表来定义sql片段,这样话这个sql片段可重用性才高在sql片段中不要包括where--><sql id="query_user_where">  <if test="userCustom!=null">     <if test="userCustom.sex!=null and userCustom.sex!="">         and user.sex = #{userCustom.sex}     </if>     <if test="userCustom.username!=null and userCustom.username!="">         and user.username like '%${usrCustom.username}%'     </if>   </if></sql>

3.引用sql片段:
在mapper.xml中定义的statement中引用sql片段:

<!-- 用户信息综合查询#{userCustom.sex}:取出pojo包装对象中性别值${userCustom.username}:取出pojo包装对象中用户名称--><select id="findUserList" parameterType="cn.xbq.mybatis.po.UserQueryVo" resultType="cn.xbq.mybatis.po.UserCustom">select * from user<!-- where可以自动去掉条件中的第一个and--><where>   <!-- 引用sql片段的id,如果refid指定的id不在本mapper文件中,需要前边加namespace -->   <include refid="query_user_where"></include>   <!-- 在这里还要引用其他的sql片段--></where>
<!-- 用户信息综合查询parameterType:指定输入类型和findUserList一样resultType:输出结果类型--><select id="findUserList" parameterType="cn.xbq.mybatis.po.UserQueryVo" resultType="cn.xbq.mybatis.po.UserCustom">select count(*) from user<!-- where可以自动去掉条件中的第一个and--><where>   <!-- 引用sql片段的id,如果refid指定的id不在本mapper文件中,需要前边加namespace -->   <include refid="query_user_where"></include>   <!-- 在这里还要引用其他的sql片段--></where>

17:foreach

向sql传递数组或者List,mybatis使用foreach解析
1.需求:
在用户查询列表和查询总数的statement中增加多个id输入查询。
sql语句如下:
select * from user where id=1 or id=10 or id=16
select * from userwhere id in(1,10,16)

<if test="ids!=null"><!-- 使用foreach遍历传入idscollection:指定输入对象中集合属性item:每个遍历生成对象中open:开始遍历时拼接的串close:结束遍历时拼接的串separator:遍历的两个对象中需要拼接的串--><!-- 使用实现下边的sql拼接:and (id=1 or id=10 or id=16)--><foreach collection="ids" item="user_id" open="and("close=")" separator="or">    <!-- 每个遍历需要拼接的串 -->    id=#{user_id}</foreach>  </if>

2.测试代码:

 SqlSession sqlSession = sqlSessionFactory.openSession();    //创建UserMapper对象,mybatis自动生成mapper对象    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);    //创建包装对象,设置查询条件    UserQueryVo userQueryVo = new UserQueryVo();    UserCustom userCustom = new UserCustom();    userCustom.setSex("1");    userCustom.setUsername("小明");    //传入多个id    List<Integer> ids = new ArrayList<Integer>();    ids.add(1);    ids.add(10);    ids.add(16);    //将id通过userQueryVo传入statement中    userQueryVo.setIds(ids);    userQueryVo.setUserCustom(userCustom);    //调用userMapper的方法    List<UserCustom> list = userMapper.findUserList(userQueryVo);
原创粉丝点击