MyBatis

MyBatis

ORM

ORM:对象关系映射

ORM框架

Hibernate(SpringDataJPA)、MyBatis

MyBatis介绍

Mybatis就是ORM一种实现的框架 MyBatis完成持久层框架

各大ORM框架优缺点

JDBC
优点:操作数据库最底层的技术,所有ORM框架的底层都是jdbc,可以自行封装,满足你的各种需求
缺点:编写比较麻烦,重复性高,sql需要写到代码内,sql和代码耦合度比较高,没有缓存,还要自行封装数据
JPA
优点:不懂sql也可以操作数据库,使用简单,不用写sql,自动化,以及世界级缓存
缺点:性能太难掌控
MyBatis
优点:可以灵活的操作sql,有缓存支持,不用封装数据,避免jdbc重复性代码
缺点:非全自动化

MyBatis入门

导包
asm-3.3.1.jar
cglib-2.2.2.jar
commons-logging-1.1.1.jar
javassist-3.17.1-GA.jar
log4j-1.2.17.jar
mybatis-3.2.1.jar
mysql-connector-java-5.1.26-bin.jar
slf4j-api-1.7.2.jar
slf4j-log4j12-1.7.2.jar

maven导包
<!-- 引入数据库驱动包 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.32</version>
</dependency>
<!-- 引入mybatis核心包 -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.3.0</version>
</dependency>
<!-- 引入junit测试 -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.9</version>
    <scope>test</scope>
</dependency>
<!-- 引入log4j包 -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
编写配置文件
<?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>
    <!-- 引入db.properties -->
    <properties resource="db.properties"/>
     <!-- 取别名-->
    <typeAliases>
        <typeAlias type="cn.itsource.domain.Product" alias="product"></typeAlias>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <!-- 事务管理 -->
            <transactionManager type="JDBC"></transactionManager>
            <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}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!-- 引入映射配置 -->
        <mapper resource="cn/itsource/domain/ProductMapper.xml"></mapper>
    </mappers>
</configuration>
编写映射文件
<mapper namespace="cn.itsource.domain.ProductMapper">
    <!--
        当domain的字段对应不上数据库表字段时
        column  数据库字段名
        property    对象字段名
    -->
    <!-- 查询一条 -->
    <select id="queryOne" parameterType="long" resultType="cn.itsource.domain.Product">
        select * from product where id = #{id}
    </select>
</mapper>
查询一条数据
dao层实现
 SqlSession sqlSession = null;
    try {
        //获取SqlSessionFactory
        Reader reader = Resources.getResourceAsReader("MyBatis-ConFig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        //获得sqlSession
        sqlSession = sqlSessionFactory.openSession();
        //查询
        return sqlSession.selectOne(NAMESPACE+"queryOne",id);
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }finally {
        if (sqlSession != null)
            sqlSession.close();
    }

测试类

@Test
public void queryOne() {
    Product product = productDao.queryOne(2L);
    System.out.println(product);
}
sqlSession工具类抽取
private static SqlSessionFactory sqlSessionFactory = null;
//使用静态代码块,确保SqlSessionFactory只创建一次
static {
    try {
        //获取SqlSessionFactory
        Reader reader = Resources.getResourceAsReader("MyBatis-ConFig.xml");
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
    } catch (IOException e) {
        e.printStackTrace();
        throw new RuntimeException("解析MyBatis的配置文件或者映射文件出现异常:" + e.getMessage());
    }
}
public static SqlSession createSqlSession(){
    //创建SqlSession对象
    return sqlSessionFactory.openSession();
}

SqlSessionFactory是一个重量级对象,创建不容易,因此一般一个项目只创建一次该对象,使用单例创建或静态代码块来创建

而sqlsession是线程不安全的,每个线程都应该有自己的sqlSession对象

添加并返回主键id
<!--
        添加一条数据
        useGeneratedKeys=true   添加数据并返回id
        keyColumn   数据库中主键对应的列
        keyProperty     对象对应的主键字段
    -->
 <insert id="save" parameterType="product" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
        insert into product(productName,dir_id,salePrice,supplier,brand,cutoff,costPrice)
        values (#{productName},#{dir_id},#{salePrice},#{supplier},#{brand},#{cutoff},#{costPrice})
    </insert>

添加修改删除都应该有事务

//获取sqlSession
SqlSession sqlSession = MyBatisUtils.createSqlSession();
//添加数据
sqlSession.insert(NAMESPACE+"save",product);
//提交事务
sqlSession.commit();
//关闭sqlSession
sqlSession.close();

sqlSession对象使用完后要记得关闭

MyBatis中为一个类取别名
在MyBatis主配置文件中添加
<typeAliases>
    <typeAlias type="cn.itsource.domain.Product" alias="product"></typeAlias>
    <!-- 为该路径下的 -->
</typeAliases>

即可不用重复写全限定名

<!-- 查询所有数据 -->
<select id="queryAll" resultType="product">
    select * from product
</select>
列名与属性名不对应的解决方案resultMap
<!--
    当domain的字段对应不上数据库表字段时
    column  数据库字段名
    property    对象字段名
-->
<resultMap id="productMap" type="product">
    <id property="id" column="id"></id>
    <result column="productName" property="name"></result>
</resultMap>
<!-- 查询所有数据 -->
<select id="queryAll" resultMap="productMap">
    select * from product
</select>
Log4j日志框架
#日志输出优先级
log4j.rootLogger=ERROR, stdout
#输出根
log4j.logger.cn.itsource=TRACE
#输出位置(控制台)
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
#输出格式
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n

log4j配置文件命名一定要是:log4j.properties

上面导包时已经将log4j的包导入了

MyBatis SQL参数传递

$与#
#和$的区别
#不是拼接sql,防sql注入
$拼接sql不防sql注入
$可用在分页排序

(多对一)关联映射递

<mapper namespace="cn.itsource.mybatis.domain.ProductMapper">
    <!--结果嵌套,只发送一条sql,将查询到的结果指定封装-->
    <!--
    <resultMap id="productMap" type="cn.itsource.mybatis.domain.Product">
        <id property="id" column="id"></id>
        <result property="productName" column="productName"></result>
        <result property="dir_id" column="dir_id"></result>
        <association property="dir" javaType="cn.itsource.mybatis.domain.ProductDir">
            <id property="id" column="did"></id>
            <result column="dname" property="dirName"></result>
        </association>
    </resultMap>
    <select id="queryAll" resultMap="productMap">
        select p.*,d.id did,d.dirName dname from product p join productdir d on p.dir_id = d.id
    </select>
    -->
    <!--嵌套查询-->
    <resultMap id="productMap" type="cn.itsource.mybatis.domain.Product">
        <id property="id" column="id"></id>
        <result property="productName" column="productName"></result>
        <result property="dir_id" column="dir_id"></result>
        <association property="dir" column="dir_id" select="cn.itsource.mybatis.domain.ProductMapper.queryDir"></association>
    </resultMap>
    <select id="queryAll" resultMap="productMap">
        select * from product
    </select>
    <select id="queryDir" resultType="cn.itsource.mybatis.domain.ProductDir" parameterType="long">
        select * from productdir where id=#{dir_id};
    </select>
</mapper>

结果嵌套性能相对高一点,只发送了一条sql

嵌套查询是1+n条sql,发送sql较多,性能相对较低

(一对多)关联映射递

<mapper namespace="cn.itsource.mybatis.domain.DeptMapper">
    <!--结果嵌套,只发送一条sql,将查询到的结果指定封装-->
    <!--<resultMap id="deptMap" type="cn.itsource.mybatis.domain.Dept">
        <id property="id" column="id"></id>
        <result property="name" column="name"></result>
        <collection  property="employee" javaType="cn.itsource.mybatis.domain.Employee">
            <id property="id" column="eid"></id>
            <result column="ename" property="name"></result>
        </collection>
    </resultMap>
    <select id="queryAll" resultMap="deptMap">
        select d.*,e.id eid,e.name ename from Dept d join employee e on d.id = e.dept_id
    </select>-->
    <!--嵌套查询-->
    <resultMap id="deptMap" type="cn.itsource.mybatis.domain.Dept">
        <id property="id" column="id"></id>
        <result property="name" column="name"></result>
        <collection property="employee" column="id" select="cn.itsource.mybatis.domain.DeptMapper.queryDir"></collection>
    </resultMap>
    <select id="queryAll" resultMap="deptMap">
        select * from dept
    </select>
    <select id="queryDir" resultType="cn.itsource.mybatis.domain.Dept" parameterType="long">
        select * from employee where dept_id=#{id};
    </select>
</mapper>

一对多查询时不能使用结果嵌套因为map中不能存在多个key值

要使用查询嵌套

SQL映射器Mapper

MyBatis基于代理机制,可以让我们无需再编写Dao的实现。
SqlSession sqlSession = MyBatisUtils.createSqlSession();
SkillsMapper mapper = sqlSession.getMapper(SkillsMapper.class);
Skills skills = mapper.queryOne(1L);
sqlSession.close();

在使用时,映射文件的namespace填写接口绝对路径,方法名要与映射文件的保持一致

Skills queryOne(Long id);

<select id="queryOne" parameterType="long" resultType="cn.itsource.mybatis.domain.Skills">
  select * from skills where id = #{id}
</select>

缓存

默认支持一级缓存,二级缓存需要配置,同JPA一致,同一个sqlsession,同一主键id命中
二级缓存命中条件,同一SqlSessionFactory,不同的sqlsessin,同一主键id
还需要添加配置

ssm集成

jar包
asm-3.3.1.jar
cglib-2.2.2.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.apache.commons.dbcp-1.2.2.osgi.jar
com.springsource.org.apache.commons.fileupload-1.2.0.jar
com.springsource.org.apache.commons.io-1.4.0.jar
com.springsource.org.apache.commons.logging-1.1.1.jar
com.springsource.org.apache.commons.pool-1.5.3.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
commons-logging-1.1.1.jar
ehcache-2.10.1.jar
freemarker.jar
javamail.jar
javassist-3.17.1-GA.jar
jstl.jarv
log4j-1.2.17.jar
mybatis-3.2.1.jar
mybatis-spring-1.2.0.jar
mysql-connector-java-5.1.6.jar
servlet-api.jar
slf4j-api-1.7.7.jar
slf4j-jdk14-1.7.7.jar
slf4j-log4j12-1.7.2.jar
spring-aop-4.1.2.RELEASE.jar
spring-beans-4.1.2.RELEASE.jar
spring-context-4.1.2.RELEASE.jar
spring-core-4.1.2.RELEASE.jar
spring-expression-4.1.2.RELEASE.jar
spring-jdbc-4.1.2.RELEASE.jar
spring-test-4.1.2.RELEASE.jar
spring-tx-4.1.2.RELEASE.jar
spring-web-4.1.2.RELEASE.jar
spring-webmvc-4.1.2.RELEASE.jar
standard.jar
thumbnai.jar
mave导包
<properties>
           <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
          <log4j.version>1.2.17</log4j.version>
          <spring.version>4.3.9.RELEASE</spring.version>
           <mybatis.version>3.2.2</mybatis.version>
   </properties>
    <dependencies>
           <dependency>
             <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>${log4j.version}</version>
         </dependency>
        <!-- spring -->
        <dependency>
             <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>
        
         <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${spring.version}</version>
        </dependency>
        
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
         
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
             <version>${spring.version}</version>
         </dependency>
       
         <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
             <version>${spring.version}</version>
        </dependency>
         
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-instrument</artifactId>
            <version>${spring.version}</version>
        </dependency>
        
        <dependency>
             <groupId>org.springframework</groupId>
            <artifactId>spring-instrument-tomcat</artifactId>
            <version>${spring.version}</version>
        </dependency>
        
         <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jms</artifactId>
            <version>${spring.version}</version>
        </dependency>
        
       <dependency>
             <groupId>org.springframework</groupId>
            <artifactId>spring-messaging</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
           <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-oxm</artifactId>
            <version>${spring.version}</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>
         
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
         </dependency>
        
        <dependency>
             <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc-portlet</artifactId>
            <version>${spring.version}</version>
         </dependency>
        
         
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-websocket</artifactId>
             <version>${spring.version}</version>
        </dependency>
         <!-- mybatis -->
        
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>${mybatis.version}</version>
        </dependency>
         
         
         <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.2.2</version>
        </dependency>
       <!-- 上传下载 -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
             <version>1.3.1</version>
        </dependency>
         <dependency>
            <groupId>commons-io</groupId>
             <artifactId>commons-io</artifactId>
            <version>2.2</version>
         </dependency>
        <dependency>
             <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
         
        <dependency>  
           <groupId>javax</groupId>  
            <artifactId>javaee-api</artifactId>  
            <version>8.0</version>  
            <scope>provided</scope>  
       </dependency> 
      
         
          <dependency>  
           <groupId>javax</groupId>  
             <artifactId>javaee-web-api</artifactId>  
            <version>8.0</version>  
            <scope>provided</scope>  
        </dependency> 
         <dependency> 
               <groupId>net.sf.json-lib</groupId>
              <artifactId>json-lib</artifactId>
              <version>2.1</version>
              <classifier>jdk15</classifier>
        </dependency>
        <dependency>
             <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency> 
            <groupId>mysql</groupId>
             <artifactId>mysql-connector-java</artifactId>
             <version>5.1.41</version>
         </dependency>
   </dependencies>
spring配置
<!-- 引入mvc配置文件-->
    <import resource="classpath:applicationContext-mvc.xml"/>
    <!-- 扫描包 扫描service层 controller层-->
    <context:component-scan base-package="cn.itsource"></context:component-scan>

    <!-- 引入jdbc.properties-->
    <context:property-placeholder location="classpath:db.properties"></context:property-placeholder>

    <!-- dataSource-->
    <!-- 连接池 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <!--maxActive: 最大连接数量 -->
        <property name="maxActive" value="150" />
        <!--minIdle: 最小空闲连接 -->
        <property name="minIdle" value="5" />
        <!--maxIdle: 最大空闲连接 -->
        <property name="maxIdle" value="20" />
        <!--initialSize: 初始化连接 -->
        <property name="initialSize" value="30" />
        <!-- 连接被泄露时是否打印 -->
        <property name="logAbandoned" value="true" />
        <!--removeAbandoned: 是否自动回收超时连接 -->
        <property name="removeAbandoned" value="true" />
        <!--removeAbandonedTimeout: 超时时间(以秒数为单位) -->
        <property name="removeAbandonedTimeout" value="10" />
        <!--maxWait: 超时等待时间以毫秒为单位 1000等于60秒 -->
        <property name="maxWait" value="1000" />
        <!-- 在空闲连接回收器线程运行期间休眠的时间值,以毫秒为单位. -->
        <property name="timeBetweenEvictionRunsMillis" value="10000" />
        <!-- 在每次空闲连接回收器线程(如果有)运行时检查的连接数量 -->
        <property name="numTestsPerEvictionRun" value="10" />
        <!-- 1000 * 60 * 30 连接在池中保持空闲而不被空闲连接回收器线程 -->
        <property name="minEvictableIdleTimeMillis" value="10000" />
        <property name="validationQuery" value="SELECT NOW() FROM DUAL" />
    </bean>

    <!-- sqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="mapperLocations" value="classpath:cn/itsource/mapper/*Mapper.xml"></property>
    </bean>

    <!-- 扫描mapper-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="cn.itsource.mapper"/>
    </bean>

    <!-- 事务-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!-- 2.开启注解事务:解析@Transactional注解 -->
    <tx:annotation-driven transaction-manager="transactionManager" />
springMVC配置
<!-- 开启spring对springmvc 注解的支持 RequestMappeing -->
    <mvc:annotation-driven />

    <!-- 对静态资源如图片进行放行,不经过DispatcherServlet,使用tomcat的DefaultServlet处理 -->
    <mvc:default-servlet-handler />

    <!-- 视图解析器:设置视图路径的前后缀,该配置可以让我们写视图路径的时候更简单。 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- struts:<result name="login">/WEB-INF/views/login.jsp</result> -->
        <!--前缀: jsp在当前工程文件夹的路径 -->
        <property name="prefix" value="/WEB-INF/views/" />
        <!--后缀:扩展名 -->
        <property name="suffix" value=".jsp" />
    </bean>
web.xml
<!-- 配置核心控制器 -->
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 引用spring配置(包括springmvc+spring+mybatis)-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>


    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>

当与spring集成以后就再也不需要我们自己管理SqlSessionFactory,也不用我们自己去实现dao

dao层接口
 List<Product> queryAll();
service层
@Autowired
private ProductMapper productMapper;

@Override
public List<Product> queryAll() {
    return productMapper.queryAll();
}

直接注入dao层,调用方法就行

Controller
@Autowired
private IProductService productService;
@RequestMapping("/product")
public String queryAll(){
    productService.queryAll();
    return null;
}

ssm集成完毕

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值