ssm系列之MyBatis(一)

MyBatis简介

1、MyBatis可以简化JDBC操作,实现数据的持久化

2、MyBatis是ORM产品,是ORM的一个实现。对象关系映射(Object Relational Mapping,简称ORM)是通过使用描述对象和数据库之间映射的元数据,将面向对象语言程序中的对象自动持久化到关系数据库中。可以使操作数据库表变得和操作对象一样。
映射关系:对象与表名映射,对象的属性与表的属性映射
映射后每增加一个对象,被映射的表就会多一条数据

配置MyBatis

1、下载并导入jar包,mybatis.jar和数据库驱动jar包, mybatis.jar下载地址.
2、MyBatis是普通的Java项目,项目创建后首先要创建mapper.xml(在文件里把对象和表一一映射):增删改查标签,需要复制官方文档中的 2.15的代码

<?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=“”中放入映射文件的路径******
namespace:该mapper.xml映射文件的唯一标识-->
<mapper namespace="org.mybatis.example.BlogMapper">
<select id="selectBlog" resultType="Blog">
select * from Blog where id = #{id}
</select>
</mapper>

3、创建表和类
4、创建configure.xml配置文件,在里面添加数据库的信息和需要加载的映射文件,需要复制官方文档中的 2.12的代码

<?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值和environment的id 来指定MyBatis运行时的数据库环境-->
    <environments default="development">

        <!-- 开发环境(如自己的计算机) -->
        <environment id="development">

            <!-- 事务提交方式:
             JDBC:利用JDBC方式处理事务(commit rollback close)
             MANAGED:将事务交由其他组件去托管(spring,jobss),用完后会默认关闭连接,需要自己配置才不会关闭,代码如下:
             <transactionManager type="MANAGED"/>
                <property name="closeConnection" value="false"/>
             -->
            <transactionManager type="JDBC"/>   <!-- 用什么方式处理事务 -->

            <!-- 数据源类型:
             UNPOOLED:传统的JDBC模式,每次访问数据库,都需要进行打开和关闭等数据库操作,比较消耗性能
             POOLED:使用数据库连接池,有多个连接就能处理多个请求,用完后只需还回来,省略了数据库的打开和关闭,提高效率
             JNDI:从tomcat中获取一个内置的数据库连接池()
             -->
            <dataSource type="POOLED">
                <!-- 配置数据库信息 -->
                <property name="driver" value="oracle.jdbc.OracleDriver"/>     <!-- value里放数据库的驱动 -->
                <property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:ORCL"/>       <!-- 访问数据库的链接字符串 -->
                <property name="username" value="scott"/>
                <property name="password" value="tiger"/>
            </dataSource>
        </environment>

        <!-- 真正的项目应该在发布的那台计算机上运行(实施计算机) -->
        <environment id="implement">
          <!-- .........-->.
        </environment>

    </environments>
    <mappers>
        <!-- 加载映射文件 -->
        <mapper resource="chern/cn/studentMapper"/>
    </mappers>
</configuration>

基础方式的增删改查

1、输入参数:如果是简单类型(8个基本类型+String),则可以使用任意占位符,即可在#{}里写任意名称,代码如下

<!--parameterType:输入参数类型    resultType:返回值类型
    且mybatis规定parameterType输入参数和resultType输出参数在形式上只能有一个
    如果是对象类型,则必须是对象的属性 #{属性名},代码如下
    -->
    
	<!---->
<insert id="addStudent" parameterType="chern.cn.Student">
        insert into student(stuno,stuname,stuage,graname) values(#{stuNo},#{stuName},#{stuAge},#{graName})
    </insert>
    
	<!---->
    <delete id="deleteStudentByStuno"   parameterType="int">
        delete from student where stuno = #{stuno}
    </delete>
    
    <!---->
    <update id="updateStudentByStuno" parameterType="chern.cn.Student">
        update student set stuname=#{stuName}, stuage=#{stuAge},graname=#{graName} where stuno=#{stuNo}
    </update>
    
    <!---->
<select id="queryPersonByStuno" resultType="chern.cn.Student" parameterType="int">
    select * from student where stuno = #{stuno}

2、输出参数:如果返回值类型是一个对象(如Student),则无论返回一个、还是多个,在resultType都写成chern.cn.Student

3、如果使用的事务方式为JDBC,则需要手工commit提交,即session.commit();

4、所有的标签等,都必须有sql语句,但是sql参数值可选,
如:select * from student where stuno = #{xxx}中select * from student代表第一个参数,where stuno = #{xxx}代表第二个参数,代码如下

//java执行查询代码
		//加载MyBatis配置文件(为了访问数据库)
        //Connection - SqlSession操作MyBatis
        //conf.xml -> reader
		Reader reader = Resources.getResourceAsReader("conf");
        //SqlSessionFactory - connection
        //reader -> SqlSession
        //通过SqlSessionFactoryBuilder().build()的第二个参数可以指定MyBatis运行时的数据库环境
        //如SqlSessionFactoryBuilder().build(reader,"development")
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
        //session - connection
        SqlSession session = sessionFactory.openSession();
        //session.selectOne("需要查询的SQL的namespace.id,"SQL的参数值")
        String statement = "chern.cn.studentMapper.queryPersonByStuno";
        Student student = session.selectOne(statement,1);
        System.out.println(student);
        session.close();

<!-- 对应映射文件的代码 -->
<mapper namespace="chern.cn.studentMapper">
    <select id="queryPersonByStuno" resultType="chern.cn.Student" parameterType="int">
    select * from student where stuno = #{stuno}
    </select>

mapper动态代理方式的增删改查(MyBatis接口开发)

1、原则:约定优于配置,配置优于硬编码
2、各种方式
以配置项目的名字为例
硬编码方式:
abc.java

		Configuration conf = new Configuration();
		conf.setName("myProject");

配置方式:
abc.xml

		<name>myProject</name>	

约定:默认值设置为myProject

3、实现步骤
1)、基础环境:mybatis.jar、ojdbc.jar、conf.xml、mapper.xml
2)、约定的目标:省略掉statement,即根据约定直接定位出sql语句
a、接口,接口中的方法必须遵循以下规则

1、方法名和mapper.xml文件中标签的id值相同
2、方法的输入参数和mapper.xml文件中标签的parameterType类型一致(如果mapper.xml的标签中没有parameterType,则说明方法没有输入参数)
3、方法的返回值和mapper.xml文件中标签的resultType类型一致(如果没有返回值,则说明方法的返回值为void)

除了以上约定,要实现 接口中的方法 和 mapper.xml中sql标签一一对应,还需要:把namespace的值设置为接口的全类名(接口 – mapper.xml 一一对应)

约定的过程
1、根据 接口名 找到 mapper.xml文件(根据的是namespace=接口全类名)
2、根据 接口的方法名 找到 mapper.xml文件中的sql标签(方法名=sql标签Id值)

以上2点可以保证:当我们调用接口中的方法时,程序能自动定位到 某一个mapper.xml文件中的sql标签

习惯:一般我们把sql映射文件(mapper.xml) 和 接口放在同一个包中

可以通过接口的方法->sql语句

主要代码:

//主要是定义好StudentMapper接口后,在里面创建相应的方法。

//mapper.xml的代码
<mapper namespace="chern.mapper.StudentMapper">
<select id="queryPersonByStuno" resultType="student" parameterType="int">
    select * from student where stuno = #{stuno}
 </select>

//StudentMapper.java的代码
Student queryPersonByStuno(int stuno);

//main方法里的代码
Reader reader = Resources.getResourceAsReader("conf");
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
        SqlSession session = sessionFactory.openSession();
        StudentMapper sessionMapper = session.getMapper(StudentMapper.class);
        Student student = sessionMapper.queryPersonByStuno(1);//接口中的方法->sql语句
        System.out.println(student);
        session.close();

在main方法中通过session对象获取接口(session.getMapper(接口.class)),再调用该接口中的方法,程序会自动执行该方法对应的sql

优化

1、改配置信息
可以将配置信息 以key–value对的形式 单独放入db.properties文件(文件放在根目录里)中,然后再动态引入(在conf.xml的configuration标签下添加<properties resource="文件路径"/>
如:

//db.properties代码
driver=oracle.jdbc.OracleDriver
url=jdbc:oracle:thin:@127.0.0.1:1521:ORCL
username=scott
password=tiger

//conf.xml代码
<!-- 该标签放在<configuration>标签下 -->
<properties resource="db.properties"/>

	<!-- 配置数据库信息 -->
	<property name="driver" value="${driver}"/>
	<property name="url" value="${url}"/>
	<property name="username" value="${username}"/>
	<property name="password" value="${password}"/>


2、全局参数(在conf文件中设置)
代码如下:

<settings>
        //<setting name="需要设置的参数" value="开启或关闭"/>如
        <setting name="cacheEnabled" value="false"/>
    </settings>

3、别名(在conf中配置)
a、设置单个别名
b、批量设置别名
代码如下:

<typeAliases>
        <!--单个别名(别名忽略大小写)
        <typeAlias type="chern.cn.Student" alias="student"/>
        -->
        <!--批量定义别名(别名忽略大小写),会自动将该包中的所有类批量定义别名:别名就是类名(不带包名的类名)-->
        <package name="chern.cn"/>
    </typeAliases>

除了自定义别名外,MyBatis还内置了一些常见类的别名,在这里就不一一列举了。

类型处理器(类型转换器)

1、MyBatis自带一些常见的类型处理器,如 int - number
2、自定义MyBatis类型处理器:java - 数据库(jdbc类型)
实例:
实体类Student: boolean stuSex
true:男
false:女
表student: number stuSex
1:男
0:女
自定义类型转换器(boolean - number)步骤:
a、创建转换器:实现TypeHandler接口(此接口有一个实现类BaseTypeHandler,所以也可以继承该实现类),主要代码

//BooleanAndIntConverter.java代码

public class BooleanAndIntConverter extends BaseTypeHandler<Boolean> {
    //set:java -> 数据库(DB)
    //get:数据库(DB)-> java
    /**
     * preparedStatement:PreparedStatement对象
     * i:PreparedStatement对象操作参数的位置
     * aBoolean:java值
     * jdbcType:jdbc操作的数据库类型
     */
    //java(boolean) -> DB(number)
    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, Boolean aBoolean, JdbcType jdbcType) throws SQLException {
        if(aBoolean){
            preparedStatement.setInt(i,1);
        }
        else{
            preparedStatement.setInt(i,0);
        }
    }
    //DB(number) -> java(boolean)
    @Override
    public Boolean getNullableResult(ResultSet resultSet, String s) throws SQLException {
        int sexnum = resultSet.getInt(s);
        return sexnum == 1?true:false;
    }

    @Override
    public Boolean getNullableResult(ResultSet resultSet, int i) throws SQLException {
        int sexnum = resultSet.getInt(i);
        return sexnum == 1?true:false;
    }

    @Override
    //CallableStatement:存储过程
    public Boolean getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        int sexnum = callableStatement.getInt(i);
        return sexnum == 1?true:false;
    }
}

b、配置conf.xml

<typeHandlers>
        <typeHandler handler="chern.converter.BooleanAndIntConverter" javaType="Boolean" jdbcType="INTEGER"/>
    </typeHandlers>

在做好以上配置后,我们还需要在studentMapper.xml进行进一步的配置。
如果类中属性 和 表中的字段 类型能够合理识别(String-varchar2),则可以使用resultType;否则使用resultMap(boolean-number)。
如果类中属性名 和 表中的字段名 能够合理识别(stuNo -stuno),则可以使用resultType;否则使用resultMap(id-stuno)。主要代码如下:

<select id="queryStudentByStunoWithConverter" resultMap="studentResult" parameterType="int">
    select * from student where stuno = #{stuno}
    </select>
    <resultMap id="studentResult" type="student">
        <!--分为主键(使用<id/>标签) 和 非主键使用<result/>标签)-->
        <id property="stuNo" column="stuno"/>
        <result property="stuName" column="stuname"/>
        <result property="stuAge" column="stuage"/>
        <result property="graName" column="graname"/>
        <result property="stuSex" column="stusex" javaType="boolean" jdbcType="INTEGER"/>
    </resultMap>
发布了8 篇原创文章 · 获赞 3 · 访问量 421
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章