MyBatis学习第一天

一.简介

MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架。
MyBatis 消除 了几乎所有的 JDBC 代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML 或注解用于配置和原始映射,将接口和 Java 的 POJOs(Plain Ordinary Java Objects,普通的 Java 对象)映射成数据库中的记录。
MyBatis的前身是iBatis,MyBatis在iBatis的基础上面,对代码结构进行了大量的重构和简化;

二.第一个程序(3.1.1)

1.导入相关的包资源

在这里插入图片描述

2.添加著主配置文件(mybatis-config.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>
    <!-- 和spring整合后 environments配置将废除-->
    <environments default="development">
        <environment id="development">
            <!-- 使用jdbc事务管理,事务控制由mybatis,该处是别名-->
            <transactionManager type="JDBC" />
            <!-- 数据库连接池,由mybatis管理,该处是别名-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql:///mybatisdemo" />
                <property name="username" value="root" />
                <property name="password" value="123456" />
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="com/mxl/mybatis01_hello/UserMapper.xml"></mapper>
    </mappers>
</configuration>

3.添加domain文件(User)

package com.mxl.mybatis01_hello;

public class User {
    private Long id;
    private String username;
    private String password;
    private Integer age;

    public User() {
    }

    public User(Long id, String username, String password, Integer age) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.age = age;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

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

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", age=" + age +
                '}';
    }
}

4.需要添加domain文件的映射信息(USerMapper.xml)

需要注意的两点是:
1.mapper的namespace中写的是所在包名加上mapper文件名
namespace=“com.mxl.mybatis01_hello.UserMapper”

2.配置自增的id注入对象中

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mxl.mybatis01_hello.UserMapper">
    <!--
    inser表示插入语句
    parameterType表示调用insert传入的参数
    keyColumn表示数据库中自增长的字段名
    keyProperty表示自增长的字段值应该注入到实体中的哪个字段
    useGeneratedKeys表示标记这个标签需要使用数据库中的自增长id
    -->
    <insert id="save" parameterType="com.mxl.mybatis01_hello.User" keyColumn="id" keyProperty="id" useGeneratedKeys="true">
        insert into t_user(username,password,age) values (#{username},#{password},#{age})
    </insert>
</mapper>

5.将domain的配置文件添加到主配置文件中

    <mappers>
        <mapper resource="com/mxl/mybatis01_hello/UserMapper.xml"></mapper>
    </mappers>

6.编写测试类,保存对象

注意:session.insert中的statement为namespace加id

public class TestCRUD {
    @Test
    public void test1() throws IOException {
        User u = new User();
        u.setUsername("撒旦");
        u.setPassword("123456");
        u.setAge(13);
        SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
        SqlSession session = sf.openSession();
        session.insert("com.mxl.mybatis01_hello.UserMapper.save",u);
        session.commit();
        session.close();
        System.out.println(u);
    }
}

三.监控sql语句

1.在资源目录下添加log4j.preperties并添加如下配置:

高光处应该写自己的namespace的包名或者父包名.
log4j.logger.com.mxl.mybatis01_hello=TRACE

# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.com.mxl.mybatis01_hello=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

四.更新操作:

Usermapper.xml中添加:

   <update id="update" parameterType="com.mxl.mybatis01_hello.User">
        update t_user set username=#{username},password=#{password},age=#{age} where id = #{id}
    </update>

测试类中添加:

  @Test
    public void test2() throws IOException {
        User u = new User();
        u.setId(1L);
        u.setUsername("马欣龙");
        u.setPassword("123");
        u.setAge(22);
        SqlSessionFactory sf =  new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
        SqlSession session = sf.openSession();
        session.update("com.mxl.mybatis01_hello.UserMapper.update",u);
        session.commit();
        session.close();
        System.out.println(u);
    }

此时发现每个测试方法中都要写

   SqlSessionFactory sf =  new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
        SqlSession session = sf.openSession();

抽取mybatisUtils工具类

public class MybatisUtils {
    private SqlSessionFactory sf = null;
    private static MybatisUtils instance = new MybatisUtils();
    private MybatisUtils(){
        try {
            sf =  new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    public static SqlSession openSession(){
        return instance.sf.openSession();
    }
}

五.查询单个对象操作:

Usermapper.xml中添加:

特别注意:要加resultType:表示查询出来的每一条结果封装成User对象
如果没写则报如下错误:
Caused by: org.apache.ibatis.executor.ExecutorException: A query was run and no Result Maps were found for the Mapped Statement ‘com.mxl.mybatis01_hello.UserMapper.get’. It’s likely that neither a Result Type nor a Result Map was specified.

    <!--
    parameterType:
    resultType:表示查询出来的每一条结果封装成User对象
    -->
    <select id="get" parameterType="java.lang.Long" resultType="com.mxl.mybatis01_hello.User">
        select id,username,password,age from t_user where id = #{id}
    </select>

测试类中添加:

    @Test
    public void test3() throws IOException {
        SqlSession session = MybatisUtils.openSession();
        User u = session.selectOne("com.mxl.mybatis01_hello.UserMapper.get", 3L);
        session.close();
        System.out.println(u);
    }

六.查询所有操作:

Usermapper.xml中添加:

 <!--
      parameterType:
      resultType:表示查询出来的每一条结果封装成User对象
    -->
    <select id="list" resultType="com.mxl.mybatis01_hello.User">
        select * from t_user
    </select>

测试类中添加:

   @Test
    public void test4() throws IOException {
        SqlSession session = MybatisUtils.openSession();
        List<User> list = session.selectList("com.mxl.mybatis01_hello.UserMapper.list");
        session.close();
        for (User user : list) {
            System.out.println(user);
        }
    }

七.删除操作:

Usermapper.xml中添加:

<delete id="delete" parameterType="java.lang.Long">
        delete from t_user where id = #{id}
    </delete>

测试类中添加:

  @Test
    public void testDelete() throws IOException {
        SqlSession session = MybatisUtils.openSession();
        session.delete("com.mxl.mybatis01_hello.UserMapper.delete", 2L);
        session.commit();
        session.close();
    }

八.补充内容:

mybatis中提供了很多别名,比如java.lang.Long的别名为小写的long.

parameterType="long"相当于parameterType=“java.lang.Long”

九.自定义别名

1.在主配置文件mybatis-config.xml中添加

 <!--定义别名:
    type:需要定义别名的类的全限定名
    alias:定义的别名
    -->
    <typeAliases>
        <typeAlias type="com.mxl.mybatis01_hello.User" alias="User"/>
    </typeAliases>

2.在UserMapper中就可以使用User的别名了

    <select id="list" resultType="User">
        select * from t_user
    </select>

十.使用db.properties配置

方式一:

1.新建db.properties文件.
2.主配置文件中使用占位符的方式定义数据库连接信息.

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

3.在mybatisUtils类中创建sqlsessionfactory的时候传入properties对象

   try {
            Properties p = new Properties();
            p.load(Resources.getResourceAsReader("db.properties"));
            sf =  new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"),p);
        }catch (Exception e){
            e.printStackTrace();
        }

方式二:

1.新建db.properties文件.
2.直接在主配置文件中配置

<properties resource="db.properties"/>

十一.使用Mapper接口的方式

使用statementID的方式存在如下问题

①.传入的statement字符串有可能会写错,写错的时候必须等到运行的时候才发现
②.传入的参数无法限定类型.

使用Mapper接口的方式

1.新键UserMapper接口(确保以下几点)
接口的全限定名 等于 UserMapper.xml中的namespace
接口中的方法 等于 UserMapper.xml中标签中的id
接口方法上的参数 等于 UserMapper.xml中的parameterType
接口方法上的返回值类型 等于 UserMapper.xml的resultType

对应的API为:

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

十二.ResultMap映射

当查询出来的字段名和对象中的属性名不一致的情况,就没办法使用resultType来默认映射(同名规则)
解决方案:
使用resultMap来映射数据库中的字段到底注入到对象中什么属性中.
1.在UserMapper.xml文件中定义resultMap标签

<resultMap id="base_map" type="User">
        <!--
        column:查询出来的字段名
        property:对象中属性名
        -->
        <id column="d_id" property="id"></id>
        <result column="d_username" property="username"></result>
        <result column="d_password" property="password"></result>
        <result column="d_age" property="age"></result>
    </resultMap>

2.在查询标签中使用resultMap=”base_map”

  <!--
      resultType:表示查询出来的每一条结果封装成User对象
      resultType与resultMap不可混用
    -->
    <select id="list" resultMap="base_map">

        select id as d_id,username as d_username,password as d_password,age as d_age from t_user
    </select>

十三.动态sql

1.条件查询

创建一个查询对象类QueryObject

public class QueryObject {
    private String keyWord;
    private Integer beginAge;
    private Integer endAge;
//getter setter方法略去
}

在UserMapper.xml中添加如下代码
注意:id中的内容应该与UserMapper接口中的方法名保持一致,否则报错!!!
注意:模糊查询语法like concat(’%’,#{keyWord},’%’)中
concat的使用—单引号的使用
注意:(大于号> >小于号 < <)
注意如果要大于(小于)等于,等于号必须紧跟在>(<)后,中间不能有空格

<!--条件查询
    注意:id中的内容应该与UserMapper接口中的方法名保持一致,否则报错!!!
    where标签
    if标签 
    注意:模糊查询语法like concat('%',#{keyWord},'%'),concat的使用以及单引号的使用
    注意:(大于号> &gt;小于号 < &lt;) 
    注意如果要大于(小于)等于,等于号必须紧跟在&gt;(&lt;)后,中间不能有空格
    -->
    <select id="selectByCondition" parameterType="com.mxl.mybatis01_hello.QueryObject" resultType="User">
        select * from t_user
        <where>
            <if test="keyWord!=null">
                and username like concat('%',#{keyWord},'%')
            </if>
            <if test="beginAge!=null">
                and age &gt;= #{beginAge}
            </if>
            <if test="endAge!=null">
                and age &lt;= #{endAge}
            </if>
        </where>
    </select>

Usermapper接口中给出相应的方法

    List<User> selectByCondition(QueryObject qo);

测试类中给出相应测试方法

  @Test
    public void testQuery(){
        SqlSession session = MybatisUtils.openSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        QueryObject qo = new QueryObject();
     // qo.setKeyWord("东");
        qo.setBeginAge(2);
        qo.setEndAge(18);
        List<User> list = mapper.selectByCondition(qo);
        for (User user : list) {
            System.out.println(user);
        }
        session.close();
    }

2.动态更新

UserMapper.xml中添加如下
该处犯错
首先where不能丢掉
每个if语句后要加上逗号,不加报错!!!

 <!--动态更新
    首先where不能丢掉
    每个if语句后要加上逗号,不加报错!!!
    -->
    <update id="updateDy" parameterType="User">
        update t_user
        <set>
            <if test="username!=null">
                username = #{username},
            </if>
            <if test="password!=null">
                password = #{password},
            </if>
            <if test="age!=null">
                age = #{age},
            </if>
        </set>
        where id = #{id}
    </update>

接口中给出相应的方法

    void updateDy(User u);

测试类中编写测试方法

 @Test
    public void testUpdateDy(){
        SqlSession session = MybatisUtils.openSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        User u = new User();
        u.setId(8L);
        u.setUsername("卡萨丁");
        u.setPassword("666");
        u.setAge(11);
        mapper.updateDy(u);
        session.commit();
        session.close();
    }

trim的使用

trim的属性:

prefix表示使用前缀
suffix表示使用的后缀

prefixOverrides表示前缀需要覆盖的内容
suffixOverrides表示后缀需要覆盖的内容

UserMapper.xml中
查询中原来的where可以用trim标签加上特定的属性来替代

and与where(覆盖最前面的and)

<select id="selectByCondition" parameterType="com.mxl.mybatis01_hello.QueryObject" resultType="User">
        select * from t_user
        <trim prefix="where" prefixOverrides="and">
            <if test="keyWord!=null">
                and username like concat('%',#{keyWord},'%')
            </if>
            <if test="beginAge!=null">
                and age &gt;= #{beginAge}
            </if>
            <if test="endAge!=null">
                and age &lt;= #{endAge}
            </if>
        </trim>
    </select>

动态更新中原来的set可以用trim标签加上特定的属性来替代

逗号与set(覆盖最后一个逗号)

 <update id="updateDy" parameterType="User">
        update t_user
        <trim suffixOverrides="," prefix="set">
            <if test="username!=null">
                username = #{username},
            </if>
            <if test="password!=null">
                password = #{password},
            </if>
            <if test="age!=null">
                age = #{age},
            </if>
        </trim>
        where id = #{id}
    </update>

foreach标签

迭代一个集合, 通常是构建在 IN 条件中的
foreach 元素是非常强大的,它允许你指定一个集合,声明集合项和索引变量,它们可 以用在元素体内。它也允许你指定开放和关闭的字符串,在迭代之间放置分隔符。这个元素 是很智能的,它不会附加多余的分隔符。
注意 你可以传递一个 List 实例或者数组作为参数对象传给 MyBatis。当你这么做时 ,MyBatis 会自动将它包装在一个 Map 中,用名称在作为键。List 实例将会以“list” 作为键,而数组实例将会以“array”作为键。

需求:查询id为4,5,6,7,8的用户

Mapper文件中的代码如下:
open和close配置的是以什么符号将这些集合元素包装起来
collection:选择list集合
separator:是各个元素的间隔符
item:配置的是循环中当前的元素

<select id="selectForEach" resultType="User">
        select * from t_user where id in
        <foreach collection="list" open="(" close=")" separator="," item="value">
            #{value}
        </foreach>
    </select>

Mapper接口中

    List<User> selectForEach(List<Long> idList);

测试类中代码

  @Test
    public void testForEach() {
        SqlSession session = MybatisUtils.openSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        List<Long> list = new ArrayList<Long>();
        list.add(4L);
        list.add(5L);
        list.add(6L);
        list.add(7L);
        list.add(8L);
        List<User> userList = mapper.selectForEach(list);
        for (User user : userList) {
            System.out.println(user);
        }
        session.close();
    }

十四.高级查询加分页

1.编写PageResult类

public class PageResult {
    private Long total;
    private List rows;
    public static final PageResult EMPTY = new PageResult(0L,Collections.emptyList());
    public PageResult(Long total, List rows) {
        this.total = total;
        this.rows = rows;
    }
//略去setter和getter方法
}

2.在QueryObject类中添加:

  //分页
    private Long page;//当前页
    private Long row;//每页显示几条数据
    //略去getter,setter方法

3.编写IUserService接口

public interface IUserService {
    PageResult list(QueryObject qo);
}

4.编写service实现类

public class UserServiceImpl implements IUserService{

    public PageResult list(QueryObject qo) {
        SqlSession session = MybatisUtils.openSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        try {
            //查询总数
            Long count = mapper.selectByConditionCount(qo);
            if (count > 0){
                List<User> result = mapper.selectByCondition(qo);
                return new PageResult(count,result);
            }else{
                return PageResult.EMPTY;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            session.close();
        }
        return null;
    }
}

5.在mapper配置文件中

 <!--公共的查询条件-->
    <sql id="condition">
        <trim prefix="where" prefixOverrides="and">
            <if test="keyWord!=null">
                and username like concat('%',#{keyWord},'%')
            </if>
            <if test="beginAge!=null">
                and age &gt;= #{beginAge}
            </if>
            <if test="endAge!=null">
                and age &lt;= #{endAge}
            </if>
        </trim>
    </sql>
    <select id="selectByConditionCount" resultType="long">
        select count(*) from t_user
        <include refid="condition"/>
    </select>
   
    <select id="selectByCondition" parameterType="com.mxl.mybatis01_hello.domain.QueryObject" resultType="User">
        select * from t_user
       <include refid="condition"/>
        limit #{start},#{row}
    </select>

6.测试类

    @Test
    public void test() throws IOException {
        QueryObject qo = new QueryObject();
        qo.setKeyWord("东");
        qo.setPage(1L);
        qo.setRow(2L);
        IUserService service = new UserServiceImpl();
        PageResult page = service.list(qo);
        System.out.println("总记录数: "+page.getTotal());
        List<User> rows = page.getRows();
        for (User u : rows) {
            System.out.println(u);
        }
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MyBatis中实现一对多关系可以通过使用collection标签来实现。[2] 在映射文件中,可以使用resultMap标签定义一个结果集映射,通过在resultMap中使用collection标签来指定一对多关系的映射关系。 具体操作如下: 1. 在查询语句中,使用JOIN语句将主表和从表连接起来,以获取一对多关系的数据。在查询语句中使用别名,以便在映射文件中进行引用。 2. 在resultMap中,使用collection标签指定一对多关系的映射关系。在collection标签的ofType属性中指定从表对应的实体类。 3. 在collection标签内部,使用result标签来映射从表的字段到实体类的属性。 例如,下面是一个实现一对多关系的映射文件示例: ```xml <select id="getTeacher" resultMap="TeacherStudent"> select t.id tid, t.name tname, s.name sname, s.id sid from mybatis.teacher t, mybatis.student s where t.id = s.tid </select> <resultMap id="TeacherStudent" type="Teacher"> <result property="name" column="tname"/> <result property="id" column="tid"/> <collection property="students" ofType="Student"> <result property="name" column="sname"/> <result property="id" column="sid"/> <result property="tid" column="tid"/> </collection> </resultMap> ``` 在上面的示例中,查询语句通过连接teacher表和student表获取一对多关系的数据。resultMap中使用collection标签来指定students属性是一个集合类型,并使用result标签来映射student表的字段到Student实体类的属性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [SSM框架的学习与应用JavaEE(第二天)Mybatis的深入学习](https://download.csdn.net/download/m0_53659738/88241458)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Mybatis多表查询之一对多、多对一](https://blog.csdn.net/qq_53860947/article/details/123743724)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值