java_mybatis总结一

mybatis的增删改查有几种方式

第三种注解(自定义方法)

IDEA创建项目时目录结构及配置文件

pom依赖

  <dependencies>
        <!--通用mapper-->
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper</artifactId>
            <version>4.1.5</version>
        </dependency>

        <!-- mybatis依赖 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.5</version>
        </dependency>
        
        <!-- 连接诶mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.37</version>
        </dependency>

        <!--测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>compile</scope>
        </dependency>

        <!--        log4j 日志依赖 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        
    <!--插件依赖-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.1.10</version>
        </dependency>
    </dependencies>
  

jdbc文件

jdbc.properties文件


driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis_mapper?useUnicode=true&characterEncoding=UTF-8&&serverTimezone=Hongkong&useSSL=false
username=root
password=root

日志文件

log4j.properties文件


### 设置###
# debug 日志级别,常用的4个日志级别:ERROR、WARN、 INFO、DEBUG
log4j.rootLogger = debug,stdout,D,E

### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = E://logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG 
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

### 输出ERROR 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://logs/error.log 
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR 
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

mybatis.xml

注意要:必须要把接口的那个包设置进来
mybatis.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>

    <!--引入 -->
    <properties resource="jdbc.properties"></properties>

    
    <!--开启驼峰映射-->
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>


    <!--分页插件-->
    <plugins>
        <!-- com.github.pagehelper为PageHelper类所在包名 -->
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
            <!-- 选择mysql数据库的分页方式 -->
            <property name="helperDialect" value="mysql"/>
            <property name="rowBoundsWithCount" value="true"/>
        </plugin>
    </plugins>


    <!-- 配置环境,连接需要的基本参数 -->
    <environments default="development">
        <environment id="development">
            <!-- 使用jdbc管理事务 -->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 配置数据源(配置连接) -->

            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>

        </environment>
    </environments>


    <mappers>
        <!--   加载映射文件的位置 接口的包-->
        <package name="Mybatis.Mapper"/>
        <package name="com.czxy.mapper"/>
    </mappers>

</configuration>

MyBatisMapperUtils工具

注意mybaits.xml的路径对应上不然读取不到文件


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 tk.mybatis.mapper.mapperhelper.MapperHelper;

import java.io.IOException;
import java.io.Reader;

public class MyBatisMapperUtils {

    private static SqlSessionFactory sqlSessionFactory = null;
	/*
     * 创建本地线程变量,为每一个线程独立管理一个session对象 每一个线程只有且仅有单独且唯一的一个session对象
     * 使用ThreadLocal对session进行管理,可以保证线程安全,避免多实例同时调用同一个session对象
     */
    private static ThreadLocal<SqlSession> threadlocal = new ThreadLocal<SqlSession>();

    // 创建sessionFactory对象,因为整个应用程序只需要一个实例工厂
    // 而静态代码块随着类的加载而执行,而且只执行一次,因此放入静态代码块中初始化工厂实例
    static {
        try {
            //读取配置文件
            Reader reader = Resources.getResourceAsReader("mybatis.xml");
            //创建会话工厂
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
            //关闭读取流
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 新建session会话,并把session放在线程变量中
     */
    private static void newSession() {
        //从刚刚创建的 sqlSessionFactory 中获取 session
        SqlSession session = sqlSessionFactory.openSession();

        //创建一个MapperHelper
        MapperHelper mapperHelper = new MapperHelper();

        //配置 mapperHelper 后,执行下面的操作
        mapperHelper.processConfiguration(session.getConfiguration());

        // 将session会话保存在本线程变量中
        threadlocal.set(session);
    }

    /**
     * 返回session对象
     * @return session
     */
    public static SqlSession getSession(){
        //优先从线程变量中取session对象
        SqlSession session = threadlocal.get();
        //如果线程变量中的session为null,
        if(session==null){
            //新建session会话,并把session放在线程变量中
            newSession();
            //再次从线程变量中取session对象
            session = threadlocal.get();
        }
        return session;
    }

    /**
     * 关闭session对象,并从线程变量中删除
     */
    public static void closeSession(){
        //读取出线程变量中session对象
        SqlSession session = threadlocal.get();
        //如果session对象不为空,关闭sessoin对象,并清空线程变量
        if(session!=null){
            session.close();
            threadlocal.set(null);
        }
    }

    /**
     * 提交并关闭资源
     */
    public static void commitAndclose() {

        //获取连接
        SqlSession openSession = getSession();
        //非空判断
        if(openSession!=null) {
            //提交
            openSession.commit();
            //关闭资源
            openSession.close();
            //从threadlocal中移除session
            threadlocal.remove();
        }
    }
}

java_mybatis总结一_第1张图片

字段

属性和表的字段 要么驼峰映射 ,要么书写的和表的字段一样

传参数

第一种 多个参数进行传递
注意:给sql赋值时@param的名字必须要与传入#{}里面的一样,前面调用时不需要注意这个字段,只要注意类型
java_mybatis总结一_第2张图片
第二种一个map 进行传递
注意:map传递设置的key名字必须要和传入#{}里面的一样
java_mybatis总结一_第3张图片
第三种一个pojo(对象)传递
传递的参数对象的属性名字必须要和#{}里面一样
java_mybatis总结一_第4张图片

SQL 自己手写

sql查询的结果接收的方式

map

@Select("SELECT brand_id,brand_name,brand_img,create_time,data_flag FROM brands WHERE brand_id = #{bid}")
public Map<String,Object> selectBrandById(Integer brandid);

pojo

java_mybatis总结一_第5张图片
@ResultMap 当多个方法返回结果需要用到这些重复字段时,可以调用上此次的
java_mybatis总结一_第6张图片

多对一 /一对一

订单 与用户 代码

 /*  映射的用户为空    原因是用了通用mapper  用户类的id没有使用注解*/
    @Select("SELECT \n" +
            "o.order_id,\n" +
            "o.user_id,\n" +
            "o.order_price,\n" +
            "o.payment,\n" +
            "o.state,\n" +
            "o.order_createtime,\n" +
            "o.note,\n" +
            "u.username,\n" +
            "u.phone\n" +
            "FROM orders o JOIN  `user` u\n" +
            "ON o.user_id=u.uid   AND  order_id=#{orderId};")
    @Results(id = "selectUser",value = {
        @Result(property = "orderId",column ="order_id",id = true),
        @Result(property = "userId",column = "user_id"),
         @Result(property = "orderPrice",column = "order_price"),
         @Result(property = "payment",column = "payment"),
         @Result(property = "state",column = "state"),
         @Result(property = "orderCreatetime",column = "order_createtime"),
         @Result(property = "note",column = "note"),
         /*多对一*/
//         @Result(property ="user" ,column = "user_id" ,one = @One(select ="Mybatis.Mapper.UserMapper.findByUid"))
         @Result(property ="users" ,column = "user_id" ,one = @One(select ="Mybatis.Mapper.UserMapper.selectByPrimaryKey"))
    })
    public Orders findOrderByOrderId(@Param("orderId") Integer orderId);

另一部分

    @Select("SELECT * FROM `user` WHERE uid=#{uid}")
    public User findByUid(@Param("uid") int uid);

再另一部分
java_mybatis总结一_第7张图片

总结 :多个对一个
1返回的结果是一个对象
2些sql时两表关联,用订单id查询 ,然后在用用户id查询一次,相当于查询了两次,所用的对应关系是 one =@One ,第二次查询时使用表的字段区查询,不然没数据,记得标记主键,记得二次查询的时候返回的结果字段明不用些错了 对象的值 users

一对多/多对多

代码


```java
  // 多对一
        @Select("SELECT\n" +
                "u.uid,\n" +
                "u.username,\n" +
                "u.sex,\n" +
                "u.birthday,\n" +
                "u.phone,\n" +
                "u.address,\n" +
                "o.order_id,\n" +
                "o.user_id,\n" +
                "o.order_price,\n" +
                "o.state,\n" +
                "o.order_createtime,\n" +
                "o.note\n" +
                "FROM `user` u  JOIN  orders o\n" +
                "ON u.uid=o.user_id  AND u.uid=#{uid}")
        /* 返回错了*/
        @Results(id = "selectUser" ,value = {
                @Result(property = "uid",column = "uid" ,id = true),
                @Result(property = "username",column = "username"),
                @Result(property = "birthday",column = "birthday"),
                @Result(property = "phone",column = "phone"),
                @Result(property = "sex",column = "sex"),
                @Result(property = "address",column = "address"),
                @Result(property = "orders",column ="order_id",many = @Many(select = "Mybatis.Mapper.OrderMapper.findByUserId"))
        })
    public List<User> findUserByUid(@Param("uid") int uid);

```java
    // 不是用uid查
    @Select("select * from orders where order_id=#{order_id}")
    public List findByUserId(@Param("order_id") int orderId);

java_mybatis总结一_第8张图片
总结
1返回的结果是集合
2两表关联查询先用用户id查询 ,二次查询再用订单id查询,many =@many
返回的 传递的 查询的

第二种通用mapper

字段
1自动驼峰映射
2忽略大小写

注意的是

1 在每个实体类写
@Table(name = “sys_user”)
2 一个实体类需要把Id标注出来需要用 @Id
3 当实体类的属性明和表的字段明不一样时 使用 @Column 进行映射上
4在查询时用不到,但是实体类需要这个字段时 ,其实就是实体类的字段和表中的字段不对应 ,就在实体类的不要查询的字段上些@Transient

通用mapper 的增删改查 推荐的用法

查询

java_mybatis总结一_第9张图片

代码


    // 查询  selectOne
    @Test
    public void selectOne() {
        SqlSession session = MyBatisMapperUtils.getSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = new User();
        // 传进去的都是些条件   设置的是一个用户需要同时 满足
        user.setUid(2);
        user.setSex("1");
        User one = mapper.selectOne(user);
        System.out.println(one);
    }

    /**
     * 根据主键查询
     * 查询所有
     *
     * 通用mapper  不能进行模糊查询 ,也不能查询某个属性值小于或者等于
     */
    @Test
    public void selecttwo() {
        SqlSession session = MyBatisMapperUtils.getSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        /*  User user = mapper.selectByPrimaryKey(2);*/
//        List userlist = mapper.selectAll();
         User nulluser = new User();
         nulluser.setSex("2");
         nulluser.setAddress("江苏南京");
        List<User> userlist = mapper.select(nulluser);
        for (User user : userlist) {
            System.out.println(user);
        }
    }

    /* 查询*/
    @Test
    public void selectthree(){
        SqlSession session = MyBatisMapperUtils.getSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user=new User();
      /*  user.getUid();*/
         int num = mapper.selectCount(user);
        System.out.println("一共"+num);
    }

添加

要提交事务 ,条件就是设置的属性值

  public void insertOne() {
        SqlSession session = MyBatisMapperUtils.getSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = new User();
        user.setUsername("mangseng2");
/*        user.setAddress("beijing");
        user.setPhone("11223366");*/
//        user.setBirthday(new Date());
        // 添加 ,没设置的值为null
        // 第一种方式
        mapper.insert(user);
        //第二种方式
        // 没有事务提交
//           mapper.insertSelective(user);
        session.commit();
        session.close();
    }

更新

要提交事务,切记要写条件,条件就是设置的属性值,不写条件回更新所有

  @Test
    public void updateOne() {
        SqlSession session = MyBatisMapperUtils.getSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        // 更行时有条件
        // 第一种方式
        User user = new User();
        // 条件
        user.setUid(2);
        user.setUsername("瑶瑶");

        // 第二种方式
        user.setAddress("湖南");
        mapper.updateByPrimaryKeySelective(user);


        // 第一种方式  不建议推荐
//        mapper.updateByPrimaryKey(user);

        session.commit();
        session.close();
    }

删除

提交事务 ,切记要些条件,不写条件会删掉所有

  @Test
    public void deleteOne(){

         SqlSession session = MyBatisMapperUtils.getSession();
         UserMapper mapper = session.getMapper(UserMapper.class);
         // 第一种方式 根据条件删除
        User user=new User();
        user.setUid(1);
     /*   user.setSex("2");
        user.setAddress("湖南");*/
//         mapper.delete(user);

        // 第二种
//        mapper.deleteByPrimaryKey(2);
         session.commit();
         session.close();


    }

Example 专注于查询

作用:大于 小于 模糊 专查某个字段的值 排序 动态sql 就是if 条件判断
使用步骤 :创建Example 对象 ,通过Example 对象创建条件对象 ,然后直接调用方法,调用一次 criteria.andGreaterThan 就相当于添加一个条件,切记这里所使用的字段都是实体类属性的字段,所有的条件写好后,调用mapper的example方法 返回结果
排序例子 example.orderBy(“brandId”).desc();
查询属性的方法
java_mybatis总结一_第10张图片
代码

   /*根据品牌名称模糊查询,根据创建日期进行范围查询*/

    @Test
    public void ExampleSelect2() throws ParseException {

         SqlSession session = MyBatisMapperUtils.getSession();

         BrandMapper mapper = session.getMapper(BrandMapper.class);

         // 使用 example 进行查询

         Example example = new Example(Brands.class);

         Example.Criteria criteria = example.createCriteria();

         Brands brands=new Brands();
        brands.setBrandName("%"+"百草"+"%");
        SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
         Date start = dateFormat.parse("2020-1-10");
         Date end = dateFormat.parse("2020-10-15");
       brands.setStartTime(start);
      brands.setEndTime(end);

         //  动态sql  三个条件
        if(brands.getBrandName()!=null&&!brands.getBrandName().equals("")){
            criteria.andLike("brandName",brands.getBrandName());
        }
         // 如果前面为空和下面为空 单独查询这个
        // 如果下面不为空 查询这个和下面这个

        //tk.mybatis.mapper.MapperException: 当前实体类不包含名为startTime的属性!
        if(brands.getStartTime()!=null){
            criteria.andGreaterThanOrEqualTo("createTime",brands.getStartTime());
        }

        //  前面两个为空 就单独查询这个
        if (brands.getEndTime()!=null){
            criteria.andLessThanOrEqualTo("createTime",brands.getEndTime());
        }

        //条件设置好了
         List<Brands> filter = mapper.selectByExample(example);

        for (Brands b : filter) {
            System.out.println(b);
        }

        session.close();
    }

  //查询ID > 1 并且 小于等于 3 或者ID 大于5的品牌,结果按照品牌ID降序排序

    /* example 适合运用 大于小于  模糊 在什么什么之间  同时  或者   就是where 后面的条件 or  and 可以排序  根据主键查询 */
    @Test
    public void ExampleSelect() {
        SqlSession session = MyBatisMapperUtils.getSession();

        BrandMapper mapper = session.getMapper(BrandMapper.class);

        Example example = new Example(Brands.class);
        // 设置条件的
        Example.Criteria criteria = example.createCriteria();



        // 类的字段 不是自定义的字段
        criteria.andGreaterThan("brandId", 1);
        criteria.andLessThanOrEqualTo("brandId", 3);
        criteria.orGreaterThanOrEqualTo("brandId", 5);
       // or 之前的条件时连续的同时满足的
        example.orderBy("brandId").desc();

        List<Brands> brands = mapper.selectByExample(example);
        // 通过这个查Example 查询
        for (Brands brand : brands) {
            System.out.println(brand);
        }
        session.close();
    }

第一种xml 方式

resultType 一个类用这
resultMap 一个类包含另外一个类用这个
项目结构

java_mybatis总结一_第11张图片
mybatis的配置文件
注意三个地方 查询后结果起别名 ,每个xml的相对路径写到mapper里面
,驼峰映射


<?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>

    <!--引入 -->
    <properties resource="jdbc.properties"></properties>

    <!--开启驼峰映射-->
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>


    <typeAliases>
        <!-- 写的是 每个类首字母的小写-->
        <package name="com.czxy.model"/>
        <package name="com.czxy.Vo"/>
    </typeAliases>




    <!-- 配置环境,连接需要的基本参数 -->
    <environments default="development">
        <environment id="development">
            <!-- 使用jdbc管理事务 -->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 配置数据源(配置连接) -->

            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>

        </environment>
    </environments>


    <mappers>
     <!--   加载映射文件的位置
    -->

        <mapper resource="mapper/UserMapper.xml"></mapper>
        <mapper resource="mapper/UserMapperDao.xml"></mapper>
        <mapper resource="mapper/BrandMapperDao.xml"></mapper>
        <!--通用mapper-->
        <package name="com.czxy.TY.mapper"/>

    </mappers>


</configuration>

注意就是
1 每个xml的namespace 都需要写上对应接口的名字的相对路径
java_mybatis总结一_第12张图片多对一的代码xml

association

resultMap接收 ,查询一次 先填充 order ,在填充user


   <!--1111111111111111111-->
            <resultMap id="selectOne" type="orders" extends="f01">

                <!-- 冗余代码-->
                <!--<id property="orderId" column="order_id"></id>
                <result property="userId" column="user_id"></result>
                <result property="orderPrice" column="order_price"></result>
                <result property="payment" column="paument"></result>
                <result property="state" column="state"></result>
                <result property="orderCreateTime" column="order_createtime"></result>
                <result property="note" column="note"></result>-->

                <!-- 对应关系
                对一  association
                对多 collection
                -->
                <association property="user">
                    <id property="uid" column="uid"></id>
                    <result property="username" column="username"></result>
                    <result property="birthday" column="birthday"></result>
                    <result property="phone" column="phone"></result>
                    <result property="sex" column="sex"></result>
                    <result property="address" column="address"></result>
                </association>
            </resultMap>

            <select id="listOrderAndUser" resultMap="selectOne">
                    SELECT
                    o.order_id,
                    o.user_id,
                    o.order_price,
                    o.payment,
                    o.note,
                    o.state,
                    o.order_createtime,
                    u.username,
                    u.phone
                    FROM  orders o JOIN `user` u
                    ON o.user_id=u.uid;
            </select>

嵌套查询 在 association 里面在查询一次,使用的时表的字段,查询两次
注意 防止包空 查询的返回结果
javaType=“user”


             <!--2222222222222222222222222-->

    <resultMap id="selectOne02" type="orders" extends="f01">
        <!-- 冗余代码-->
    <!--    <id property="orderId" column="order_id"></id>
        <result property="userId" column="user_id"></result>
        <result property="orderPrice" column="order_price"></result>
        <result property="payment" column="payment"></result>
        <result property="state" column="state"></result>
        <result property="orderCreatetime" column="order_createtime"></result>
        <result property="note" column="note"></result>-->
        <!-- 查询订单时  同时查询用户  用的是订单的userId  -->
        <association property="user" select="selectUserByID" column="user_id">
        </association>
    </resultMap>

    <select id="selectUserByID" resultType="user">
            SELECT
            uid,
            username,
            phone
            FROM
            `user`
            WHERE
            uid=#{uid}
    </select>


    
            <select id="listOrderBySelect" resultMap="selectOne02">
                  SELECT
                    o.order_id,
                    o.user_id,
                    o.order_price,
                    o.payment,
                    o.note,
                    o.state,
                    o.order_createtime,
                    u.username,
                    u.phone
                    FROM  orders o JOIN `user` u
                    ON o.user_id=u.uid;
                    </select>
    

使用过Vo ,查询的结果 返回给Vo ,查询一次

  <!--33333333333333333333333-->
    <select id="listOrderAndReturnOrdersVO"  resultType="OrderVo" >
        SELECT
        o.order_id,
        o.user_id,
        o.order_price,
        o.payment,
        o.note,
        o.state,
        o.order_createtime,
        u.username,
        u.phone
        FROM  orders o JOIN `user` u
        ON o.user_id=u.uid;
    </select>

公共代码块抽出来的


    
    
    
    
    
    
    

实体VO

public class OrderVo extends Orders {


    private String username;

    private String phone;

    public OrderVo() {
    }

    public OrderVo(String username, String phone) {
        this.username = username;
        this.phone = phone;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }


一对多的体现
java_mybatis总结一_第13张图片
多对一的体现
java_mybatis总结一_第14张图片

一对多
返回的集合需要些 类型 oftype=xxx,防止报空 ,查询一次

<!-- 1111111111111111111111111111   -->
    <resultMap id="brandAndProducesMap" type="brands">
        <id property="brandId" column="brand_id"></id>
        <result property="brandName" column="brand_name"></result>
        <result property="brandImg" column="brand_img"></result>

        <!--一对多 collection   防止报空  必须写ofType 指定集合类型 -->
        <collection property="listProduct" ofType="product">  <!--listProduct-->
            <id property="productId" column="product_id"></id>
            <result property="productImg" column="product_img"></result>
            <result property="productName" column="product_name"></result>
            <result property="productSale" column="product_sale"></result>
            <result property="productPrice" column="product_price"></result>
        </collection>
    </resultMap>

    <!--Exception in thread "main" org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 2-->
    <select id="selectBrandListProduct" resultMap="brandAndProducesMap">
          SELECT
             b.brand_id,
             b.brand_name,
             b.brand_img,
             p.product_id,
             p.product_img,
             p.product_name,
             p.product_sale,
             p.stock,
             p.product_price,
             p.brandid
             FROM
             brands b JOIN product p
             ON b.brand_id=p.brandid
    </select>

第二种嵌套 oftype=xx

多个类 resultMap—>type
一个类---->resulttype

<!-- 22222222222-->
    <resultMap id="baseResultMap" type="brands">
        <id property="brandId" column="brand_id"></id>
        <result property="brandName" column="brand_name"></result>
        <result property="brandImg" column="brand_img"></result>
    </resultMap>


    <resultMap id="resultMapBySelect" type="brands" extends="baseResultMap">
        <collection property="listProduct" column="brand_id" select="listProductsByBrandID"></collection>
    </resultMap>


    <select id="listProductsByBrandID" resultType="product">
         SELECT
            product_id,
            product_img,
            product_name,
            product_sale,
            stock,
            product_price,
            brandid
        FROM product
        WHERE brandid = #{brandID}
    </select>



    <select id="selectBrandAndListProducts" resultMap="resultMapBySelect" >
         SELECT
         brand_id,
         brand_img,
         brand_name
         FROM
         brands
         WHERE
         brand_id=#{brand_id}
    </select>

多对多的数据

/*Table structure for table `tab_student` */

DROP TABLE IF EXISTS `tab_student`;

CREATE TABLE `tab_student` (
  `sid` int NOT NULL AUTO_INCREMENT COMMENT '学生ID',
  `student_name` varchar(30) DEFAULT NULL COMMENT '姓名',
  `student_birthday` date DEFAULT NULL COMMENT '生日',
  `student_height` double DEFAULT NULL COMMENT '身高',
  `sex` varchar(2) DEFAULT NULL COMMENT '性别',
  PRIMARY KEY (`sid`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

/*Data for the table `tab_student` */

insert  into `tab_student`(`sid`,`student_name`,`student_birthday`,`student_height`,`sex`) values (1,'褚英才','1997-02-01',175,'男'),(2,'绍洋','1999-08-21',160,'女'),(3,'司徒玉','2000-10-12',162,'女'),(4,'孟杨','1999-06-08',172,'男'),(5,'郎桂芝','1998-10-26',168,'女');

/*Table structure for table `tab_student_teacher` */

DROP TABLE IF EXISTS `tab_student_teacher`;

CREATE TABLE `tab_student_teacher` (
  `id` int NOT NULL AUTO_INCREMENT,
  `sid` int DEFAULT NULL COMMENT '学生ID',
  `tid` varchar(32) DEFAULT NULL COMMENT '老师ID',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

/*Data for the table `tab_student_teacher` */

insert  into `tab_student_teacher`(`id`,`sid`,`tid`) values (1,1,'T001'),(2,2,'T001'),(3,1,'T002'),(4,3,'T002'),(5,5,'T002'),(6,2,'T003');

/*Table structure for table `tab_teacher` */

DROP TABLE IF EXISTS `tab_teacher`;

CREATE TABLE `tab_teacher` (
  `tid` varchar(32) NOT NULL COMMENT '老师ID',
  `tname` varchar(30) DEFAULT NULL COMMENT '姓名',
  `tsex` varchar(3) DEFAULT NULL COMMENT '性别',
  PRIMARY KEY (`tid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

/*Data for the table `tab_teacher` */

insert  into `tab_teacher`(`tid`,`tname`,`tsex`) values ('T001','韩老师','男'),('T002','董老师','男'),('T003','茆老师','女');



public class Teacher {

private String tid;
private String tname;
private String tsex;
//老师对应多个学生
List stuList = new ArrayList();

//get set...

}

public class Student {
private Integer sid;
private String studentName;
private Date studentBirthday;
private Double studentHeight;
private String sex;

//学生对应多个老师
private List teacherList = new ArrayList<>();
//get set...

}

StudentMapper.xml

<resultMap id="studentBaseMap" type="student">
    <id property="sid" column="sid"/>
    <result property="studentName" column="student_name"/>
    <result property="studentBirthday" column="student_birthday"/>
    <result property="studentHeight" column="student_height"/>
    <result property="sex" column="sex"/>
    <collection property="teacherList" ofType="Teacher">
        <id property="tid" column="tid"/>
        <result property="tname" column="tname"/>
        <result property="tsex" column="tsex"/>
    </collection>
</resultMap>

<select id="selectStudentAndTeachers" resultMap="studentBaseMap">
    SELECT
    s.sid,
    s.student_name,
    s.student_birthday,
    s.student_height,
    s.sex,
    t.tid,
    t.tname,
    t.tsex
    FROM tab_student s,tab_student_teacher st,tab_teacher t
    WHERE s.sid = st.sid
    AND st.tid = t.tid
    AND s.sid = #{sid}
</select>

总结

xml 可以查询一次 也可以查询两次 注解必须查询两次 ,xml可以查询单表 ,也可查询多表 注解可以查询单表和多表

你可能感兴趣的:(java_mybatis总结一)