当前位置: 首页 > news >正文

MyBatis

MyBatis

  • 1.ORM思想
  • 2.MyBatis中的事务
  • 3.在MyBatis中引入JUnit单元测试
  • 4.MyBatis集成日志框架logback
  • 5.使用mybatis完成CRUD业务
  • 6.SQLMapper映射文件中namespace的作用
  • 7.MyBatis核心配置文件
    • 7.1 数据库连接池
  • 7.2

1.ORM思想

ORM:对象 关系 映射
O(Object):JVM中的java对象,R(Relational):关系型数据库,M(Mapping):映射

2.MyBatis中的事务

(1)
在mybatis-config.xml文件中,可以通过以下配置进行mybatis的事务管理
<transactionManager type="JDBC"/> JDBC|MANAGED不区分大小写)
JDBC:mybatis框架自己管理事务,自己采用原生的JDBC代码去管理事务
          conn.setAutoCommit(false);开启事务
          ...
          conn.commit();提交事务
MANAGED:mybatis不在负责事务的管理,事务管理交给其他容器来负责,如Spring
                  如果没有其他容器管理的话,就默认没有事务

3.在MyBatis中引入JUnit单元测试

        <!--junit依赖-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>

4.MyBatis集成日志框架logback

(1)引入logback依赖

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.4.3</version>
        </dependency>

(2)引入logback所必必须的xml配置文件

命名必须为:logback.xml或者logback-test.xml,这个配置文件必须放在类的根路径下
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
    <!--控制台输出-->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度,%msg:日志消息,%n换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        </encoder>
    </appender>
    
    <!--按照每天生成日志文件-->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <FileNamePattern>${LOG_HOME}/TestWeb.log.%d{yyyy-MM-dd}.log</FileNamePattern>
            <!--日志文件保留天数-->
            <MaxHistory>30</MaxHistory>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度,%msg:日志消息,%n换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        </encoder>
        <!--日志文件最大的大小-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>100MB</MaxFileSize>
        </triggeringPolicy>
    </appender>

    <!--mybatis log configure-->
    <logger name="com.apache.ibatis" level="TRACE"/>
    <logger name="java.sql.Connection" level="DEBUG"/>
    <logger name="java.sql.Statement" level="DEBUG"/>
    <logger name="java.sql.PreparedStatement" level="DEBUG"/>

    <!--日志输出级别,logback日志级别包括五个:TRACE<DEBUG<INFO<WARN<ERROR-->
    <root level="DEBUG">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="FILE"/>
    </root>
</configuration>

5.使用mybatis完成CRUD业务

(1)将SqlSession对象的得到过程封装成一个util

public class SqlSessionUtil {

    //工具类的构造方法一般是私有化的
    private SqlSessionUtil(){}

    private static SqlSessionFactory sqlSessionFactory;
    //类加载时执行 工具类第一次加载的时候,解析mybatis-config.xml文件,创建一个SqlSessionFactory对象
    static {
        try {
            sqlSessionFactory=new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    //工具类中所有的方法都是静态的,直接采用类名就可以调用,不需要new对象
    public static SqlSession openSession(){
        //返回会话对象
        return sqlSessionFactory.openSession();
    }
}

(2)写一个封装汽车信息的类

public class Car {
    //数据库表中的字段应该和类中的属性一一对应
    private Long id;//使用包装类Long防止null的问题
    private String carNum;
    private String brand;
    private Double guidePrice;
    private String produceTime;
    private String carType;

    public Car(){}

    public Car(Long id, String carNum, String brand, Double guidePrice, String produceTime, String carType) {
        this.id = id;
        this.carNum = carNum;
        this.brand = brand;
        this.guidePrice = guidePrice;
        this.produceTime = produceTime;
        this.carType = carType;
    }

    public Long getId() {
        return id;
    }

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

    public String getCarNum() {
        return carNum;
    }

    public void setCarNum(String carNum) {
        this.carNum = carNum;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public Double getGuidePrice() {
        return guidePrice;
    }

    public void setGuidePrice(Double guidePrice) {
        this.guidePrice = guidePrice;
    }

    public String getProduceTime() {
        return produceTime;
    }

    public void setProduceTime(String produceTime) {
        this.produceTime = produceTime;
    }

    public String getCarType() {
        return carType;
    }

    public void setCarType(String carType) {
        this.carType = carType;
    }

    @Override
    public String toString() {
        return "Car{" +
                "id=" + id +
                ", carNum='" + carNum + '\'' +
                ", brand='" + brand + '\'' +
                ", guidePrice=" + guidePrice +
                ", produceTime='" + produceTime + '\'' +
                ", carType='" + carType + '\'' +
                '}';
    }
}

(3)Mapper文件中写SQL语句

<?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="org.mybatis.example.BlogMapper">
    <!--提供一个插入语句,id是这条SQL语句的唯一标识-->
    <insert id="insertCar">
        insert into t_car(id,car_num,brand,guide_price,produce_time,car_type)
        values (null,#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType})
    </insert>
    <delete id="deleteById">
        delete from t_car where id=#{num}
    </delete>
    <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>
    <select id="selectById" resultType="com.mybatis.bean.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>
    <select id="selectAll" resultType="com.mybatis.bean.Car">
        select id,car_num as carNum,brand,guide_price as guidePrice,
               produce_time as produceTime,car_type as carType
        from t_car
    </select>
</mapper>

(4)写测试程序

public class CapMapperTest {
    @Test
    public void testInsertCar(){
        SqlSession sqlSession= SqlSessionUtil.openSession();
        //封装数据
        Car car = new Car(null,"1002","兰博基尼",800.0,"2020-12-21","跑车");
        //执行语句

        //insert方法的参数
        //(1)sqlId,在CarMapper文件中复制
        //(2)对象,封装要传入的数据
        int count = sqlSession.insert("insertCar",car);
        System.out.println(count);
        sqlSession.commit();
        sqlSession.close();
    }

    @Test
    public void testDeleteById(){
        SqlSession sqlSession=SqlSessionUtil.openSession();
        //执行sql语句
        int count = sqlSession.delete("deleteById", 1);
        System.out.println(count);
        sqlSession.commit();
        sqlSession.close();
    }

    @Test
    public void testUpdateById(){
        Car car = new Car(2L,"1000","劳斯莱斯",789.0,"2021-03-23","跑车");
        SqlSession sqlSession = SqlSessionUtil.openSession();
        //执行sql语句
        int count = sqlSession.update("updateById", car);
        System.out.println(count);
        sqlSession.commit();
        sqlSession.close();
    }

    @Test
    public void testSelectById(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        Object car = sqlSession.selectOne("selectById", 1);
        System.out.println(car);
        sqlSession.close();
    }

    @Test
    public void testSelectAll(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        List<Object> cars = sqlSession.selectList("selectAll");
        cars.forEach(car -> System.out.println(car));
        sqlSession.close();
    }
}

6.SQLMapper映射文件中namespace的作用

(1)
namespace是用来指定命名空间,防止id冲突
<mapper namespace="car">
<mapper namespace="user">

(2)写id的时候,需要
//List<Object> cars = sqlSession.selectList("selectAll");
//正确的写法 namespace+id
List<Object> cars = sqlSession.selectList("user.selectAll");

7.MyBatis核心配置文件

7.1 数据库连接池

优点:
(1)提升效率
(2)防止创建对象过来,导致数据库宕机

7.2

<?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表示默认使用的环境,当使用mybatis创建SqlSessionFactory对象没有指定环境的话
    ,默认使用development-->
    <environments default="development">
        <!--其中一个环境,连接的数据库是test-->
        <!--一般一个数据库对应一个SqlSessionFactory对象-->
        <environment id="development">
            <!--transactionManager
                作用:配置事务管理器,指定mybatis具体使用什么方式去管理事务
                type属性有两个值:
                    JDBC:使用原生的JDBC代码管理事务
                    MANAGED:mybatis不再负责事务管理,交给其他容器管理
            -->
            <transactionManager type="JDBC"/>
            <!--dataSource
                1.dataSource被称为数据源
                2.作用:为程序提供Connection对象(凡是给程序提供Connection对象,都是数据源)
                3.数据源实际上是一套规范,JDK有这套规范:javax.sql.DataSource(这个接口是JDK规定的)
                4.我们可以实现这个接口,编写数据源组件(数据库连接池是连接对象的,所以数据库连接池是一个数据源)
                5.常见的数据源有哪些(常见的数据库连接池):druid,c3p0,dbcp
                6.type属性:用来指定数据源的类型,用来指定具体使用什么方式来获取Connection对象
                  type有三个属性值:
                      UNPOOLED:不使用数据库连接池技术,每一次请求过来都新建新的Connection对象
                      POOLED:使用mybatis自己实现的数据库连接池
                      JNDI:集成其他第三方的数据库连接池
            -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/test"/>
                <property name="username" value="root"/>
                <property name="password" value="cw20010212"/>
                <!--正常使用连接池的话,池中很多参数需要设置,设置好参数,可以让连接池发挥的更好-->
                <!--连接池当中最多正在使用的连接对象的数量上限,默认值是10-->
                <property name="poolMaximumActiveConnections" value="3"/>
                <!--每隔两秒打印日志,并尝试获取连接对象-->
                <property name="poolTimeToWait" value="2000"/>
                <!--强行让某个连接空闲,设置超时时间-->
                <property name="poolMaximumCheckoutTime" value="10000"/>
                <!--设置连接池中最多空闲数量-->
                <property name="poolMaximumIdleConnections" value="5"/>
            </dataSource>
        </environment>

        <!--令一个环境,连接的数据库是cm-->
        <environment id="abc">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/cm"/>
                <property name="username" value="root"/>
                <property name="password" value="cw20010212"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--指定XxxMapper.xml文件的路径-->
        <!--resource属性默认从类的根路径下查找文件-->
        <mapper resource="CarMapper.xml"/>
        <mapper resource="UserMapper.xml"/>
    </mappers>
</configuration>

相关文章:

  • 营销型网站建设的特点/友情链接实例
  • 家用宽带怎么做网站 访问/长沙关键词自然排名
  • 手机网站html/广东企业网站seo报价
  • 洛阳做网站公司在哪/申请百度收录网址
  • 网站建设备案查询/杭州网络推广有限公司
  • 页面设计器翻译成英文/苏州手机关键词优化
  • CAD机械零件平面绘制练习六
  • 相比Vue和React,Svelte可能更适合你
  • HTTP/HTTPS/TCP原理
  • 基于TCP的socket API,让你拥有另一套自己的服务器~
  • 关于IO的探究:BIO、NIO、AIO(未完待续)
  • API接口名称(item_search - 按关键字搜索淘宝商品)[item_search,item_get,item_search_shop等]
  • 拥抱云原生,Java与Python基于gRPC通信
  • 【node.js从入门到精通】使用express创建web服务器,路由,进行中间件的创建链接路由及其他中间件
  • 【C语言】-字符串函数和内存函数(下)
  • r语言使用rjags R2jags建立贝叶斯模型|附代码数据
  • wifi码小程序全面分析
  • 使用小程序实现图表(圆饼图、柱状图、折线图)