Mybatis 总结02

 

  1. 输入映射和输出映射

Mapper.xml映射文件中配置了执行statement相关的信息,比如:sql语句、sql中输入参数的映射、sql中输出结果的映射等

 

输入映射通过parameterType标签属性来进行的。

输出映射通过resultType或resultMap标签属性来进行的。

 

    1. parameterType(输入类型)
      1. 传递简单类型

参考第一天内容中的根据用户ID查询用户信息的案例。

      1. 传递pojo对象

 

参考第一天内容中的添加用户的案例。

      1. 传递pojo包装对象

 

       这时可以使用包装对象传递输入参数。Pojo类中包含pojo。

 

        1. 需求

在综合查询的场景中,需要根据不同的查询条件进行用户列表的查询。这些查询条件中,包括用户名称,还可能包括商品ID或者商品名称。

 

        1. 分析
  1. 通过mybatis传递多个查询条件时,需要使用pojo或者map来传递。
  2. 判断这多个条件是否属于同一张表,那么就会对应一个实体类。如果不是,则最好声明一个包装pojo(也就是声明一个大对象,其中包含子对象或者子属性)

 

 

        1. QueryVo

定义包装对象QueryVo

public class QueryVo {

    

       private User user;

 

       public User getUser() {

              return user;

       }

       public void setUser(User user) {

              this.user = user;

       }

      

}

 

        1. SQL语句

SELECT * FROM user where username like '%小明%'

 

        1. Mapper文件

<!-- 使用包装类型查询用户

              使用ognl从对象中取属性值,如果是包装对象可以使用.操作符来取内容部的属性

       -->

       <select id="queryUserList" parameterType="queryVO" resultType="user">

              SELECT * FROM user where username like '%${user.username}%'

       </select>

 

        1. Mapper接口

/**

 * 用户管理mapper

 */

public interface UserMapper {

 

      //综合查询用户列表

       public List<User> queryUserList(QueryVo vo)throws Exception;

 

}

 

        1. 测试方法

在UserMapperTest测试类中,添加以下测试代码:

@Test

       public void testQueryUserList() throws Exception {

              SqlSession sqlSession = sqlSessionFactory.openSession();

              //获得mapper的代理对象

              UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

              //创建QueryVo对象

              QueryVo queryVo = new QueryVo();

              //创建user对象

              User user = new User();

              user.setUsername("小明");

 

              queryVo.setUser(user);

              //根据queryvo查询用户

              List<User> list = userMapper.queryUserList(queryVo);

              System.out.println(list);

              sqlSession.close();

       }

 

      1. 传递map类型

通过map类型传参和通过pojo类传参是一样的。

 

Pojo类型传参的要求,pojo中的属性名称和映射文件中的#{}里面的值一致。

Map类型传参的要求,map中的key和映射文件中的#{}里面的值一致。

 

 

    1. resultType(输出类型)

resultType本质上也是使用resultMap完成映射的。

      1. 使用要求

使用resultType进行输出映射时,要求sql语句中查询的列名和要映射的pojo的属性名一致。

      1. 输出简单类型
        1. 需求

在综合查询用户列表时,要求分页查询,而分页查询需要查询符合条件的记录总数。

 

        1. Mapper映射文件

<!-- 获取用户列表总数 -->

       <select id="queryUserCount" parameterType="user" resultType="int">

          select count(1) from user  where username like '%${user.username}%'

       </select>

 

        1. Mapper接口

      //综合查询用户总数

       public int  queryUserCount(QueryVo queryVo) throws Exception;

 

        1. 测试代码

在UserMapperTest测试类中,添加以下测试代码:

 

     @Test

       public void testQueryUserList() throws Exception {

              SqlSession sqlSession = sessionFactory.openSession();

              //获得mapper的代理对象

              UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

              //创建QueryVo对象

              QueryVo queryVo = new QueryVo();

              //创建user对象

              User user = new User();

              user.setUsername("小明");

 

              queryVo.setUser(user);

              //根据queryvo查询用户

              List<User> list = userMapper.queryUserList(queryVo);

           System.out.println(list);

 

           int count = userMapper.queryUserCount(user);

           System.out.println(count);

 

              sqlSession.close();

       }

 

注意:输出简单类型必须查询出来的结果集只有一列。

 

 

        1. 总结

查询结果只有一列的时候,才能使用resultType的简单类型完成映射。

      1. 输出pojo对象

参考第一天内容之根据用户ID查询用户信息的案例

      1. 输出pojo列表

参考第一天内容之根据用户名称模糊查询用户列表的案例。

 

      1. 总结

输出映射,是发送在哪个JDBC的8步操作中的哪些步骤?

 

首先确定,输出映射的前提,是已经执行完sql语句,并且拿到ResultSet对象了。

 

也就是说输出映射就是将ResultSet中的值

按照[列名]取出结果集中的值,然后封装到一个pojo类型的[属性]中。

 

    1. resultMap
      1. 使用要求

       如果sql查询列名和pojo的属性名不一致,可以通过resultMap将列名和属性名作一个对应关系,最终将查询结果映射到pojo对象中。

      1. 需求

将以下sql的查询结果进行映射:

SELECT id id_,username username_,birthday birthday_ FROM user

      1. Mapper接口

 

// resultMap入门

public List<User> findUserResultMap() throws Exception;

 

      1. Mapper映射文件

由于sql查询列名和Users类属性名不一致,所以不能使用resultType进行结构映射。

需要定义一个resultMap将sql查询列名和Users类的属性名对应起来,完成结果映射。

 

       <!-- 定义resultMap:将查询的列名和映射的pojo的属性名做一个对应关系 -->

       <!--

              type:指定查询结果要映射的pojo的类型

              id:指定resultMap的唯一标示

        -->

       <resultMap type="user" id="userResultMap">

              <!--

              id标签:映射查询结果的唯一列(主键列)

                     column:查询sql的列名

                     property:映射结果的属性名

              -->

              <id column="id_" property="id"/>

              <!-- result标签:映射查询结果的普通列 -->

              <result column="username_" property="username"/>

              <result column="birthday_" property="birthday"/>

       </resultMap>

 

       <!-- resultMap入门 -->

       <select id="findUserResultMap" resultMap="userResultMap">

              SELECT id id_,username username_,birthday birthday_ FROM user

       </select>

 

 

<id />:此属性表示查询结果集的唯一标识,非常重要。如果是多个字段为复合唯一约束则定义多个<id />。

Property:表示User类的属性。

Column:表示sql查询出来的字段名。

Column和property放在一块儿表示将sql查询出来的字段映射到指定的pojo类属性上。

 

<result />:普通结果,即pojo的属性。

 

 

 

  1. 动态sql

通过mybatis提供的各种标签方法实现动态拼接sql,常用的动态标签包括:ifwhereforeachsql片段

 

    1. if

综合查询的案例中,查询条件是由页面传入,页面中的查询条件可能输入用户名称,也可能不输入用户名称。

 

       <select id="queryUserList" parameterType="queryVo" resultType="user">

              SELECT * FROM user where 1=1

              <if test="user != null">

                     <if test="user.username != null and user.username != ''">

                            AND username like '%${user.username}%'

                     </if>

              </if>

       </select>

 

注意:要做『不等于空』字符串校验。

 

 

    1. where

上边的sql中的1=1,虽然可以保证sql语句的完整性:但是存在性能问题。Mybatis提供where标签解决该问题。

 

代码修改如下:

       <select id="queryUserList" parameterType="queryVo" resultType="user">

              SELECT * FROM user

              <!-- where标签会处理它后面的第一个and -->

              <where>

                     <if test="user != null">

                            <if test="user.username != null and user.username != ''">

                                   AND username like '%${user.username}%'

                            </if>

                     </if>

              </where>

       </select>

 

    1. sql片段

 

在映射文件中可使用sql标签将重复的sql提取出来,然后使用include标签引用即可,最终达到sql重用的目的,具体实现如下:

 

  1. 原映射文件中的代码:

<select id="queryUserList" parameterType="queryVo" resultType="user">

              SELECT * FROM user

              <!-- where标签会处理它后面的第一个and -->

              <where>

                     <if test="user != null">

                            <if test="user.username != null and user.username != ''">

                                   AND username like '%${user.username}%'

                            </if>

                     </if>

                     <if test="ids != null and ids.size > 0">

                            <!-- collection:指定输入的集合参数的参数名称 -->

                            <!-- item:声明集合参数中的元素变量名 -->

                            <!-- open:集合遍历时,需要拼接到遍历sql语句的前面 -->

                            <!-- close:集合遍历时,需要拼接到遍历sql语句的后面 -->

                            <!-- separator:集合遍历时,需要拼接到遍历sql语句之间的分隔 -->

                            <foreach collection="ids" item="id" open=" AND id IN ( "

                                   close=" ) " separator=",">

                                   #{id}

                            </foreach>

                     </if>

              </where>

       </select>

 

 

  1. 将where条件抽取出来:

<sql id="query_ where">

              <if test="user != null">

                     <if test="user.username != null and user.username != ''">

                            AND username like '%${user.username}%'

                     </if>

              </if>

              <if test="ids != null and ids.size > 0">

                     <!-- collection:指定输入的集合参数的参数名称 -->

                     <!-- item:声明集合参数中的元素变量名 -->

                     <!-- open:集合遍历时,需要拼接到遍历sql语句的前面 -->

                     <!-- close:集合遍历时,需要拼接到遍历sql语句的后面 -->

                     <!-- separator:集合遍历时,需要拼接到遍历sql语句之间的分隔符号 -->

                     <foreach collection="ids" item="id" open=" AND id IN ( "

                            close=" ) " separator=",">

                            #{id}

                     </foreach>

              </if>

       </sql>

 

  1. 使用include引用:

       <!-- 使用包装类型查询用户 使用ognl从对象中取属性值,如果是包装对象可以使用.操作符来取内容部的属性 -->

       <select id="findUserList" parameterType="queryVo" resultType="user">

              SELECT * FROM user

              <!-- where标签会处理它后面的第一个and -->

              <where>

                     <include refid="query_ where"></include>

              </where>

 

       </select>

 

 

注意:如果引用其它mapper.xmlsql片段,则在引用时需要加上namespace,如下:

<include refid="namespace.sql片段”/>

 

 

 

 

 

    1. foreach

 

向sql传递数组或List参数,mybatis使用foreach解析

 

      1. 需求

传入多个id查询用户信息,用下边两个sql实现:

 

SELECT * FROM USERS WHERE username LIKE '%小明%' AND (id =1 OR id =10 OR id=16)

SELECT * FROM USERS WHERE username LIKE '%小明%'  AND  id  IN (1,10,16)

 

      1. 修改POJO

在pojo中定义list属性ids存储多个用户id,并添加getter/setter方法

 

 

 

      1. Mapper映射文件

 

<!-- 使用包装类型查询用户 使用ognl从对象中取属性值,如果是包装对象可以使用.操作符来取内容部的属性 -->

       <select id="queryUserList" parameterType="queryVo" resultType="user">

              SELECT * FROM user

              <!-- where标签会处理它后面的第一个and -->

              <where>

                     <if test="user != null">

                            <if test="user.username != null and user.username != ''">

                                   AND username like '%${user.username}%'

                            </if>

                     </if>

                     <if test="idList != null and idList.size > 0">

                            <!--

                                   collection:指定输入的集合参数的参数名称

                                   item:声明集合参数中的元素变量名

                                   open:集合遍历时,需要拼接到遍历sql语句的前面

                                   close:集合遍历时,需要拼接到遍历sql语句的后面

                                   separator:集合遍历时,需要拼接到遍历sql语句之间的分隔符号

                            -->

                            <foreach collection="idList" item="id" open=" AND id IN ( " close=" ) " separator=",">

                                   #{id}

                            </foreach>

                     </if>

              </where>

 

       </select>

 

 

 

      1. 测试代码

在UserMapperTest测试代码中,修改testFindUserList方法,如下:

@Test

       public void testQueryUserList() throws Exception {

              SqlSession sqlSession = sqlSessionFactory.openSession();

              // 获得mapper的代理对象

              UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

              // 创建QueryVo对象

              QueryVo queryVo = new QueryVo();

              // 创建user对象

              User user = new User();

              user.setUsername("小明");

 

              queryVo.setUser(user);

 

              List<Integer> ids = new ArrayList<Integer>();

              ids.add(1);// 查询id1的用户

              ids.add(10); // 查询id10的用户

              queryVo.setIds(ids);

 

              // 根据queryvo查询用户

              List<User> list = userMapper.queryUserList(queryVo);

              System.out.println(list);

              sqlSession.close();

       }

 

  1. 关联查询
    1. 商品订单数据模型

 

用户表:user

记录了购买商品的用户信息

Id:唯一标识一个用户

订单表:orders

记录了用户创建的订单

创建用户:user_id(外键)

订单号

创建时间

订单状态

一对一:一个订单只能由一个用户创建

一对多:一个用户可以创建多个订单

 

 

注意:因为一个订单信息只会是一个人下的订单,所以从查询订单信息出发,关联查询用户信息为一对一查询。如果从用户信息出发,查询用户下的订单信息则为一对多查询,因为一个用户可以下多个订单。

 

    1. 一对一查询
      1. 需求

查询所有订单信息,关联查询下单用户信息。

      1. Sql语句

SELECT

  orders.*,

  user.username,

  user.address

FROM

  orders

  user

WHERE orders.user_id = user.id

 

主信息:订单信息

从信息:用户信息

      1. 方法一:resultType

使用resultType进行结果映射。

        1. 分析
  1. 如果使用resultType进行结果映射,则查询的列名和映射pojo的属性名称要一致。
  2. 关联查询的结果集,既包含订单信息,又包含用户信息。使用订单po或者用户po类都无法完成结果映射。
  3. 需要定义扩展po类,此类继承订单信息po类,同时还要包括用户信息:

 

        1. 定义扩展po类

扩展Po类中应该包括上边sql查询出来的所有字段,如下:

 

public class OrdersExt extends Orders {

 

       private String username;// 用户名称

       private String address;// 用户地址

get/set。。。。

 

OrdersExt类继承Orders类后,便会继承Orders类的所有字段,除此之外只需要定义用户信息字段即可。

 

        1. Mapper映射文件

在UserMapper.xml中,添加以下代码:

 

<!-- 查询所有订单信息 -->

       <select id="findOrdersAndUser" resultType="cn.itcast.mybatis.po.OrdersExt">

       SELECT

       orders.*,

       user.username,

       user.address

       FROM

       orders,    user

       WHERE orders.user_id = user.id

       </select>

 

        1. Mapper接口

在UserMapper接口中,添加以下接口方法:

 

public List<OrdersExt> findOrdersAndUser() throws Exception;

 

        1. 测试代码

在UserMapperTest测试类中,添加测试代码:

 

public void testFindOrdersAndUser()throws Exception{

              //获取session

              SqlSession session = sqlSessionFactory.openSession();

              //获限mapper接口实例

              UserMapper userMapper = session.getMapper(UserMapper.class);

              //查询订单信息

              List<OrdersExt> list = userMapper.findOrdersAndUser();

              System.out.println(list);

              //关闭session

              session.close();

       }

 

        1. 小结
  1. 使用resultType完成结果映射,映射的java对象中的属性都是简单类型属性(不包括pojo属性)。
      1. 方法二:resultMap

使用resultMap完成结果映射,是需要将关联信息,映射为对象嵌套对象的关系。

 

使用resultMap进行结果映射,定义专门的resultMap用于映射一对一查询结果。

 

        1. 修改扩展po类

       在OrdersExt类中加入User属性,user属性中用于存储关联查询的用户信息,因为订单关联查询用户是一对一关系,所以这里使用单个User对象存储关联查询的用户信息。

public class OrdersExt extends Orders {

 

       private String username;// 用户名称

       private String address;// 用户地址

 

    private User user;// 用户对象

get/set。。。。

 

        1. Mapper映射文件

在UserMapper.xml中,添加以下代码:

 

<!-- 查询订单关联用户信息使用resultmap -->

       <resultMap type="OrdersExt" id="ordersAndUserRstMap">

              <id column="id" property="id"/>

              <result column="user_id" property="userId"/>

              <result column="number" property="number"/>

              <result column="createtime" property="createtime"/>

              <result column="note" property="note"/>

              <!-- 一对一关联映射 -->

              <!--

              property:Orders对象的user属性

              javaTypeuser属性对应 的类型

               -->

              <association property="user" javaType="cn.itcast.mybatis.po.User">

                     <!-- column:user表的主键对应的列  propertyuser对象中id属性-->

                     <id column="user_id" property="id"/>

                     <result column="username" property="username"/>

                     <result column="address" property="address"/>

              </association>

       </resultMap>

       <select id="findOrdersAndUserRstMap" resultMap="ordersAndUserRstMap">

              SELECT

                     o.*,

                     u.username,

                     u.address

              FROM

                     orders o

              JOIN `user` u ON u.id = o.user_id

       </select>

 

association表示进行一对一关联查询映射

property表示关联查询的结果存储在cn.itcast.mybatis.po.Orders的user属性中

javaType表示关联查询的映射结果类型

 

        1. Mapper接口

在UserMapper接口中,添加以下接口方法:

 

public List<OrdersExt> findOrdersAndUserRstMap() throws Exception;

 

        1. 测试代码

在UserMapperTest测试类中,添加测试代码:

 

Public void testfindOrdersAndUserRstMap()throws Exception{

              //获取session

              SqlSession session = sqlSessionFactory.openSession();

              //获限mapper接口实例

              UserMapper userMapper = session.getMapper(UserMapper.class);

              //查询订单信息

              List<OrdersExt> list = userMapper.findOrdersAndUserRstMap();

              System.out.println(list);

              //关闭session

              session.close();

       }

 

        1. 小结

使用resultMap进行结果映射时,具体是使用association完成关联查询的映射,将关联查询信息映射到pojo对象中。

 

      1. 总结

特殊映射要求:对象嵌套对象。

一般映射要求:将查询结果都映射成一个pojo的简单类型属性。

 

没有特殊映射要求,在一对一映射的时候,使用resultType更简单。建议使用resultType完成结果映射。

 

resultMap在一些更特殊的情况(延迟加载)下,必须使用它完成映射。

 

mybatis中,mapper代理获取的对象使用的是JDK代理。延迟加载的对象代理就是使用的cglib

 

    1. 一对多查询

使用resultType完成结果映射,查询记录有多少条,则映射成几个结果对象。

 

 

      1. 需求

查询所有用户信息及用户关联的订单信息。

 

      1. Sql语句

SELECT

  user.*,

  orders.`id` ordersId,

  orders.`number`

FROM

  USER,

  orders

WHERE user.`id` = orders.`user_id`

主信息:用户信息

从信息:订单信息

      1. 分析

在一对多关联查询时,只能使用resultMap进行结果映射。

 

  1. 一对多关联查询时,sql查询结果有多条,而映射对象是一个。
  2. resultType完成结果映射的方式的一条记录映射一个对象。
  3. resultMap完成结果映射的方式是以[主信息]为主对象,[从信息]映射为集合或者对象,然后封装到主对象中。
      1. 修改po类

在User类中加入List<Orders> orders属性

 

 

      1. Mapper映射文件

在UserMapper.xml文件中,添加以下代码:

<resultMap type="user" id="userAndOrderRstMap">

              <!-- 用户信息映射 -->

              <id property="id" column="id"/>

              <result property="username" column="username"/>

              <result property="birthday" column="birthday"/>

              <result property="sex" column="sex"/>

              <result property="address" column="address"/>

              <!-- 一对多关联映射 -->

              <collection property="orders" ofType="orders">

                     <id property="id" column="ordersId"/>     

                     <result property="number" column="number"/>

              </collection>

       </resultMap>

       <select id="findUserAndOrderRstMap" resultMap="userAndOrderRstMap">

              SELECT

  user.*,

  orders.`id` ordersId,

  orders.`number`

FROM

  USER,

  orders

WHERE user.`id` = orders.`user_id`

       </select>

      

 

Collection标签:定义了一对多关联的结果映射。

property="orders"关联查询的结果集存储在User对象的上哪个属性。

ofType="orders"指定关联查询的结果集中的对象类型即List中的对象类型。此处可以使用别名,也可以使用全限定名。

      1. Mapper接口

// resultMap入门

public List<User> findUserAndOrdersRstMap() throws Exception;

      1. 测试代码

@Test

       public void testFindUserAndOrdersRstMap() {

              SqlSession session = sqlSessionFactory.openSession();

              UserMapper userMapper = session.getMapper(UserMapper.class);

              List<User> result = userMapper.findUserAndOrdersRstMap();

              for (User user : result) {

                     System.out.println(user);

              }

              session.close();

       }

 

 

  1. Mybatis整合spring
    1. 整合思路

使用spring管理mybatis的实例

 

  1. 数据库的连接以及数据库连接池事务管理都交给spring容器来完成。
  2. SqlSessionFactory对象应该放到spring容器中进行单例管理。
  3. 传统dao的开发方式中,dao实现类应该交由spring管理。
  4. Mapper代理开发方式中,mapper的代理对象应该交由spring管理。

 

    1. 整合需要的jar包
  1. Mysql的数据库驱动jar包。
  2. 数据库连接池的jar包。
  3. Mybatis的jar包
  4. spring的jar包
  5. Spring+mybatis的整合包。

 

 

    1. 整合的步骤

 

第一步:创建一个java工程。

第二步:导入jar包。(上面提到的jar包)

 

此步骤之前,需要将po类创建。

第三步:mybatis的配置文件sqlmapConfig.xml

第四步:编写Spring的配置文件

1、数据库连接及连接池

2、事务管理(暂时可以不配置)

3、sqlsessionFactory对象,配置到spring容器中

4、mapeer代理对象或者是dao实现类配置到spring容器中。

第五步:编写映射文件

第六步:编写dao代码或者mapper接口

第七步:测试。

      1. SqlMapConfig.xml

在classpath目录下,创建mybatis目录,然后创建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>

       <typeAliases>

              <package name="cn.itcast.ms.po"/>

       </typeAliases>

       <mappers>

              <mapper resource="mybatis/sqlmap/User.xml"/>

       </mappers>

</configuration>

 

      1. applicationContext.xml

在classpath目录下,创建spring目录,然后创建applicationContext.xml文件

 

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

<beans xmlns="http://www.springframework.org/schema/beans"

       xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"

       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd

       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd

       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd

       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

 

       <!-- 加载配置文件 -->

       <context:property-placeholder location="classpath:db.properties" />

       <!-- 数据库连接池 -->

       <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"

              destroy-method="close">

              <property name="driverClassName" value="${jdbc.driver}" />

              <property name="url" value="${jdbc.url}" />

              <property name="username" value="${jdbc.username}" />

              <property name="password" value="${jdbc.password}" />

              <property name="maxActive" value="10" />

              <property name="maxIdle" value="5" />

       </bean>

       <!-- mapper配置 -->

       <!-- spring管理sqlsessionfactory 使用mybatisspring整合包中的 -->

       <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

              <!-- 数据库连接池 -->

              <property name="dataSource" ref="dataSource" />

              <!-- 加载mybatis的全局配置文件 -->

              <property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml" />

       </bean>

 

</beans>

 

      1. db.properties

在classpath目录下,创建db.properties文件。

jdbc.driver=com.mysql.jdbc.Driver

jdbc.url=jdbc:mysql://localhost:3306/ssm?characterEncoding=utf-8

jdbc.username=root

jdbc.password=root

 

    1. Dao的开发

三种dao的实现方式:

1、传统dao的开发方式

2、使用mapper代理形式开发方式

3、使用扫描包配置mapper代理。

 

      1. 传统dao开发方式

开发dao接口和实现类。整合spring之后的dao实现类需要继承SqlsessionDaoSupport类

 

        1. Dao实现类

 

public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {

 

       @Override

       public User findUserById(int id) throws Exception {

              //不能关闭SqlSession,让spring容器来完成

              return User user = this.getSqlSession().selectOne("test.findUserById", id);

       }

 

       @Override

       public void insertUser(User user) throws Exception {

              SqlSession session = this.getSqlSession();

              session.insert("test.insertUser", user);

              session.commit();

              //session.close();

       }

 

}

 

 

        1. 配置dao

把dao实现类配置到spring容器中

 

applicationContext.xml中添加以下配置:

<!-- 配置UserDao实现类 -->

       <bean id="userDao" class="cn.itcast.ms.dao.UserDaoImpl">

              <property name="sqlSessionFactory" ref="sqlSessionFactory"/>

       </bean>

        1. 测试方法

@Test

       public void testFindUserById() throws Exception {

              UserDao userDao = (UserDao) applicationContext.getBean("userDao");

              User user = userDao.findUserById(1);

              System.out.println(user);

       }

 

      1. Mapper代理开发方式
        1. 开发mapper接口和映射文件

 

        1. 配置mapper代理
          1. 方式1

<!-- 配置mapper代理对象 -->

       <bean class="org.mybatis.spring.mapper.MapperFactoryBean">

              <property name="mapperInterface" value="cn.itcast.ms.mapper.UserMapper"/>

              <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>

       </bean>

 

          1. 方式2(推荐)

<!-- 使用扫描包的形式来创建mapper代理对象 -->

       <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">

              <property name="basePackage" value="cn.itcast.ms.mapper"></property>

       </bean>

注意:springmapper代理对象的beanid就是类名(首字母小写)

 

 

        1. 测试方法

public class UserMapperTest {

 

       private ApplicationContext applicationContext;

       @Before

       public void setUp() throws Exception {

              applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext.xml");

       }

 

       @Test

       public void testGetUserById() {

              UserMapper userMapper = applicationContext.getBean(UserMapper.class);

              User user = userMapper.getUserById(1);

              System.out.println(user);

       }

 

}

  1. Mybatis逆向工程

使用官方网站的Mapper自动生成工具mybatis-generator-core-1.3.2来生成po类和Mapper映射文件和mapper接口(注意,只能针对单表进行生成,关联关系无法生成)。

    1. 导入逆向工程

使用课前资料已有逆向工程,如下图:

 

 

      1. 复制逆向工程到工作空间中

复制的效果如下图:

 

 

      1. 导入逆向工程到eclipse中

如下图方式进行导入:

 

 

 

    1. 修改配置文件

在generatorConfig.xml中配置Mapper生成的详细信息,如下图:

 

注意修改以下几点:

  1. 修改要生成的数据库表
  2. pojo文件所在包路径
  3. Mapper所在的包路径

 

配置文件如下:

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

<!DOCTYPE generatorConfiguration

  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"

  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

 

<generatorConfiguration>

       <context id="testTables" targetRuntime="MyBatis3">

              <commentGenerator>

                     <!-- 是否去除自动生成的注释 true:是 false: -->

                     <property name="suppressAllComments" value="true" />

              </commentGenerator>

              <!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->

              <jdbcConnection driverClass="com.mysql.jdbc.Driver"

                     connectionURL="jdbc:mysql://localhost:3306/mybatis" userId="root" password="root">

              </jdbcConnection>

              <!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver" connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:yycg"

                     userId="yycg" password="yycg"> </jdbcConnection> -->

 

              <!-- 默认false,把JDBC DECIMAL NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL

                     NUMERIC 类型解析为java.math.BigDecimal -->

              <javaTypeResolver>

                     <property name="forceBigDecimals" value="false" />

              </javaTypeResolver>

 

              <!-- targetProject:生成PO类的位置 -->

              <javaModelGenerator targetPackage="cn.itcast.ssm.po"

                     targetProject=".\src">

                     <!-- enableSubPackages:是否让schema作为包的后缀 -->

                     <property name="enableSubPackages" value="false" />

                     <!-- 从数据库返回的值被清理前后的空格 -->

                     <property name="trimStrings" value="true" />

              </javaModelGenerator>

              <!-- targetProject:mapper映射文件生成的位置 -->

              <sqlMapGenerator targetPackage="cn.itcast.ssm.mapper"

                     targetProject=".\src">

                     <!-- enableSubPackages:是否让schema作为包的后缀 -->

                     <property name="enableSubPackages" value="false" />

              </sqlMapGenerator>

              <!-- targetPackagemapper接口生成的位置 -->

              <javaClientGenerator type="XMLMAPPER"

                     targetPackage="cn.itcast.ssm.mapper" targetProject=".\src">

                     <!-- enableSubPackages:是否让schema作为包的后缀 -->

                     <property name="enableSubPackages" value="false" />

              </javaClientGenerator>

              <!-- 指定数据库表 -->

              <table schema="" tableName="user"></table>

              <table schema="" tableName="order"></table>

       </context>

</generatorConfiguration>

    1. 生成逆向工程代码

找到下图所示的java文件,执行工程main主函数,

 

 

 

刷新工程,发现代码生成,如下图:

 

    1. 测试逆向工程代码

1. 复制生成的代码到mybatis-spring工程,如下图

 

 

2. 修改spring配置文件

在applicationContext.xml修改

<!-- Mapper代理的方式开发,扫描包方式配置代理 -->

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">

       <!-- 配置Mapper接口,如果需要加载多个包,直接写进来,中间用,分隔 -->

       <!-- <property name="basePackage" value="cn.itcast.mybatis.mapper" /> -->

       <property name="basePackage" value="cn.itcast.ssm.mapper" />

</bean>

 

3. 编写测试方法:

public class UserMapperTest {

       private ApplicationContext context;

 

       @Before

       public void setUp() throws Exception {

              this.context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");

       }

 

       @Test

       public void testInsert() {

              // 获取Mapper

              UserMapper userMapper = this.context.getBean(UserMapper.class);

 

              User user = new User();

              user.setUsername("曹操");

              user.setSex("1");

              user.setBirthday(new Date());

              user.setAddress("三国");

 

              userMapper.insert(user);

       }

 

       @Test

       public void testSelectByExample() {

              // 获取Mapper

              UserMapper userMapper = this.context.getBean(UserMapper.class);

 

              // 创建User对象扩展类,用户设置查询条件

              UserExample example = new UserExample();

              example.createCriteria().andUsernameLike("%%");

 

              // 查询数据

              List<User> list = userMapper.selectByExample(example);

 

              System.out.println(list.size());

       }

 

       @Test

       public void testSelectByPrimaryKey() {

              // 获取Mapper

              UserMapper userMapper = this.context.getBean(UserMapper.class);

 

              User user = userMapper.selectByPrimaryKey(1);

              System.out.println(user);

       }

}

 

注意:

  1. 逆向工程生成的代码只能做单表查询
  2. 不能在生成的代码上进行扩展,因为如果数据库变更,需要重新使用逆向工程生成代码,原来编写的代码就被覆盖了。
  3. 一张表会生成4个文件

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值