Mybatis学习1

Mybatis01

1.什么是MyBatis ?

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。

iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)

概述

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。

Hibernate (很强大,重量级,不灵活,复杂)

特点

  • 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
  • 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
  • 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
  • 提供映射标签,支持对象与数据库的orm字段关系映射
  • 提供对象关系映射标签,支持对象关系组建维护
  • 提供xml标签,支持编写动态sql。

中文官网

http://www.mybatis.cn/

2快速入门

1.创建maven工程

2.在pom.xml文件下引入依赖

    <dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.12</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
        </dependency>

    </dependencies>

3.引入实体类


/**
 * 学生实体类 与 student_tb一一对应
 */
public class Student implements Serializable {

    private int id;

    private String name;

    private String sex;

    private int age;

    private float height;

    private Date birthday;


    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public float getHeight() {
        return height;
    }

    public void setHeight(float height) {
        this.height = height;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", age=" + age +
                ", height=" + height +
                ", birthday=" + birthday +
                '}';
    }
}

4.编写持久层IStudentDao接口

import com.wgz.entity.Student;

import java.util.List;

public interface IStudentDao {

     /**
      * 查找所有学生
      * @return
      */
     List<Student> findAllStudent();

}

5.编写持久层配置文件IStudentDao.xml

注意:
  • 1.配置文件的名称必须以 接口名+.xml命名
  • 2.文件的位置必须放在main目录下resources\com\wgz\dao对应目录
<?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="com.wgz.dao.IStudentDao">
        <!--配置查询所有学生的 方法
            id:为对应的方法方法名
            resultType:返回数据类型的全限定名
        -->
        <select id="findAllStudent" resultType="com.wgz.entity.Student">
            select * from student_tb
        </select>



</mapper>

6.在 创建sqlMapConfig.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">
<!--
    mybatis主配置
-->
<configuration >

    <!--配置mybatis环境-->
    <environments default="mysql">
        <environment id="mysql">
            <transactionManager type="JDBC"></transactionManager>
            <!--配置数据源-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/szqy08"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>



    <mappers>
    		
            <mapper resource="com/wgz/dao/IStudentDao.xml"></mapper>
    </mappers>

</configuration>

7.创建测试类


public class TestMybatis {

    public static void main(String[] args) {


        try {
            // 1.读取配置文件
            InputStream in = Resources.getResourceAsStream("sqlMapConfig.xml");

            // 2.创建session工厂
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
            SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(in);

            // 3.获取session
            SqlSession sqlSession = sqlSessionFactory.openSession();

            //  4.使用sqlSession 创建代理对象

            // 方式一 通过代理:
          //  IStudentDao studentDao = sqlSession.getMapper(IStudentDao.class);
//            List<Student> studentList  = studentDao.findAllStudent();

            // 方式二:方式儿直接指明方法名
            List<Student> studentList = sqlSession.selectList("com.wgz.dao.IStudentDao.findAllStudent");

            for (Student student:studentList){
                System.out.println(student);
            }


        } catch (IOException e) {
            e.printStackTrace();
        }


    }

}

8.配置mybatis的日志,在resouces目录下创建log4j.properties

# 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

# 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=mybatis.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

3.基于mybatis实现curd

根据id查询学生

1.IStudentDao接口中增加


     /**
      * 根据 查询学生
      * @param id
      * @return
      */
     Student findStudentById(int id);

2.在IStudentDao.xml中增加

        <select id="findStudentById" parameterType="java.lang.Integer" resultType="com.wgz.entity.Student">
              select * from student_tb where id=#{id}
        </select>

说明:
  • parameterType:为传入参数的类型

  • resultType:为输出参数的类型

  • #{id} 为占位符 获取接口中的参数

3.测试

    private static void findStudentById(IStudentDao studentDao) {
        Student student = studentDao.findStudentById(42);
        System.out.println("student:"+student);
    }
增加学生

1.IStudentDao接口中增加


        /**
      * 保存学生
      * @param student
      */
     void saveStudent(Student student);

2.在IStudentDao.xml中增加

        <insert id="saveStudent" parameterType="com.wgz.entity.Student" >

            insert into  student_tb (name,age,sex,height,birthday)values (#{name},#{age},#{sex},#{height},#{birthday})

        </insert>
说明
  • #{name} 为获取参数中student 对象中的属性值

3.测试

    /**
     * 增加学生
     * @param studentDao
     */
    private static void addStudent(IStudentDao studentDao) {

        Student student = new Student();
        student.setAge(19);
        student.setName("zhangsan");
        student.setHeight(178);
        student.setBirthday(Date.valueOf("2007-02-23"));
        studentDao.saveStudent(student);
    }
删除学生

1.IStudentDao接口中增加

     /**
      * 删除学生
      * @param id
      * @return
      */
     int deleteStudentById(int id);

2.在IStudentDao.xml中增加

        <delete id="deleteStudentById" parameterType="java.lang.Integer">
                delete from student_tb where id = #{id}
        </delete>

3.测试

    private static void deleteStudent(IStudentDao studentDao) {
	//  获取影响 修改的数量
       int num= studentDao.deleteStudentById(44);
        System.out.println("num:"+num);
    }
修改学生

1.IStudentDao接口中增加

     /**
      * 更新学生
      * @param student
      * @return
      */
     int updateStudent(Student student);

2.在IStudentDao.xml中增加

        <update id="updateStudent" parameterType="com.wgz.entity.Student">

            update student_tb set name=#{name},age=#{age},height=#{height},sex=#{sex},birthday=#{birthday} where id=#{id}
        </update>

3.测试

    private static void updateStudent(IStudentDao studentDao) {
        Student student = new Student();
        student.setAge(20);
        student.setName("zhangsan");
        student.setHeight(178);
        student.setBirthday(Date.valueOf("2007-02-23"));
        student.setId(46);

        int num =  studentDao.updateStudent(student);
        System.out.println("num:"+num);
    }

4.获取自增id

  • 使用selectKey方式获取
        <!--产生自增ID-->
      <insert id="saveStudent" parameterType="com.wgz.entity.Student"  >


            insert into  student_tb (name,age,sex,height,birthday)values (#{name},#{age},#{sex},#{height},#{birthday})
          <selectKey  keyColumn="id" keyProperty="id" resultType="java.lang.Integer" order="AFTER">
              select last_insert_id()
          </selectKey>
        </insert>

useGeneratedKeys=“true” 设置使用自增主键;

keyProperty=“id” 设置自增主键返回字段(用户在插入数据之后获取相应主键);

order=“AFTER” 设置在insert之前执行查询序列操作,然后在insert时候引用查询的序列#{id}

  • 使用useGeneratedKeys方式获取
    <insert id="saveStudent" parameterType="com.wgz.entity.Student" useGeneratedKeys="true" keyProperty="id" keyColumn="id" >

        insert into  student_tb (name,age,sex,height,birthday)values (#{name},#{age},#{sex},#{height},#{birthday})

    </insert>

测试

    /**
     * 增加学生
     * @param studentDao
     */
    private static void addStudent(IStudentDao studentDao) {

        Student student = new Student();
        student.setAge(19);
        student.setName("zhangsan");
        student.setHeight(178);
        student.setBirthday(Date.valueOf("2007-02-23"));
        int num =  studentDao.saveStudent(student);
        System.out.println("num:"+num);
        // 可以得到学生的id
        System.out.println("student:"+student);
    }

5.模糊查询

  • 方式一

1.IStudentDao接口中增加

     /**
      * 根据名称模糊查询
      * @param likeName
      * @return
      */
     List<Student> findStudentListByName(String likeName);

2.在IStudentDao.xml中增加

        <select id="findStudentListByName" parameterType="string" resultType="com.wgz.entity.Student">
            select  * from  student_tb where  name like  #{likeName}
        </select>

3.测试

   List<Student> studentList = studentDao.findStudentListByName("%an%");
  for (Student student:studentList){
            System.out.println(student);
        }
  • 方式2

修改IStudentDao.xml

   <select id="findStudentListByName" parameterType="string" resultType="com.wgz.entity.Student">
            select  * from  student_tb where  name like '%${value}%'
        </select>

v a l u e 为 s q l 语 句 的 拼 接 , 以 {value} 为sql语句的拼接,以 valuesql{value} 的形式获取likeName的值,并拼接,注意${value}必须是value字段

测试

    private static void findStudentByName(IStudentDao studentDao) {

        List<Student> studentList = studentDao.findStudentListByName("an");
        for (Student student:studentList){
            System.out.println(student);
        }
    }
#{}vs${}区别?

#{}是获取参数中的属性值,并讲java中的类型转化为数据库中的类型

为 s q l 语 句 拼 接 , 以 {} 为sql语句拼接,以 sql{value} 获取参数中的值

6别名的配置

在mybatis中使用parameterType或者resultType 是必须写全限定名,其实在mybatis已经为我们配置好了一些类型别名,我们也可以自定配置别名

系统别名

在mybatis中TypeAliasRegistry已经为我们配置的默认别名

    registerAlias("string", String.class);

    registerAlias("byte", Byte.class);
    registerAlias("long", Long.class);
    registerAlias("short", Short.class);
    registerAlias("int", Integer.class);
    registerAlias("integer", Integer.class);
    registerAlias("double", Double.class);
    registerAlias("float", Float.class);
    registerAlias("boolean", Boolean.class);

    registerAlias("byte[]", Byte[].class);
    registerAlias("long[]", Long[].class);
    registerAlias("short[]", Short[].class);
    registerAlias("int[]", Integer[].class);
    registerAlias("integer[]", Integer[].class);
    registerAlias("double[]", Double[].class);
    registerAlias("float[]", Float[].class);
    registerAlias("boolean[]", Boolean[].class);

    registerAlias("_byte", byte.class);
    registerAlias("_long", long.class);
    registerAlias("_short", short.class);
    registerAlias("_int", int.class);
    registerAlias("_integer", int.class);
    registerAlias("_double", double.class);
    registerAlias("_float", float.class);
    registerAlias("_boolean", boolean.class);

    registerAlias("_byte[]", byte[].class);
    registerAlias("_long[]", long[].class);
    registerAlias("_short[]", short[].class);
    registerAlias("_int[]", int[].class);
    registerAlias("_integer[]", int[].class);
    registerAlias("_double[]", double[].class);
    registerAlias("_float[]", float[].class);
    registerAlias("_boolean[]", boolean[].class);

    registerAlias("date", Date.class);
    registerAlias("decimal", BigDecimal.class);
    registerAlias("bigdecimal", BigDecimal.class);
    registerAlias("biginteger", BigInteger.class);
    registerAlias("object", Object.class);

    registerAlias("date[]", Date[].class);
    registerAlias("decimal[]", BigDecimal[].class);
    registerAlias("bigdecimal[]", BigDecimal[].class);
    registerAlias("biginteger[]", BigInteger[].class);
    registerAlias("object[]", Object[].class);

    registerAlias("map", Map.class);
    registerAlias("hashmap", HashMap.class);
    registerAlias("list", List.class);
    registerAlias("arraylist", ArrayList.class);
    registerAlias("collection", Collection.class);
    registerAlias("iterator", Iterator.class);

    registerAlias("ResultSet", ResultSet.class);
自定义别名

在mybatis配置文件sqlMapConfig.xml配置,注意typeAliases要写在environments标签之前

    <typeAliases>
            <!--声明单个别名 使用时忽略大小写-->
           <!-- <typeAlias type="com.wgz.entity.MiddleStudent" alias="middleStudent"></typeAlias>-->
            <!--扫描包声明别名-->
            <package name="com.wgz.entity"/>
    </typeAliases>
0

使用

        <select id="findStudentListByName" parameterType="string" resultType="Student">
            select  * from  student_tb where  name like '%${value}%'
        </select>
  • 当sql 语句需要参数 时,就要指定对应 参数类型 parameter(基本类型可以不指定),
    当sql语句是查询时 需要指定resultType 增删改返回的的时影响到的行数 不需要指定

7.resultMap 配置结果类型

当实体类中的字段和数据库中的字段不匹配时,我们可以有两种方式解决

  • 1.使用sql语句的 as 修改查询结果的名称
  • 2.使用resultType,可以实现多个sql语句共用
        
	<resultMap id="studentMap" type="student">
            <id property="id" column="id"/>
            <result property="name" column="name"/>
            <result property="sex" column="sex"/>
            <result property="age" column="age"/>
            <result property="height" column="height"/>
            <result property="birthday" column="birthday"/>
            
        </resultMap>

        <select id="findStudentById" parameterType="java.lang.Integer" resultMap="studentMap">
              select * from student_tb where id=#{id}
        </select>
    

说明

为sql语句结果的主键与实体类的映射,property为实体类字段,column为数据表主键字段

为普通sql语句字段实体类的属性映射,property为实体类字段,column为数据表主键字段

resultMap=“studentMap” 使用resultMap作为查询结果

8.SqlMapConfig.xml配置文件

SqlMapConfig.xml 中配置的内容和顺序 ,必须为以下顺序,否则会出现错误

<configuration><!--配置-->
	<properties/><!--属性-->
	<settings/><!--设置-->
	<typeAliases/><!--类型别名--> 
	<typeHandlers/><!--类型处理器--> 
	<objectFactory/><!--对象工厂-->  
	<plugins/><!--插件--> 
	<environments><!--配置环境--> 
		<environment><!--环境变量--> 
		<transactionManager/><!--事务管理器--> 
			<dataSource/><!--数据源--> 
		</environment>
	</environments>
	<databaseidProvider/><!--数据库厂商标识-->  
	<mappers/><!--映射器--> 
</configuration>

properties

使用properties作为数据库资源配置

    <properties resource="jdbc.properties"/>
    
    <typeAliases>
            <!--声明单个别名 使用时忽略大小写-->
           <!-- <typeAlias type="com.wgz.entity.MiddleStudent" alias="middleStudent"></typeAlias>-->
            <!--扫描包声明别名-->
            <package name="com.wgz.entity"/>
    </typeAliases>


    <!--配置mybatis环境-->
    <environments default="mysql">
        <environment id="mysql">
            <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>

jdbc.properties配置文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/szqy08
jdbc.username=root
jdbc.password=123456

typeAliases别名

    
    <typeAliases>
            <!--声明单个别名 使用时忽略大小写-->
           <!-- <typeAlias type="com.wgz.entity.MiddleStudent" alias="middleStudent"></typeAlias>-->
            <!--扫描包声明别名-->
            <package name="com.wgz.entity"/>
    </typeAliases>

mappers映射器配置

    <mappers>
            <!--在map 中声明 映射文件 两种方式  -->
            <!--方式一:resource声明xml-->
          <!--  <mapper resource="com/wgz/dao/IStudentDao.xml"></mapper>-->

            <!--方式二:class 声明类名-->
            <!--<mapper class="com.wgz.dao.IStudentDao"></mapper>-->

    <!--         <mapper class="com.wgz.dao.IStudentDao2"/>
             <mapper class="com.wgz.dao.IMiddleStudentDao"></mapper>-->
          <!--方式三:扫描包名-->
            <package name="com.wgz.dao"/>
    </mappers>

mapUnderscoreToCamelCase 开启驼峰映射

<!-- 开启驼峰映射 ,为自定义的SQL语句服务-->
    <!--设置启用数据库字段下划线映射到java对象的驼峰式命名属性,默认为false
      user_name  ---userName
    -->  
    <settings>
      <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    <!--
      多请求参数时:
      parameterType 可以不写

      参数较少

      findStudentByAgeAndSex(int age,String sex)    配置文件     select  * from  student_tb where  age >= #{arg0} and sex = #{arg1}
                                                                select  * from  student_tb where  age >= #{param1} and sex = #{param2}
      findStudentByAgeAndSex(@Param("age") int age,@Param("sex") String sex);
                                                     配置文件     select  * from  student_tb where  age >= #{age} and sex = #{sex}
      多参数
      1.将参数封装为 实体类
      2.将参数封装为map
      List<Student> findStudentByAgeAndSexMap(Map<String,Object> map);
                                                        配置文件    select * from student_tb where  age >= #{age} and sex = #{sex}
    -->
    <select id="findStudentByAgeAndSex" resultType="student">
        select  * from  student_tb where  age >= #{age} and sex = #{sex}
    </select>


    <select id="findStudentByAgeAndSexMap" resultType="student">

        select * from student_tb where  age >= #{age} and sex = #{sex}
    </select>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值