使用mybatis完成CRUD

1. 什么是CRUD
    C: Create增
    R: Retrieve查(检索)
    U: Update改
    D: Delete删

2. insert
    <insert id="insertCar">
        insert into t_car(id,car_num,brand,guide_price,produce_time,car_type)
        values(null,'1003','丰田霸道',30.0,'2000-10-11','燃油车');
    </insert>
    这样写的问题是?
        值 显然是写死到配置文件中的。
        这个在实际开发中是不存在的。
        一定是前端的form表单提交过来数据。然后将值传给sql语句。

    例如:JDBC的代码是怎么写的?
        String sql = "insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) values(null,?,?,?,?,?)";
        ps.setString(1, xxx);
        ps.setString(2, yyy);
        ....

    在JDBC当中占位符采用的是?,在mybatis当中是什么呢?
        和?等效的写法是:#{}
        在mybatis当中不能使用?占位符,必须使用 #{} 来代替JDBC当中的 ?
        #{} 和 JDBC当中的 ? 是等效的。

    java程序中使用Map可以给SQL语句的占位符传值:
        Map<String, Object> map = new HashMap<>();
        map.put("k1", "1111");
        map.put("k2", "比亚迪汉");
        map.put("k3", 10.0);
        map.put("k4", "2020-11-11");
        map.put("k5", "电车");

        insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) values(null,#{k1},#{k2},#{k3},#{k4},#{k5});


    <!--insert语句id是这条SQL语句的唯一标识。这个id就代表了这条SQL语句-->
    <insert id="insertCar">

            insert into t_car(id,car_num,brand,guide_price,produce_time,car_type)
            values(null ,#{k1},#{k2},#{k3},#{k4},#{k5})
    </insert>
package com.powernode.mybatis.test;

import com.powernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

public class CarMapperTest {

    @Test
    public void InsertCarTest(){

        // 准备数据
        Map<String, Object> map = new HashMap<>();
        map.put("k1", "103");
        map.put("k2", "奔驰E300L");
        map.put("k3", 50.3);
        map.put("k4", "2020-10-01");
        map.put("k5", "燃油车");

        SqlSession sqlSession = SqlSessionUtil.openSession();
        // insert(string s,Object o)
        int count = sqlSession.insert("insertCar",map);
        System.out.println(count);
        sqlSession.commit();
        sqlSession.close();


    }
}


        注意:#{这里写什么?写map集合的key,如果key不存在,获取的是null}

        一般map集合的key起名的时候要见名知意。
            map.put("carNum", "1111");
            map.put("brand", "比亚迪汉2");
            map.put("guidePrice", 10.0);
            map.put("produceTime", "2020-11-11");
            map.put("carType", "电车");

            insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) values(null,#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType});

    java程序中使用POJO类给SQL语句的占位符传值:
        Car car = new Car(null, "3333", "比亚迪秦", 30.0, "2020-11-11", "新能源");

        注意:占位符#{},大括号里面写:pojo类的属性名
        insert into t_car(id,car_num,brand,guide_price,produce_time,car_type)
        values(null,#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType})

        把SQL语句写成这个德行:
        insert into t_car(id,car_num,brand,guide_price,produce_time,car_type)
                values(null,#{xyz},#{brand},#{guidePrice},#{produceTime},#{carType})
        出现了什么问题呢?
            There is no getter for property named 'xyz' in 'class com.powernode.mybatis.pojo.Car'
            mybatis去找:Car类中的getXyz()方法去了。没找到。报错了。

        怎么解决的?
            可以在Car类中提供一个getXyz()方法。这样问题就解决了。

        通过这个测试,得出一个结论:
            严格意义上来说:如果使用POJO对象传递值的话,#{}这个大括号中到底写什么?
                写的是get方法的方法名去掉get,然后将剩下的单词首字母小写,然后放进去。

                例如:getUsername() --> #{username}
                例如:getEmail() --> #{email}
                ....
        也就是说mybatis在底层给?传值的时候,先要获取值,怎么获取的?
            调用了pojo对象的get方法。例如:car.getCarNum(),car.getCarType(),car.getBrand()
3. delete
    * 需求:根据id删除数据
        将id=59的数据删除。

    实现:
        int count = sqlSession.delete("deleteById", 59);


        <delete id="deleteById">
            delete from t_car where id = #{fdsfd}
        </delete>
        注意:如果占位符只有一个,那么#{}的大括号里可以随意。但是最好见名知意。

4. update
    * 需求:根据id修改某条记录。

    实现:
        <update id="updateById">
            update t_car set
                 car_num=#{carNum},
                 brand=#{brand},
                 guide_price=#{guidePrice},
                 produce_time=#{produceTime},
                 car_type=#{carType}
            where
                id = #{id}
        </update>

        Car car = new Car(4L, "9999", "凯美瑞", 30.3, "1999-11-10", "燃油车");
        int count = sqlSession.update("updateById", car);

5. select(查一个,根据主键查询的话,返回的结果一定是一个。)
    * 需求:根据id查询。

    实现:
        <select id="selectById" resultType="com.powernode.mybatis.pojo.Car">
            select * from t_car where id = #{id}
        </select>

        Object car = sqlSession.selectOne("selectById", 1);

    需要特别注意的是:
        select标签中resultType属性,这个属性用来告诉mybatis,查询结果集封装成什么类型的java对象。你需要告诉mybatis。
        resultType通常写的是:全限定类名。

    Car{id=1, carNum='null', brand='宝马520Li', guidePrice=null, produceTime='null', carType='null'}
    输出结果有点不对劲:
        id和brand属性有值。
        其他属性为null。

    carNum以及其他的这几个属性没有赋上值的原因是什么?
        select * from t_car where id = 1
        执行结果:
        +----+---------+-----------+-------------+--------------+----------+
        | id | car_num | brand     | guide_price | produce_time | car_type |
        +----+---------+-----------+-------------+--------------+----------+
        |  1 | 1001    | 宝马520Li |       10.00 | 2020-10-11   | 燃油车   |
        +----+---------+-----------+-------------+--------------+----------+
        car_num、guide_price、produce_time、car_type这是查询结果的列名。


        这些列名和Car类中的属性名对不上。
        Car类的属性名:
        carNum、guidePrice、produceTime、carType

        那这个问题怎么解决呢?
            select语句查询的时候,查询结果集的列名是可以使用as关键字起别名的。

        <select id="selectById" resultType="com.powernode.mybatis.pojo.Car">
            select
                id,car_num as carNum,brand,guide_price as guidePrice,
                produce_time as produceTime,
                car_type as carType

            from
                t_car
            where
                id = #{id}
        </select>
        起别名之后:
        +----+--------+-----------+------------+-------------+---------+
        | id | carNum | brand     | guidePrice | produceTime | carType |
        +----+--------+-----------+------------+-------------+---------+
        |  1 | 1001   | 宝马520Li |      10.00 | 2020-10-11  | 燃油车  |
        +----+--------+-----------+------------+-------------+---------+

6. select(查所有的)

    <select id="selectAll" resultType="com.powernode.mybatis.pojo.Car">
        select
            id,car_num as carNum,brand,guide_price as guidePrice,
            produce_time as produceTime,
            car_type as carType
        from
            t_car
    </select>

    List<Object> cars = sqlSession.selectList("selectAll");

    注意:resultType还是指定要封装的结果集的类型。不是指定List类型,是指定List集合中元素的类型。
    selectList方法:mybatis通过这个方法就可以得知你需要一个List集合。它会自动给你返回一个List集合。

7. 在sql mapper.xml文件当中有一个namespace,这个属性是用来指定命名空间的。用来防止id重复
怎么用?
    在xml文件中:
        <mapper namespace="aaaaaaaaa">
            <select id="selectAll" resultType="com.powernode.mybatis.pojo.Car">
                select
                    id,car_num as carNum,brand,guide_price as guidePrice,
                    produce_time as produceTime,
                    car_type
                from
                    t_car
            </select>
        </mapper>
    在java程序中的写法:
        List<Object> cars = sqlSession.selectList("aaaaaaaaa.selectAll");

    实际上,本质上,mybatis中的sqlId的完整写法:
        namespace.id

 

**namespace:**代表命名空间,它的命名规则是‘ dao接口的全限定名称’。

        原因:为了通过mybatis自动生成dao接口的实现类

**parameterType:**代表查询语句中参数的数据类型

**resultType:**代表查询的结果用指定数据类型接收

多个数据源

<!--default表示默认使用的环境。-->
    <!--默认环境什么意思?当你使用mybatis创建SqlSessionFactory对象的时候,没有指定环境的话,默认使用哪个环境。-->
    <environments default="powernodeDB">

        <!--其中的一个环境。连接的数据库是powernode-->
        <!--一般一个数据库会对应一个SqlSessionFactory对象。-->
        <!--一个环境environment会对应一个SqlSessionFactory对象-->
        <environment id="powernodeDB">
            <!--
                transactionManager标签:
                    1.作用:配置事务管理器。指定mybatis具体使用什么方式去管理事务。
                    2.type属性有两个值:
                        第一个:JDBC: 使用原生的JDBC代码来管理事务。
                            conn.setAutoCommit(false);
                            ....
                            conn.commit();
                        第二个:MANAGED:mybatis不再负责事务的管理,将事务管理交给其它的JEE(JavaEE)容器来管理。例如:spring
                    3. 大小写无所谓。不缺分大小写。但是不能写其他值。只能是二选一:
                        jdbc、managed
                    4. 在mybatis中提供了一个事务管理器接口:Transaction
                        该接口下有两个实现类:
                            JdbcTransaction
                            ManagedTransaction
                        如果type="JDBC",那么底层会实例化JdbcTransaction对象。
                        如果type="MANAGED",那么底层会实例化ManagedTransaction
            -->
            <transactionManager type="JDBC"/>
            <!--
                dataSource配置:
                    1.dataSource被称为数据源。
                    2.dataSource作用是什么?为程序提供Connection对象。(但凡是给程序提供Connection对象的,都叫做数据源。)
                    3.数据源实际上是一套规范。JDK中有这套规范:javax.sql.DataSource(这个数据源的规范,这套接口实际上是JDK规定的。)
                    4.我们自己也可以编写数据源组件,只要实现javax.sql.DataSource接口就行了。实现接口当中所有的方法。这样就有了自己的数据源。
                    比如你可以写一个属于自己的数据库连接池(数据库连接池是提供连接对象的,所以数据库连接池就是一个数据源)。
                    5.常见的数据源组件有哪些呢【常见的数据库连接池有哪些呢】?
                        阿里巴巴的德鲁伊连接池:druid
                        c3p0
                        dbcp
                        ....
                    6. type属性用来指定数据源的类型,就是指定具体使用什么方式来获取Connection对象:
                        type属性有三个值:必须是三选一。
                        type="[UNPOOLED|POOLED|JNDI]"
                        UNPOOLED:不使用数据库连接池技术。每一次请求过来之后,都是创建新的Connection对象。
                        POOLED:使用mybatis自己实现的数据库连接池。
                        JNDI:集成其它第三方的数据库连接池。

                        JNDI是一套规范。谁实现了这套规范呢?大部分的web容器都实现了JNDI规范:
                            例如:Tomcat、Jetty、WebLogic、WebSphere,这些服务器(容器)都实现了JNDI规范。
                        JNDI是:java命名目录接口。Tomcat服务器实现了这个规范。
            -->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
                <!--提醒:正常使用连接池的话,池中有很多参数是需要设置的。设置好参数,可以让连接池发挥的更好。事半功倍的效果。-->
                <!--具体连接池当中的参数如何配置呢?需要反复的根据当前业务情况进行测试。-->
                <!--poolMaximumActiveConnections:连接池当中最多的正在使用的连接对象的数量上限。最多有多少个连接可以活动。默认值10-->
                <property name="poolMaximumActiveConnections" value="10"/>
                <!--每隔2秒打印日志,并且尝试获取连接对象-->
                <property name="poolTimeToWait" value="2000"/>
                <!--强行让某个连接空闲,超时时间的设置-->
                <property name="poolMaximumCheckoutTime" value="10000"/>
                <!--最多的空闲数量-->
                <property name="poolMaximumIdleConnections" value="5"/>
            </dataSource>

        </environment>
@Test
    public void testEnvironment() throws Exception {
        // 获取SqlSessionFactory对象(采用默认的方式获取)
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();

        // 这种方式就是获取的默认环境
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"));
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 执行SQL语句
        sqlSession.insert("car.insertCar");
        sqlSession.commit();
        sqlSession.close();

        // 这种方式就是通过环境id来使用指定的环境
        SqlSessionFactory sqlSessionFactory1 = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"), "powernodeDB");
        SqlSession sqlSession1 = sqlSessionFactory1.openSession();
        // 执行SQL语句
        sqlSession1.insert("car.insertCar");
        sqlSession1.commit();
        sqlSession1.close();
    }

properties

mybatis提供了更加灵活的配置,连接数据库的信息可以单独写到一个属性资源文件中,假设在类的根路径下创建jdbc.properties文件,配置如下:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=false
jdbc.username=root
jdbc.password=123456
 <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!--JDBC连接Mysql5需用com.mysql.jdbc.Driver -->
                <!--JDBC连接Mysql6需用com.mysql.cj.jdbc.Driver,同时需要指定时区serverTimezone-->
                <property name="driver" value="${jdbc.driver}"/>
                <!--&需要使用 &amp; 代替-->
                <!--jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&amp;useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=false-->
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值