• mybatis实现增删改查


    MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除 了几乎所有的 JDBC 代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML 或注解用于配置和原始映射,将接口和 Java 的

    POJOs(Plan Old Java Objects,普通的 Java 对象)映射成数据库中的记录。
        MyBatis的前身是IBatis,也是一个使用很广的持久化框架。和hibernate对比,MyBatis更基础,要求使用者自己控制的东西更多。mybatis完成了基本的一些ORM概念,但是没有Hibernate那么完善。要使用mybatis,程序

    员的关注点更集中于SQL和数据库结构设计。mybatis没有hibernate使用起来那么面向对象,所以,在使用mybatis的时候,hibernate的一些思想和设计需要改变。
    MyBatis的好处:更底层,对性能控制更有优势。

    既然Mybatis也是一种ORM框架,所以,肯定也有两类配置文件。第一类,用来配置MyBatis环境,比如数据库连接等。第二类,用来配置对象到数据库表的映射。在MyBatis中,不光要配置对象到数据库表的映射,包括对应的

    SQL,也需要自己来完成(相当于自己来完成hibernate生成对象CRUDsql的过程要自己来完成)。在学习mybatis的过程当中,要对比着hibernate来思考,可以更容易的理解。而且,mybatis在ibatis的基础上面,更多的吸收

    了标准ORM的一些思想,所以,在API的设计上面和Hibernate还是有相似的地方,可以辅助学习。
        首先任意创建一个对象User:

    package cd.itcast.mybatis.domain;
        public class User {
            private Long id;
            private String name;
            private Date hireDate;
        //getter & setter
        }

    下面就使用Mybatis完成对这个对象的CRUD的测试。
        首先创建一个Mybatis的配置文件,我们在classpath下面创建一个xml文件,任意起名为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>
            <environments default="default">
                <environment id="default">
                    <transactionManager type="JDBC" />
                    <dataSource type="POOLED">
                        <property name="driver" value="com.mysql.jdbc.Driver"/>
                        <property name="url" value="jdbc:mysql:///mybatis"/>
                        <property name="username" value="root"/>
                        <property name="password" value="admin"/>
                    </dataSource>
                </environment>
            </environments>
        </configuration>

    这就是mybatis的一个典型的配置文件。在这个配置文件中,我们可以清楚得看到一些关键信息。第一,有一个environments这个元素,在这个元素里面配置的是一个一个的environment元素,每一个environment元素有一个id

    做为名字,而environments元素上面有一个default属性,引用environment元素的名称,很容易想象出他们之间的关系。在environments里面可以定义多个enviroment元素,使用default属性指定一个默认的environment。而

    在environment里面,定义了一组数据库相关的东西,包括transactionManager,这个元素代表着怎么去管理事务,后面还会详细讲到。而下面的dataSource就很明显了,代表连接数据库的相关信息。在这里,dataSource有一

    个属性type,这里我们写的是POOLED,很明显,使用连接池来做mybatis的连接提供。在        dataSource里面,配置了四个属性,做为数据库连接信息配置。
        接下来,就是为我们的User对象完成映射了。前面说了,在mybatis中,需要自己去控制sql,所以,我们的配置文件会像下面这样。在User的同级包下,添加一个XML文件,起名为UserMapper.xml,代表这个文件是User对

    象的映射文件:

    <?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="cd.itcast.mybatis.domain.UserMapper">
            <insert id="save" keyProperty="id" parameterType="cd.itcast.mybatis.domain.User"useGeneratedKeys="true">
                INSERT INTO user(name,hiredate) values (#{name},#{hireDate})
            </insert>
        </mapper>

    Mapper:代表这是一个对象的映射关系
        namespace:为当前映射关系创建的命名空间,要引用这个映射关系里面定义的东西,需要带上这个命名空间。还有其他非常重要的作用,之后会看到。
        insert:代表定义了一个插入操作(即SQL的insert操作)
        id:为这个插入操作起一个名字,以后要保存user这个对象,其实就是要调用这个插入操作。
        keyProperty:代表主键对应对象的属性名称。有点像hibernate里面那个id元素。
        parameterType:mybatis里面非常重要的一个元素,代表这个insert操作对应的方法需要传入一个什么类型的对象。这里,我们就是要把User这个对象保存到数据库中,所以,我们这个插入方法的参数就是一个User类型

    的对象实例。
        useGeneratedKeys:代表告诉mybatis,使用autoGeneratedKey来获取数据库帮我们自动生成的ID。(这个方法在jdbc中讲过)
        INSERT INTO user(name,hiredate) values (#{name},#{hireDate}):非常重要的东西。这就是一条完整的把USER对象插入到user表的SQL语句。但是在这个SQL语句里面,最重要的就是#{name},#{hireDate}这两个占位参

    数。这两个参数的意思就是:使用传入对象(parameterType)中的name,hireDate两个属性的值来填充这两个参数内容。
    完成映射文件之后,在mybatis-config.xml中加入映射文件:

    <mappers>
            <mapper resource="cd/itcast/mybatis/domain/UserMapper.xml"/>
        </mappers>

    插入操作的测试。1,首先创建一个USER表:

    CREATE TABLE `user` (
            `id` bigint(11) NOT NULL AUTO_INCREMENT,
            `name` varchar(50) DEFAULT NULL,
            `hiredate` date DEFAULT NULL,
            PRIMARY KEY (`id`)
        )

    然后创建一个UserTest类:

    @Test
        public void testSave() throws Exception{
            SqlSessionFactory factory= new SqlSessionFactoryBuilder().build(Resources .getResourceAsStream("mybatis-config.xml"));
            SqlSession session = factory.openSession();
            try {
                User u = new User();
                u.setName("itcasT");
                u.setHireDate(new Date());
                session.insert("cd.itcast.mybatis.domain.UserMapper.save", u);
                session.commit();
            } finally {
                session.close();
            }
        }

    1,Resources .getResourceAsStream("mybatis-config.xml"):使用Reources类的静态方法getResourceAsStream,从classpath:mybatis-config.xml位置读入配置文件,并装成inputStream。
        2,SqlSessionFactory factory= new SqlSessionFactoryBuilder().build(inputStream):使用读入的流,创建SqlSessionFactory。可以从名字上类比hibernate。
        3,SqlSession session = factory.openSession();使用factory开启一个SqlSession。SqlSession即是在mybatis中操作实体对象的主要的类了。
        4,User u = new User();创建一个需要保存的实体类。
        5,session.insert("cd.itcast.mybatis.domain.UserMapper.save", u):非常重要的方法,使用session的insert方法,对比上面的映射文件,即告诉mybatis现在调用的是一个标记到insert元素中的SQL语句,接着传入

    cd.itcast.mybatis.domain.UserMapper.save,很明显这个就是namespace+id拼成的,意思就是我要调用的是定义在cd.itcast.mybatis.domain.UserMapper这个映射关系中的名字为save的insert语句。这个语句需要传入一个

    cd.itcast.mybatis.domain.User对象实例做为参数,所以把创建的User实体做为参数传入。
        6,session.commit():很明显,即提交事务。
        7,session.close():和hibernate一样,使用完后,都必须要关闭session。
        从整个代码上面可以很明显的猜测到mybatis的创建过程。执行测试,保存成功。但是看不到mybatis执行的sql,怎么办?日志:
        在classpath中建立一个名叫log4j.properties的文件,内容如下:

    # Global logging configuration
        log4j.rootLogger=ERROR, stdout
        # MyBatis logging configuration...
        log4j.logger.cd.itcast.mybatis=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

    很明显,log4j.logger.cd.itcast.mybatis意思就是要监控cd.itcast.mybatis包下面的所有mapper的动作。再次运行:

    DEBUG [main] - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@79a2e7]
        DEBUG [main] - ==>  Preparing: INSERT INTO user(name,hiredate) values (?,?)
        DEBUG [main] - ==> Parameters: itcasT(String), 2012-09-12 15:10:16.812(Timestamp)

    可以很清楚的看到执行的sql和执行sql使用的参数。

     修改操作,在UserMapper.xml中加入:
        <update id="update" parameterType="cd.itcast.mybatis.domain.User">
            UPDATE user SET name = #{name},hiredate = #{hireDate} WHERE id = #{id}
        </update>
        1, update:代表当前定义了一个update操作(sql的update语句);
        a) id:为当前操作定义了一个名字,用于调用
        b) parameterType:update调用需要一个cd.itcast.mybatis.domain.User的类型实例做为参数。
        2, UPDATE user SET name = #{name},hiredate = #{hireDate} WHERE id = #{id}:即完整的UPDATE语句,其中的#{name},#{hireDate},#{id}和insert语句中的完全一致。

        修改测试:
        @Test
        public void testUpdate() {
            SqlSessionFactory factory= new SqlSessionFactoryBuilder().build(Resources .getResourceAsStream("mybatis-config.xml"));
            SqlSession session = factory.openSession();
            try {
                User u = new User();
                u.setId(1l);
                u.setName("update");
                u.setHireDate(new Date());
                session.update("cd.itcast.mybatis.domain.UserMapper.update", u);
                session.commit();
            } finally {
            session.close();
            }
        }
        对照保存测试,很好理解,关键的一句:
        session.update("cd.itcast.mybatis.domain.UserMapper.update", u):即调用在cd.itcast.mybatis.domain.UserMapper中定义的名字为update的Update语句,传入一个cd.itcast.mybatis.domain.User的对象实例。
        运行测试,console打印:
        DEBUG [main] - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@1b60280]
        DEBUG [main] - ==>  Preparing: UPDATE user SET name = ?,hiredate = ? WHERE id = ?
        DEBUG [main] - ==> Parameters: update(String), 2012-09-07 00:00:00.0(Timestamp), 2(Long)


    Get方法:
        在UserMapper.xml中添加如下配置:
        <select id="get" parameterType="long" resultType="cd.itcast.mybatis.domain.User">
            SELECT * FROM user WHERE id = #{id}
        </select>
        1, select:代表这是一个SELECT语句
        a) parameterType:代表要执行这个select语句需要传入一个类型为long的参数,即User对象的id
        b) resultType:非常重要的东西,即完成ORM的映射关系所在。这里指定的cd.itcast.mybatis.domain.User代表,把结果集转换成一个User对象实例。注意,在这里有一个要求就是,属性名称和列的名称必须一致,才能

    完成转型。否则就需要自定义属性到字段的映射规则。
        2, SELECT * FROM user WHERE id = #{id}:即查询语句。非常重要的一点,这个#{id}是mybatis在使用查询单个对象的时候默认使用的参数的名称。即传入的类型为long的值,mybatis就用#{id}来代替。

        Get测试:
        @Test
        public void testGet() {
            SqlSessionFactory factory= new SqlSessionFactoryBuilder().build(Resources .getResourceAsStream("mybatis-config.xml"));
            SqlSession session = factory.openSession();
            try {
                User u = session.selectOne("cd.itcast.mybatis.domain.UserMapper.get",1l);
                System.out.println(u);
            } finally {
            session.close();
            }
        }
        其中很重要的一点:
        User u = session.selectOne("cd.itcast.mybatis.domain.UserMapper.get",1l);
        调用的是cd.itcast.mybatis.domain.UserMapper中定义的get对应的SELECT语句。注意这里使用的是session.selectOne,代表,选择的是一个。那么mybatis就会把查询到的结果集中的第一行数据按照列名和属性名一一

    对应的关系,把结果包装成一个User类型的实例。
        从这里也能得出结论:在mapper文件中定义的sql语句的类型和在session中使用的调用方法是对应的。
        运行测试:
        DEBUG [main] - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@1b60280]
        DEBUG [main] - ==>  Preparing: SELECT * FROM user WHERE id = ?
        DEBUG [main] - ==> Parameters: 2(Long)
        TRACE [main] - <==    Columns: id, name, hiredate
        TRACE [main] - <==        Row: 2, itcasT, 2012-09-07
        还可以看到返回的结果集内容。



    多条查询:
        在UserMapper.xml中加入:
        <select id="list" resultType="cd.itcast.mybatis.domain.User">
            SELECT * FROM user
        </select>
        1,非常重要的一点,这次返回的结果应该是一个List<User>,但是配置的resultType仍然是cd.itcast.mybatis.domain.User,mybatis强大的一点,对于select,其实我们配置的都是把每一条结果集转成的对象类型。
        2,SELECT * FROM user:即查询语句。因为不需要参数了,所以也没有定义paramterType。

        查询测试:
        @Test
        public void testList() {
            SqlSessionFactory factory= new SqlSessionFactoryBuilder().build(Resources .getResourceAsStream("mybatis-config.xml"));
            SqlSession session = factory.openSession();
            try {
                List<User> us = session.selectList("cd.itcast.mybatis.domain.UserMapper.list");
                System.out.println(us);
                } finally {
                session.close();
            }
        }
        1, 使用的是session.selectList,代表这次调用的select语句需要把结果集包装成一个对象列表。
        运行测试,console:
        DEBUG [main] - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@158f9d3]
        DEBUG [main] - ==>  Preparing: SELECT * FROM user
        DEBUG [main] - ==> Parameters:
        TRACE [main] - <==    Columns: id, name, hiredate
        TRACE [main] - <==        Row: 2, update, 2012-09-07
        TRACE [main] - <==        Row: 3, itcasT, 2012-09-12
        得到正确的结果。


     删除:
        在UserMapper.xml中添加:
        <delete id="delete" parameterType="long">
            DELETE FROM user WHERE id = #{id}
        </delete>
        使用delete标识这是一个删除语句。参数parameterType=long表明删除数据的参数。同select一样,如果传入的参数就是一个id,那么在sql语句中使用#{id}来引用这个参数。
        测试用例:
        @Test
        public void testDelete() {
            SqlSessionFactory factory= new SqlSessionFactoryBuilder().build(Resources .getResourceAsStream("mybatis-config.xml"));
            SqlSession session = factory.openSession();
            try {
                session.delete("cd.itcast.mybatis.domain.UserMapper.delete", 1l);
                session.commit();
            } finally {
                    session.close();
            }
        }
        使用session.delete方法指定调用的删除SQL和传入参数。运行结果:
        DEBUG [main] - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@158f9d3]
        DEBUG [main] - ==>  Preparing: DELETE FROM user WHERE id = ?
        DEBUG [main] - ==> Parameters: 1(Long)

        到这里,mybatis的CRUD基本演示完毕。从这些方法里面大概能够感受到mybatis的一些基本的使用方式。

  • 相关阅读:
    SQL Server 锁升级(Lock Escalations)
    Linux 输入与输出重定向详解
    MySQL DDL的成本高低
    spring 学习-bean创建-refresh方法
    spring 学习-bean创建-scan扫描bean
    spring 学习-bean创建-重要类介绍
    zkclient大量节点事件导致CPU飙升
    spring 学习-bean创建-重要类介绍
    ElasticSearch 按值排序
    Redis set 详解
  • 原文地址:https://www.cnblogs.com/shenming/p/3812421.html
Copyright © 2020-2023  润新知