美文网首页
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