mybatis

什么是框架?

	软件的半成品,解决了软件开发过程中的配适性问题,从而简化了开发步骤,提高了开发的效率。

什么是ORM框架?

	ORM (Object RelationalMapping)对象关系映射,将程序中的一个对象与表中的一行数据一一对应
	ORM框架提供了持久化类与表的映射关系,在运行时参照映射文件的信息,把对象持久化到数据库中

使用JDBC完成ORM操作的缺点?

    存在大量的冗余代码。
    手工创建 Connection、Statement等。
    手工将结果集封装成实体对象。
    查询效率低,没有对数据访问进行过优化(Not Cache)

MyBatis框架

“高级JDBC”

ORM框架:映射框架
框架--是一个半成品,里面使用大量的设计模式,简化书写代码,提供大了的动态sql语句以及结果映射!

入门

pom.xml导入mybatis的核心依赖

<!--mysql驱动包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.25</version>
        </dependency>
<!--mybatis的核心jar包-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.7</version>
        </dependency>

配置 mybatis配置文件

创建 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">
<!--xx.dtd是xml文件约束,约束标签-->
<!--核心配置-->
<configuration>
    <!--JDBC环境配置-->
    <environments default="mysql">
        <!--可以配置多个环境-->
        <environment id="mysql">
            <!--mybatis事务管理器
                        连接数据库操作
            -->
            <transactionManager type="JDBC"/>
            <!--启用mybatis自带的连接池-->
            <dataSource type="POOLED">
                <!--配置连接池这个类中的属性参数
                    drvier/url/username/password都是
                    org.apache.ibatis.datasource.pooled.PooledDataSource信息
                -->
                <!--驱动类-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <!--连接数据库的地址-->
                <property name="url" value="jdbc:mysql://localhost:3306/myee2302_db_2"/>
                <!--用户名-->
                <property name="username" value="root"/>
                <!--登录密码-->
                <property name="password" value="123456"/>
            </dataSource>
        </environment>

    </environments>
<!--加载mapper映射器-->
    <mappers>
        <!--配置mapper文件的所在位置-->
        <package name="com.qf.mapper"/>
    </mappers>
</configuration>

准备好mybatis的持久层接口以及它的映射文件

public interface AccountDao {

    /**
     * 查询所有账户
     * @return 返回账户列表
     */
    List<Account> findAllAccounts() ;
}
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--映射器的配置
    namesapce:名称空间指定接口的完全限定名称
-->
<mapper namespace="com.qf.mapper.AccountDao">
        <!--大量的sql标签
            id必须和接口文件中的方法名必须一致

            当前接口中的方法有返回值,返回值如果是实体类型或者是List集合
            输出映射:resultType必须要指定为当前实体类型的完全限定名称
        -->
    <select id="findAllAccounts" resultType="com.qf.pojo.Account">
        select * from account
    </select>
</mapper>

单元测试进行执行

package com.qf.mybatistest;

import com.qf.mapper.AccountDao;
import com.qf.pojo.Account;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * @author 高圆圆
 * @date 2023/5/5 14:48
 * 单元测试类
 */
public class MybatisTest {

    @Test
    public void testFindAll() throws IOException {
        //1)读取resource下面的mybatis-config.xml文件
        //org.apache.ibatis.io.Resources --InputStream getResourceAsStream(配置文件名称)
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        //2)创建一个对象SqlSessionFactoryBuilder
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder() ;
        //3)创建SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);//加载流对象 获取到工厂对象
        //4)创建 SqlSession---就是执行对象--底层就是PreparedStatement
        SqlSession sqlSession = sqlSessionFactory.openSession();//自动提交
        //5)获取AccountDao接口对象---通过mybatis的动态代理获取接口对象
        AccountDao accountDao = sqlSession.getMapper(AccountDao.class);//接口类型字节码文件
        //6)调用方法
        List<Account> allAccounts = accountDao.findAllAccounts();
        if(allAccounts!=null || allAccounts.size()>0){
            for(Account account :allAccounts){
                System.out.println(account);
            }
        }
    }
}

log4j日志

pom.xml导入依赖

<!--log4j的日志包-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

resources配置文件

# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE            debug   info   warn error fatal
# 全局日志配置
log4j.rootCategory=debug, CONSOLE, LOGFILE

# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE


#跟踪具体的接口或者接口中的指定方法
log4j.logger.com.qf.mapper.UserDao=TRACE

# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
#控制台输出
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n


#本地磁盘上产生日志文件
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
# 缓存在指定路径
log4j.appender.LOGFILE.File=D:/EE_2302/day56/code/log4j.log 
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

查询

添加用户获取自增长id值

<insert id="addUser" parameterType="com.qf.pojo.User" >

    <!--在插入的时候,获取id自增长主键的值,配置一些函数

        selectKey
             属性
                keyColumn:表的主键字段名称
                keyProperty:实体类的属性名称
                resultType:返回值自增长主键的值类型:当前实体类的完全限定名称或者别名
                order:AFTER:在执行插入语句之后执行selectkey的语句获取最后一次id的值
        -->
        <selectKey keyColumn="id" keyProperty="id" resultType="int"  order="AFTER">
            <!--通过这个函数获取最后一次自增长主键的id值-->
            SELECT LAST_INSERT_ID() ;
        </selectKey>
        insert  into user(username,gender,age,address) values(#{username},#{gender},#{age},#{address})
    </insert>

mybatis模糊查询

<!--
    mybatis进行sql优化的时候,尽量使用#{} 占位符号
        不要使用${} (字符串拼接)
        推荐的写法 #{}
    -->
<select id="selectUsersByUserName" parameterType="java.lang.String" resultType="com.qf.pojo.User">
        select * from user where username like #{username}
</select>

通过vo实体查询指定用户

dao

  /**
     * 通过包装的vo实体查询指定的用户
     * @param vo vo实体
     * @return 返回用户
     */
    User findUserByQueryVo(QueryVo vo) ;

xml

<!--通过vo实体查询指定的用户
         参数形式QueryVo实体类型,里面包含另一个实体属性user属性
         获取到QueryVo对象.getUser().getUsername():获取到用户名
         一个实体类中的getXxx()里面xxx就是实体类的bean属性
         ognl简写表达式  get()去掉,第一个字母小写
    -->
    <select id="findUserByQueryVo" parameterType="queryvo" resultType="user">

            select * from user where username = #{user.username}
    </select>

入参类型是多个参数

顺序传参

dao:

User findUserByMultConditon(String name,String addr) ;

xml:

<!--指定多个条件查询用户
        按照参数的顺序进行查询,param1,param2....依次,不利于管理维护(不推荐)
    -->
   <select id="findUserByMultConditon" resultType="com.qf.pojo.User">

        select * from user where username = #{param1}  and address = #{param2}
    </select>

参数绑定注解方式(推荐)

dao:

//启用mybatis的@Param注解--指定绑定参数名称,这个参数名称就是等会需要赋值的参数(#{参数名称})
    User findUserByMultConditon(@Param("username") String name, @Param("address") String addr) ;

xml:

<!--
    指定多个条件查询用户的方式2:使用mybatis参数绑定注解方式(推荐)
    #{}里面的内容需要和@Param里面的参数名称一致
    -->
    <select id="findUserByMultConditon" resultType="com.qf.pojo.User">
        select * from user where username = #{username} and address = #{address}
    </select>

Map集合接收所有参数

dao:

//使用Map集合接收所有参数 --复杂类型
//User findUserByMultConditon(Map<String,String> map) ;

xml:

 <!--
    指定多个条件查询的方式3:使用Map集合
    #{}里面的内容需要和map集合的key一致
    -->
    <select id="findUserByMultConditon" resultType="com.qf.pojo.User">
        select * from user where username = #{name} and address  = #{addr}
    </select>

自定义vo实体封装

vo实体类

根据前端需要的具体参数,视情况而定vo类的属性

@Data
@NoArgsConstructor
@AllArgsConstructor
public class VoUser {
    private String name ;
    private String address ;
}

dao

//通过自定义的实体类,将查询的参数封装到这个类中
User findUserByMultConditon(VoUser voUser) ;

xml

<!--
        指定多个条件查询的方式4:使用自定义vo实体,将参数放在实体中
    -->
<select id="findUserByMultConditon" resultType="com.qf.pojo.User" parameterType="com.qf.pojo.VoUser">
        select * from user where username = #{name} and address = #{address}
</select>

mybatis使用德鲁伊连接池

pom.xml导入依赖

<!--druid德鲁伊-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.10</version>
</dependency>

创建配置文件

创建jdbc.properties

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ku'm?characterEncoding=utf-8
jdbc.username=root
jdbc.password=123456
jdbc.maxActive=10

自定义一个类

创建包名datasource下

/**
 * 自定义数据源工厂--提供德鲁伊的数据源DruidDataSource
 */
public class MyDruidDataSourceFactory  extends PooledDataSourceFactory {
    public MyDruidDataSourceFactory(){
        //给数据源进行初始化
        this.dataSource=new DruidDataSource();创建德鲁伊数据源
    }
}

优化后的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">
<!--xx.dtd是xml文件约束,约束标签-->
<!--核心配置-->
<configuration>
    <!--属性配置
        加载外部配置文件-->
    <properties resource="jdbc.properties"></properties>

    <!--实体类的别名配置-->
    <typeAliases>

        <!--type指定的当前实体类的完全限定名称
            alias:实体的类别名(自己指定,见名知意)
            这种方式麻烦(实体类很多,配置很多个typeAlias),可以直接指定实体类的包名
            所有的实体类的包名就是默认当前类名(建议小写),不区分大小写 -->

        <package name="com.qf.pojo"/>
    </typeAliases>
    <!--配置插件-->
    <plugins>
        <!--插件里面属性
            interceptor指定当前拦截器
        -->
        <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
    </plugins>
    <!--环境配置-->
    <environments default="mysql">
        <!--可以配置多个环境-->
        <environment id="mysql">
            <!--mybatis事务管理器
                        连接数据库操作 -->
            <transactionManager type="JDBC"/>
            
            <!--启用mybatis自带的连接池-->
            <!--<dataSource type="POOLED">-->
            
            <!--启用druid连接池-->
            <dataSource type="com.qf.datasource.MyDruidDataSourceFactory">
                <!--配置连接池这个类中的属性参数
                    drvier/url/username/password都是
                    org.apache.ibatis.datasource.pooled.PooledDataSource信息 -->
                
                <!--驱动类-->
                <!-- ${获取外部资源文件的key对应的内容} -->
                <property name="driverClassName" value="${jdbc.driverClassName}"/>
                <!--连接数据库的地址-->
                <property name="url" value="${jdbc.url}"/>
                <!--用户名-->
                <property name="username" value="${jdbc.username}"/>
                <!--登录密码-->
                <property name="password" value="${jdbc.password}"/>
                 <!--初始化数量-->
                <property name="maxActive" value="${jdbc.maxActive}"/>
            </dataSource>
        </environment>

    </environments>
    <!--加载mapper映射器-->
    <mappers>

        <!--配置接口的包名-->
        <package name="com.qf.mapper"/>
    </mappers>

</configuration>

Mybatis分页插件PageHelper的使用

导入分页插件依赖

<!--mybatis的分页插件-->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.1.2</version>
 </dependency>

配置插件

 <plugins>
        <!--插件里面属性
            interceptor指定当前拦截器
        -->
        <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
    </plugins>

业务层实现

先设置分页,再进行查询

//通过mybatis的分页插件完成分页条件
//PageHelper父类有一个API---
//参数:pageNum:当前页码
//	   pageSizeL
//public static <E> Page<E> startPage(int pageNum, int pageSize)
//当前页码1,每页显示3条
PageHelper.startPage(1,3) ;


//6)调用方法
List<User> users = userDao.findAll(); //获取分页列表数据
//创建PageInfo对象
PageInfo pageInfo = new PageInfo(users) ;
System.out.println(pageInfo); //展示分页的数据
if(users!=null || users.size()>0){
    for(User user :users){
        System.out.println(user);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值