美文网首页
Mybatis入门一篇就够了

Mybatis入门一篇就够了

作者: 一巴掌拍出两坨脂肪 | 来源:发表于2021-04-08 11:20 被阅读0次
    版权声明:本文为作者原创书籍。转载请注明作者和出处,未经授权,严禁私自转载,侵权必究!!!

    情感语录:业余生活要有意义,不要越轨!

    Mybatis 的下载并搭建

    下载地址:https://github.com/mybatis/mybatis-3

    本文采用mybatis-3.5.0 正式版学习。最好把夹包和源码包都下载下来,方便看demo中的模板,mybatis-3.5.0.zipmybatis-3-mybatis-3.5.0.zip

    Mybatis之 Sqlsession,所有的操作基本靠这个来完成的,那它到底有啥作用呢?

    Sqlsession的作用:

    1、向sql语句传入参数

    2、执行SQL语句

    3、获取执行sqL语句的结果

    4、事务的控制

    如何得到 Sqlsession:

    1、通过配置文件获取数据库连接相关信息

    2、通过配置信息构建Sqlsessionfactory

    3、通过 Sqlsessionfactory打开数据库会话

    public class DBAccess {
    
    public SqlSession getSqlSession() throws IOException{
    
        //第一步 通过配置文件获取数据库连接信息
        Reader reader = Resources.getResourceAsReader("com/learn/config/Configuration.xml");
    
        //第二步 通过配置信息构建一个 Sqlsessionfactor
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
    
        //第三步 通过 sqlsessionfactory打开个数据库会话
        SqlSession sqlSession = sqlSessionFactory.openSession();
        return sqlSession;
    }
    
    }
    

    Configuration.xml?这是什么鬼,客官莫急,该配置文件就是我们刚下载下来的源码包中就有的,参照学习,路径:\src\test\java\org\apache\ibatis\submitted\complex_property

    将该文件拷贝到你工程中,其他看不懂的先注释掉,只保留下面这段就好(源配置文件中并没有password这项 需要手动配置上,这里用mysql举例)

    <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC">
        <property name="" value=""/>
      </transactionManager>
      <dataSource type="UNPOOLED">
        <!--配置mysql驱动-->
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <!--配置数据库-->
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/teststudy"/>
        <!--数据库的用户名-->
        <property name="username" value="root"/>
        <!--数据库的密码-->
        <property name="password" value="zxy1546688949"/>
      </dataSource>
    </environment>
    </environments>
    

    新建数据库:"teststudy",名字谁便取,需要注意的是对应上Configuration.xml文件中配置的数据库url。新建一张"message"表,添加"id","title","content"三个字段,我这里方便测试id就没让自增长。

    数据库和表都建立完成,激动的心颤动的手,我已经安奈不住想插入数据了,下面先举个例使用mybatis向数据库插入数据:

    额??怎么插呢?先将Configuration.xml同目录下的User.xml配置文件也拷贝到工程并改名MessageBean.xml,并在Configuration.xml配置文件添加该文件的路径信息:

     <mappers>
      <mapper resource="com/learn/sqlxml/MessageBean.xml"/>
     </mappers>
    

    找到insert语句,简单修改下如下:

    ① 单条语句插入:

       <!--注意拼接sql语法-->
    <insert id="insertMessage" parameterType="com.learn.parameter.MessageParam" statementType="PREPARED"
            keyProperty="id" useGeneratedKeys="true">
        INSERT INTO message
        (
        id,
        title,
        content
        )
        VALUES
        (
        #{id,jdbcType=INTEGER},
        #{title,jdbcType=VARCHAR},
        #{content,jdbcType=VARCHAR}
        )
    </insert>
    

    编写代码:

    public void insertMsg(String id,String title, String content) {
        DBAccess dbAccess = new DBAccess();
        SqlSession sqlSession = null;
        try {
            sqlSession = dbAccess.getSqlSession();
            //执行sql语句
            MessageParam msg = new MessageParam();
            msg.setId(id);
            msg.setTitle(title);
            msg.setContent(content);
            sqlSession.insert("insertMessage", msg);
            //注意提交
            sqlSession.commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != sqlSession) {
                sqlSession.close();
            }
        }
    }
    

    测试代码:

    @Test
    public void testInsertMsg(){
        ApiTest apiTest = new ApiTest();
        //添加点信息
        apiTest.insertMsg("1","hello","word");
    }
    

    执行上面代码刷新数据库


    哎呀,这就插入数据库了,简直不能太方便..........多来几条数据试试看!

    ② 在MessageBean.xml中添加如下进行批量插入:

    <!--批量插入-->
    <insert id="insertListMsg" parameterType="java.util.List" useGeneratedKeys="true">
        insert into message
        (id,title,content)
        values
        <foreach collection="list" item="item"  index="index" separator =",">
            (
            #{item.id,jdbcType=INTEGER},
            #{item.title,jdbcType=VARCHAR},
            #{item.content,jdbcType=VARCHAR}
            )
        </foreach>
    </insert>
    

    编写代码:

    public void insertListMsg(List<MessageParam> list) {
        DBAccess dbAccess = new DBAccess();
        SqlSession sqlSession = null;
        try {
            sqlSession = dbAccess.getSqlSession();
            //执行sql语句
            sqlSession.insert("insertListMsg", list);
            //注意提交
            sqlSession.commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != sqlSession) {
                sqlSession.close();
            }
        }
    }
    

    测试代码:

    @Test
    public void testInsertListMsg(){
        ApiTest apiTest = new ApiTest();
        List<MessageParam> paramList = new ArrayList<>();
        //添加点信息
        for (int i = 2; i<22;i++){
            MessageParam param = new MessageParam();
            param.setId(i+"");
            param.setTitle("你看我头上是几"+i);
            param.setContent("这是第"+i+"条数据");
            paramList.add(param);
        }
        apiTest.insertListMsg(paramList);
    }
    

    执行上面方法刷新数据库可以看到下面最新插入的数据。


    属性介绍:useGeneratedKeys 参数只针对 insert 语句生效,默认为 false。当设置为 true 时,表示如果插入的表以自增列为主键,则允许 JDBC 支持自动生成主键,并可将自动生成的主键返回。

    具体用法:
    useGeneratedKeys=”true” keyProperty=”对应的主键的对象”。

    ③ 有了数据我们进行查询下,下面来个最简单的表查询,在MessageBean.xml中添加如下:

    <!--resultMap 这里指查询的结果需要对应到那些列上  parameterType 指定参数类型,当多个参数是使用对象包装-->
    <select id="queryListMessage" resultMap="messageResult">
    SELECT * FROM Message
    </select>
    

    注:这里使用到了resultMap 属性,resultMap 这里指查询的结果需要对应到那些属性上(需要创建实体建立对应关系),resultMap 指定的实体类指向了id 为messageResult的配置信息,在MessageBean.xml中添加如下:

    <!-- resultMap type指 MessageBean这个实体类,这步就相当传统的jdbc set方法避免了手动, id 在该节点中不允许同名-->
    <resultMap type="com.learn.bean.MessageBean" id="messageResult">
        <!--id 用于主键列-->
        <id column="id" jdbcType="INTEGER" property="id"/>
        <!--普通列-->
        <result column="title" jdbcType="VARCHAR" property="title"/>
        <result column="content" jdbcType="VARCHAR" property="content"/>
    </resultMap>
    

    编写代码:

    public List<MessageBean> queryMessageList() {
    
        List<MessageBean> listBean = new ArrayList<>();
        DBAccess dbAccess = new DBAccess();
        SqlSession sqlSession = null;
        try {
            sqlSession = dbAccess.getSqlSession();
    
            listBean = sqlSession.selectList("queryListMessage");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != sqlSession) {
                sqlSession.close();
            }
        }
    
        return listBean;
    }
    

    测试用例:

    @Test
    public void testQureyListMsg(){
        ApiTest apiTest = new ApiTest();
        //查询全部
        List<MessageBean> listBeans = apiTest.queryMessageList();
        for (int i = 0; i < listBeans.size(); i++) {
            System.out.println(listBeans.get(i).toString());
        }
    }
    

    输出结果:

     MessageBean{id='1', content='word', title='hello'}
     MessageBean{id='2', content='这是第2条数据', title='你看我头上是几2'}
     MessageBean{id='3', content='这是第3条数据', title='你看我头上是几3'}
     MessageBean{id='4', content='这是第4条数据', title='你看我头上是几4'}
     MessageBean{id='5', content='这是第5条数据', title='你看我头上是几5'}
     MessageBean{id='6', content='这是第6条数据', title='你看我头上是几6'}
     MessageBean{id='7', content='这是第7条数据', title='你看我头上是几7'}
     ........
    

    ④假如我只想查询id为5的这条数据呢?那好sql的基本操作条件查询,在MessageBean.xml中添加如下:

    <!--条件查询-->
    <select id="queryMessage" parameterType="com.learn.parameter.MessageParam" resultMap="messageResult">
        SELECT * FROM Message WHERE id = #{id}
    </select>
    

    注:原生sql语句要查询id=5的这条数据是不是这样写:select * from message where id = 5,开发中肯定不能写死在程序,是不是通过?进行占位啊?那好在mybatis中是通过#{属性}的方式,这个属性是怎么来的呢?是由:parameterType属性配置方式指定,如上parameterType="com.learn.parameter.MessageParam" 即:MessageParam实体的完整包路径:

    public class MessageParam {
    
    private String id;
    private String content;
    private String title;
    public String getTitle() {
        return title;
    }
    
    public void setTitle(String title) {
        this.title = title;
    }
    
    public String getId() {
        return id;
    }
    
    public void setId(String id) {
        this.id = id;
    }
    
    public String getContent() {
        return content;
    }
    
    public void setContent(String content) {
        this.content = content;
       }
    }
    

    编写代码:

    public MessageBean qureyMsg(String id) {
        DBAccess dbAccess = new DBAccess();
        SqlSession sqlSession = null;
        MessageBean bean = null;
        try {
            sqlSession = dbAccess.getSqlSession();
            //执行sql语句
            bean = sqlSession.selectOne("queryMessage", id);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != sqlSession) {
                sqlSession.close();
            }
        }
        return bean;
    }
    

    测试用例:

    @Test
    public void testQureyOneMsg(){
        ApiTest apiTest = new ApiTest();
        //查询id为1的信息
       MessageBean messageBean = apiTest.qureyMsg("5");
    
       System.out.println(messageBean.toString());
    }
    

    输出结果:

     2019-03-22 13:17:36,073 [main] DEBUG [Message.queryMessage] - <==      Total: 1
     MessageBean{id='5', content='这是第5条数据', title='你看我头上是几5'}
    

    ⑤删除数据:怎么通过mybatis删除数据信息呢?和查询等操作没什么区别,在MessageBean.xml中添加如下代码:

    <delete id="delete" parameterType="com.learn.parameter.MessageParam">
        DELETE FROM message WHERE id = #{id:INTEGER}
    </delete>
    

    编写代码:

    public void delMsg(String id) {
        DBAccess dbAccess = new DBAccess();
        SqlSession sqlSession = null;
        try {
            sqlSession = dbAccess.getSqlSession();
            //执行sql语句
            sqlSession.delete("delete", id);
            //注意提交
            sqlSession.commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != sqlSession) {
                sqlSession.close();
            }
        }
    }
    

    测试用例:

    @Test
    public void testDelMsg(){
        ApiTest apiTest = new ApiTest();
        //删除第一条 hello word信息。
        apiTest.delMsg("1");
    }
    

    结果输出:

    2019-03-22 16:12:39,777 [main] DEBUG [Message.delete] - ==>  Preparing: DELETE FROM message WHERE id = ? 
    2019-03-22 16:12:39,822 [main] DEBUG [Message.delete] - ==> Parameters: 1(String)
    2019-03-22 16:12:39,836 [main] DEBUG [Message.delete] - <==    Updates: 1
    

    可以看到成功的删除了。思考!!!! 我要删除多条数据怎么办?mybatis又不支持多参数传入,咳咳,那我穿入一个集合可以不呢?当然是可以的,如下:

    <!--批量删除   separator属性可以指定拼接的格式,如ids = 1,2,3 -->
    <delete id="deleteLisMsg" parameterType="java.util.List">
        DELETE FROM message WHERE id in
       (
        <foreach collection="list" item="item" separator=",">
            #{item}
        </foreach>
        )
    </delete>
    

    编写代码:

    public void testDeletebatcheMsg(List<String> ids) {
        DBAccess dbAccess = new DBAccess();
        SqlSession sqlSession = null;
        try {
            sqlSession = dbAccess.getSqlSession();
            //执行sql语句
            sqlSession.delete("deleteLisMsg", ids);
            //注意提交
            sqlSession.commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != sqlSession) {
                sqlSession.close();
            }
        }
    }
    

    测试用例:

    @Test
    public void testDeletebatcheMsg(){
        ApiTest apiTest = new ApiTest();
        //通过id 删除点信息
        List<String> ids = new ArrayList<>();
        ids.add("2");
        ids.add("3");
        ids.add("4");
        ids.add("5");
        apiTest.testDeletebatcheMsg(ids);
    }
    

    输出结果:

    2019-03-22 16:19:59,893 [main] DEBUG [Message.deleteLisMsg] - ==>  Preparing: DELETE FROM message 
     WHERE  id in( ? , ? , ? , ? ) 
    2019-03-22 16:19:59,944 [main] DEBUG [Message.deleteLisMsg] - ==> Parameters: 2(String), 3(String), 4(String), 
    5(String)
    2019-03-22 16:19:59,965 [main] DEBUG [Message.deleteLisMsg] - <==    Updates: 4
    

    可以看到成功的删除四条信息。等等!!! 在你文章里能看到打印的sql语句和参数,为嘛我在控制台啥也看不见呢?what amazing ????? 接触过SSH框架的都知道可以格式化sql语句输出,mybaits木有这玩意。怎么办?客观别急,放下手中的菜刀。我们可以通过打印的方式将其输出嘛。

    准备打印夹包并放入工程添加上依赖(add as library),没有的客观也别急,文末源码里会给出:

    commons-logging-1.2.jar
    log4j-1.2.17.jar
    log4j-core-2.11.1.jar
    log4j-api-2.11.1.jar
    

    编写log4j.properties配置文件,我这里直接放入了src下,规范起见还是建议放入到指定的配置文件目录下比较好,方便以后管理:

    log4j.rootLogger=DEBUG,Console
    log4j.appender.Console=org.apache.log4j.ConsoleAppender
    log4j.appender.Console.layout=org.apache.log4j.PatternLayout
    log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
    log4j.logger.org.apache=INFO
    

    好了就上面两个步骤,再次操作就能看到sql语句啦!!

    细心的同学会发现上面的代码是不是有问题啊,整个工程中如果有同名的方法,那不是在调用方法时,怎么区分该调那个呢?像这样写sqlSession.delete("deleteLisMsg", ids);肯定是不好的,在项目中应该 命名空间+方法名 才是正确的写法,指定到具体的那个配置文件上的那个方法。

    我们的MessageBean.xml命名空间用的 Message命名

      <!-- namespace 指定命名空间,同一命名空间下不支持相同的id名称 -->
     <mapper namespace="Message">
    

    正确的写法应该是 sqlSession.delete("Message.deleteLisMsg", ids);,好了文章就介绍到这里!!!!

    Mybatis官方中文译:https://www.w3cschool.cn/mybatis/7zy61ilv.html

    学习源码:https://gitee.com/zhengzaihong_love/MyBatisStudy

    相关文章

      网友评论

          本文标题:Mybatis入门一篇就够了

          本文链接:https://www.haomeiwen.com/subject/uurcvqtx.html