zoukankan      html  css  js  c++  java
  • mybatis学习日志之总结

    一、介绍mybatis

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

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

      MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Ordinary Java Objects,普通的 Java对象)映射成数据库中的记录。

    二、写一个简单的demo

    1.首先在工程下的lib中导入相应的jar包

    2.先写一个bean的实体类

    public class User {
            private int id;
            private String name;
            private int age;
    }

    3.创建一个UserMapper.xml文件

    <?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">
    <!-- namespace:表示名称空间。现在的目的是区分id的. -->
    <mapper namespace="com.zhiyou100.xz.mapper.UserMapper">
      <!-- 查询年龄在10~30之间的用户
      1、查询条件不在实体类中。参数类型封装到map中。#{参数}===map的键
      2、封装一个实体类。min max
      如果在xml文件中出现了特殊字符?1.使用转义字符<:&lt; 2.CDATA
      -->
      <select id="selectByAge" parameterType="map" resultType="com.zhiyou100.xz.bean.User">
        <![CDATA[select * from users where age>=#{min} and age<=#{max}]]>
      </select>

      <!-- 查询所有 -->
      <select id="selectAll" resultType="com.zhiyou100.xz.bean.User">
        select * from users
      </select>

      <!-- 根据id查询用户。id:标识该标签。
      parameterType:参数类型。可以写 也可以省略
      resultType:返回结果的类型。

      #{id}:类似于EL表达式。 解析id的值
      -->
      <select id="getUser" parameterType="int" resultType="com.zhiyou100.xz.bean.User">
        select * from users where id=#{id}
      </select>
      <!-- $ Preparing:insert into users(name,age) values('吴立琪',18):完成sql拼接。Statement sql注入的缺陷
        如果你传入的为列名或表名时可以使用$
        # insert into users(name,age) values(?,?):防止sql的注入。PreparedStatement
        useGeneratedKeys="true" 表示使用字段生成的key
        keyProperyty:把生产的key赋值到哪个属性上。
      -->
      <insert id="addUser1" parameterType="com.zhiyou100.xz.bean.User" useGeneratedKeys="true" keyProperty="id">
        insert into users(name,age) values(#{name},#{age})
      </insert>
      <!--
        parameterType:表示user类的对象。
        相当于方法:
        public void addUser(User user){
        user.getName();
        user.getAge();
        }
      -->
      <insert id="addUser" parameterType="com.zhiyou100.xz.bean.User">
        insert into users(name,age) values(#{name},#{age})
      </insert>

      <delete id="deleteUser" parameterType="int">
        delete from users where id=#{id}
      </delete>

      <update id="updateUser" parameterType="com.zhiyou100.xz.bean.User">
        update users set name=#{name},age=#{age} where id=#{id}
      </update>
    </mapper>

    4.配置conf.xml文件,并引入数据源db.properties

    <?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>
        <!-- 引入数据源文件 -->
        <properties resource="db.properties"/>
        <!-- 为实体类取别名 -->
        <typeAliases>
            <!-- <typeAlias type="com.zhiyou100.xz.bean.User" alias="u"/> -->
            <!-- 以下方法以该包下的所有类的类名作为别名 -->
            <package name="com.zhiyou100.xz.bean"/> 
        </typeAliases>
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC" />
                <dataSource type="POOLED">
                    <!-- 习惯把数据源的信息放到一个属性文件中,后缀名为.properties -->
                    <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="com/zhiyou100/xz/mapper/UserMapper.xml"/>
        </mappers>
    </configuration>
    #数据源的信息
    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/mybatis
    jdbc.username=root
    jdbc.password=root

    5.在src下加入日志信息文件log4j.properties

    log4j.properties,
    log4j.rootLogger=DEBUG, Console
    #Console
    log4j.appender.Console=org.apache.log4j.ConsoleAppender
    log4j.appender.Console.layout=org.apache.log4j.PatternLayout
    log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
    log4j.logger.java.sql.ResultSet=INFO
    log4j.logger.org.apache=INFO
    log4j.logger.java.sql.Connection=DEBUG
    log4j.logger.java.sql.Statement=DEBUG
    log4j.logger.java.sql.PreparedStatement=DEBUG

    6.测试运行

    package com.test;


    import java.io.Reader;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;

    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.jupiter.api.AfterAll;
    import org.junit.jupiter.api.BeforeAll;
    import org.junit.jupiter.api.Test;

    import com.zhiyou100.xz.bean.User;

    class TestMybatis {
      static SqlSession session=null;
      final String str="com.zhiyou100.xz.mapper.UserMapper";
      @BeforeAll
      static void setUpBeforeClass() throws Exception {
      //解析配置文件conf.xml
      Reader reader=Resources.getResourceAsReader("conf.xml");
      //获取SessionFactory对象
      SqlSessionFactory sessionFactory=new SqlSessionFactoryBuilder().build(reader);

      //获取Session对象,表示jdbc中connection,操作数据库的
      session=sessionFactory.openSession();
      }

      @Test
      void testSelectByAge() {
      Map<String,Integer> map=new HashMap<String,Integer>();
      map.put("min",10);
      map.put("max",30);
      List<User> list=session.selectList(str+".selectByAge",map);
      System.out.println(list);

      }
      @Test
      void testAll() {
      List<User> list=session.selectList(str+".selectAll");
      System.out.println(list);

      }
      @Test
      void testId() {
      User user=session.selectOne(str+".getUser", 1);
      System.out.println(user);

      }
      @Test
      void testAdd() {
      User user=new User("张三",20);
      session.insert(str+".addUser1", user);
      int id=user.getId();//通过user对象中的getId()方法获取添加记录后返回自增列的值
      System.out.println(id);
      }
      @Test
      void testDelete() {
      int row=session.delete(str+".deleteUser", 3);
      System.out.println(row);
      }
      @Test
      void testUpdate() {
      int row=session.update(str+".updateUser", new User(4,"里斯",20));
      System.out.println(row);
      }
      @AfterAll
      static void tearDownAfterClass() throws Exception {
      session.commit();//提交数据
      }

    }

      

    三、优化mybatis

    1.连接数据库的配置单独放在一个properties文件中,如以上2-4中

    2.为实体类定义别名,简化sql映射xml文件中的引用

    <!-- 为实体类取别名 -->
        <typeAliases>
            <!-- <typeAlias type="com.zhiyou100.xz.bean.User" alias="u"/> -->
            <!-- 以下方法以该包下的所有类的类名作为别名 -->
            <package name="com.zhiyou100.xz.bean"/> 
        </typeAliases>

    3.可以在src下加入log4j的配置文件,打印日志信息,如以上的2-5中。

    注意要先添加log4j-1.2.17.jar

    四、接口与映射文件结合使用

    1.创建一个接口,该接口要和映射文件匹配(接口名、接口中的方法)

    public interface UserDao {
         /**
          *  根据id查询
          * @param id
          * @return
          */
        public User getUser(int id);
        /**
         * 添加
         * @param user
         */
        public void addUser(User user);
        /**
         * 删除用户
         * @param id
         */
        public void deleteUser(int id);
        /**
         * 更新用户
         * @param user
         */
        public void updateUser(User user);
        /**
         * 查询年龄在min~max之间的用户 
         * @param min
         * @param max
         * @return
         * @Param:表示告诉mybatis把该方法的参数封装成map时,键名叫什么
         */
        public List<User> selectByAge(@Param("min") int min,@Param("max") int max);   
        //这里默认mybatis把参数封装到所谓的map中,以键值对0,10 1,30 或param1,10 paramm2,30存放,
        //并未以min,max为键名,要用@Param指出键名叫什么
        //第二种方法
        //public List<User> selectByAge(Map<String,Integer> map);
        
    }

    2.映射文件中

    <?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">
    <!-- namespace:表示名称空间。这里的namespace一定要与接口所在的包以及接口的名字一样 -->
    <mapper namespace="com.zhiyou100.xz.dao.UserDao">
        <!-- 这里的id一定要与接口中方法的名字进行对照
         -->
        <select id="getUser" parameterType="int" resultType="com.zhiyou100.xz.bean.User">
              select * from users where id=#{id}   
        </select>
        <!-- 
            parameterType:表示user类的对象。
            相当于方法:
            public void addUser(User user){
                user.getName();
                user.getAge();
            }
         -->
        <insert id="addUser" parameterType="com.zhiyou100.xz.bean.User">
                insert into users(name,age) values(#{name},#{age})
        </insert>
      

        <delete id="deleteUser" parameterType="int">
            delete from users where id=#{id}
        </delete>

        <update id="updateUser" parameterType="com.zhiyou100.xz.bean.User">
            update users set name=#{name},age=#{age} where id=#{id}
        </update>

        <select id="selectByAge" parameterType="map" resultType="com.zhiyou100.xz.bean.User">
            <![CDATA[select * from users where age>=#{min} and age<=#{max}]]>
        </select>

    </mapper>

     3.测试

    import java.io.Reader;
    import java.util.List;
    
    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.jupiter.api.AfterAll;
    import org.junit.jupiter.api.BeforeAll;
    import org.junit.jupiter.api.Test;
    
    import com.zhiyou100.xz.bean.User;
    import com.zhiyou100.xz.dao.UserDao;
    
    class TestMybatis {
        static SqlSession session=null; 
        final String str="com.zhiyou100.xz.mapper.UserMapper";
        static  UserDao userDao;
        @BeforeAll
        static void setUpBeforeClass() throws Exception {
            //解析配置文件conf.xml
                    Reader reader=Resources.getResourceAsReader("conf.xml");
                    //获取SessionFactory对象
                    SqlSessionFactory sessionFactory=new SqlSessionFactoryBuilder().build(reader);
                    
                    //获取Session对象,表示jdbc中connection,操作数据库的
                    session=sessionFactory.openSession();
                    //得到接口的实现类
                    userDao=session.getMapper(UserDao.class);//相当于创建一个Dao对象
        }
    
        @Test
        void testSelectByAge() {
            List<User> list=userDao.selectByAge(10, 30);
            System.out.println(list);
            
        }
        @Test
        void testId1() {
            User user=userDao.getUser(1);
            System.out.println(user);
            
        }
        @Test
        void testAdd() {
            userDao.addUser(new User("孔子",2000));
        }
        @Test
        void testDelete() {
            userDao.deleteUser(5);
            
        }
        @Test
        void testUpdate() {
            userDao.updateUser(new User(6,"孔子",20));
            
        }
        @AfterAll
        static void tearDownAfterClass() throws Exception {
            session.commit();//提交数据   事物管理:要么都执行,要么都不执行
        }
    
    
    }

    五、解决列名与属性名不一致的情况

    1. 解决方案为为查询的字段起别名 要求别名与属性名一致。

    <!-- 这里的id一定要与接口中方法的名字进行对照
         -->
        <select id="selectById" resultType="com.zhiyou100.xz.bean.Order">
              select order_id id,order_no no,order_price price from orders where order_id=#{id}   
        </select> 

    2.使用resultMap标签来定义实体类与字段之间的对应关系

    <!-- resultMap:引用resultMap标签  不能与resultType同时用  -->
        <select id="selectById2" resultMap="myMap">
            select * from orders where order_id=#{id}
        </select>
        
        <!-- resultMap:写属性与字段的对应关系
            type:表示哪个实体类与表的对应关系
         -->
        <resultMap type="com.zhiyou100.xz.bean.Order" id="myMap">
            <!-- id:标签标识表中的主键与实体类的值属性对应关系 -->
            <id column="order_id" property="id"/>
            <result column="order_no" property="no"/>
            <result column="order_price" property="price"/>
        </resultMap>

      

    六、关联查询

    • 多对一或一对一,如一个老师多个班级,利用association标签

    链表查询时

        <!-- resultMap:引用resultMap标签  -->
        <select id="selectById" resultMap="clazzMapper">
            select * from class c,teacher t where c.teacher_id=t.t_id and c_id=#{cid}
        </select>
        
        <!-- resultMap:写属性与字段的对应关系
            type:表示哪个实体类与表的对应关系
         -->
        <resultMap type="com.zhiyou100.xz.bean.Clazz" id="clazzMapper">
            <!-- id:标签标识表中的主键与实体类的值属性对应关系 -->
            <id column="c_id" property="cid"/>
            <result column="c_name" property="cname"/>
            <result column="teacher_id" property="tid"/>
            <!-- 该类中引入的一的一方的属性
                property:属性名
                javaType:该属性的Java类型
             -->
             <!--  链表查询  -->
            <association property="teacher" javaType="com.zhiyou100.xz.bean.Teacher">
                    <id column="t_id" property="tid"/>
                    <result column="t_name" property="tname"/>
            </association>
          </resultMap>         

    嵌套查询时

       <!-- resultMap:写属性与字段的对应关系
            type:表示哪个实体类与表的对应关系
         -->
        <resultMap type="com.zhiyou100.xz.bean.Clazz" id="clazzMapper">
            <!-- id:标签标识表中的主键与实体类的值属性对应关系 -->
            <id column="c_id" property="cid"/>
            <result column="c_name" property="cname"/>
            <result column="teacher_id" property="tid"/>
            <!-- 该类中引入的一的一方的属性
                property:属性名
                javaType:该属性的Java类型
             -->
            <!-- column:外键列
              select="com.zhiyou100.xz.dao.TeacherDao.selectByTeacherId"
           当另建一个TeacherDao时引用的方式   --> <association property="teacher" javaType="com.zhiyou100.xz.bean.Teacher" column="teacher_id" select="selectByTeacherId"> </association> </resultMap> <!-- 以下为嵌套语句 --> <select id="selectById" resultMap="clazzMapper"> select * from class where c_id=#{cid} </select> <select id="selectByTeacherId" resultType="com.zhiyou100.xz.bean.Teacher"> select t_id tid,t_name tname from teacher where t_id=#{tid} </select>
    • 一对多,如一个班级多个学生,利用collection标签
      <!--引用resultMap标签  -->
        <select id="getClazz" parameterType="int" resultMap="clazzMap">
            select * from class c,teacher t,student s where c.teacher_id=t.t_id and c.c_id=s.class_id and c.c_id = #{id}   
        </select>
        
        <!--resultMap:写数学与字段的对应关系
            type:表示哪个实体类与表的对应关系
          -->
        <resultMap type="com.zhiyou100.klb.bean.Clazz" id="clazzMap">
            <!-- ID:表示表中的主键与实体类的属性的对应关系 -->
            <id column="c_id" property="cid"/>
            <result column="c_name" property="cname"/>
            <result column="teacher_id" property="tid"/>
            
            <association property="teacher" javaType="com.zhiyou100.klb.bean.Teacher">
                <id column="t_id" property="tid"/>
                <result column="t_name" property="tname"/>
            </association>
            <!-- ofType:集合中泛型的类型 -->
            <collection property="students" ofType="com.zhiyou100.klb.bean.Student">
                <id column="s_id" property="sid"/>
                <result column="s_name" property="sname"/>
                <result column="class_id" property="cid"/>
            </collection>
        </resultMap>

    七、动态sql语句

    1.if语句

    <select id="selectByWhere1" parameterType="int" resultType="com.zhiyou100.xz.bean.User">
         select * from users  
              <if test="name!=null">
                  where name=#{name}
              </if>
              <if test="sex!=null and sex!=''">
                  and sex=#{sex}
              </if>
    </select>

    2.if+where 语句

    <select id="selectByWhere2"  resultType="com.zhiyou100.xz.bean.User">
                 select * from users 
             <where>
              <if test="name!=null">
                  and name=#{name}
              </if>
              <if test="sex!=null and sex!=''">
                  and sex=#{sex}
              </if>
             </where> 
    </select>

    3. if+set 语句

     <update id="updateUser" parameterType="com.zhiyou100.xz.bean.User">
                 update users
                 <set>
                      <if test="name!=null">
                          name=#{name},
                      </if>
                       <if test="sex!=null and sex!=''">
                          sex=#{sex},
                       </if>
                       <if test="age>0">
                           age=#{age}
                       </if>
                 </set>
                 where id=#{id}
         </update>

    4. choose(when,otherwise) 语句+模糊查询用concat

    <!-- choose+where+otherwise -->
         <select id="selectByWhere3"  resultType="com.zhiyou100.xz.bean.User">
                 select * from users 
             <where>
                 <choose>
                      <when test="name!=null and name!=''">
                          name like concat('%',#{name},'%')
                      </when>
                      <when test="sex!=null and sex!=''">
                          sex=#{sex}
                      </when>
                      <otherwise>
                          age>=#{age}
                      </otherwise>
                  </choose>
             </where> 
         </select>

    5. trim 语句

    <!-- trim 前缀 -->
         <select id="selectByWhere2"  resultType="com.zhiyou100.xz.bean.User">
                 select * from users 
             <trim prefix="where" prefixOverrides="and / or">
                  <if test="name!=null">
                      and name=#{name}
                  </if>
                  <if test="sex!=null and sex!=''">
                      and sex=#{sex}
                  </if>
             </trim> 
         </select>
    <!-- trim 后缀 -->
         <update id="updateUser" parameterType="com.zhiyou100.xz.bean.User">
                 update users
                 <!-- 
                     prefix:把trim中返回的字符串前添加一个set
                     prefixOverrides:覆盖trim中返回的字符串的前缀为and | or
                     suffix:把trim中返回的字符串后添加一个指定字符串
                     suffixOverrides:覆盖trim中返回的字符串的前缀
                  -->
                 <trim prefix="set" suffixOverrides=",">
                      <if test="name!=null">
                          name=#{name},
                      </if>
                       <if test="sex!=null and sex!=''">
                          sex=#{sex},
                       </if>
                       <if test="age>0">
                           age=#{age}
                       </if>
                 </trim>
                 where id=#{id}
         </update>

    6. SQL 片段

    <!-- sql片段  -->
        <sql id="usercolumns">
           id,name,age,sex
        </sql>
    
    <select id="selectByWhere1" parameterType="int" resultType="com.zhiyou100.xz.bean.User">
              select
              <!-- 引用相应的sql片段  -->
              <include refid="usercolumns" /> 
                 from users  
              <if test="name!=null">
                  where name=#{name}
              </if>
              <if test="sex!=null and sex!=''">
                  and sex=#{sex}
              </if>
     </select>

    7. foreach 语句

    <!-- delete from users where id in(?,?,?) -->
         <delete id="deleteByIds">
                 delete from users where id in
                 <!-- 
                     collection:表示要遍历的集合名称
                     open:以(作为开始
                     close:以)作为结束
                     separator:每个元素之间使用,分割
                     item:每次遍历的值赋值给的变量名
                  -->
                 <foreach collection="ids" open="(" close=")" separator="," item="id">
                         #{id}
                 </foreach>
         </delete>
         <!-- delete from users where id=1 or id=4 or id=6 -->
         <delete id="delete">
                 delete from users 
                 <!-- 
                     collection:表示要遍历的集合名称
                     open:以(作为开始
                     close:以)作为结束
                     separator:每个元素之间使用,分割
                     item:每次遍历的值赋值给的变量名
                     这里最好不要在foreach标签中用open="where " 因为当id等于0时,做全表删除时会报错
                  -->
                  <where>
                 <foreach collection="ids"  separator="or" item="id">
                         id=#{id}
                 </foreach>
                 </where>
         </delete>

    八、逆向工程(generator)

      通过前面的学习,在实际开发中,我们基本上能对mybatis应用自如了,但是我们发现了一个问题,所有操作都是围绕着po类,xxxMapper.xml文件,xxxMapper接口等文件来进行的。如果实际开发中数据库的表特别多,那么我们需要手动去写每一张表的po类,xxxMapper.xml,xxxMapper.java文件,这显然需要花费巨大的精力,而且可能由于表字段太多,写错了而不知道也是可能的。

      所以我们在实际开发中,一般使用逆向工程方式来自动生成所需的文件,如dao,bean,xml映射文件 。

     1.新建一个工程并导入jar包

      2.创建generator.xml配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE generatorConfiguration
      PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
      "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
    
    <generatorConfiguration>
        <!-- mysql驱动jar所在的位置 -->
      <classPathEntry location="D:\mysql\mysql-connector-java-5.1.47.jar" />
        
        <!-- 数据源的信息 -->
      <context id="DB2Tables" targetRuntime="MyBatis3">
          <!-- 禁止所有注释 -->
          <commentGenerator>
            <property name="suppressAllComments" value="true" />
        </commentGenerator>
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
            connectionURL="jdbc:mysql://localhost:3306/mybatis"
            userId="root"
            password="root">
        </jdbcConnection>
    
        <javaTypeResolver >
          <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>
        <!-- 生产的实体类所在的位置 -->
        <javaModelGenerator targetPackage="com.zhiyou100.xz.bean" targetProject="./src">
          <property name="enableSubPackages" value="true" />
          <property name="trimStrings" value="true" />
        </javaModelGenerator>
        <!-- 生成的映射文件所在的位置 -->
        <sqlMapGenerator targetPackage="com.zhiyou100.xz.mapper"  targetProject="./resources">
          <property name="enableSubPackages" value="true" />
        </sqlMapGenerator>
        <!-- 生产的dao文件所在位置 -->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.zhiyou100.xz.dao"  targetProject="./src">
          <property name="enableSubPackages" value="true" />
        </javaClientGenerator>
        <!-- 某张表与实体类的对应关系
            schema:该表所在的数据库
            tableName:表名
            domainObjectName:实体类名
         当需要多张表建立实体类时要建立多个table标签
         -->
        <table schema="mybatis" tableName="users" domainObjectName="Users" 
        enableCountByExample="false" enableSelectByExample="false" enableUpdateByExample="false" enableDeleteByExample="false">
        <!--以Example结尾的属性全为false,是为了减少生成复杂的方法 -->
          <property name="useActualColumnNames" value="true"/>
          <generatedKey column="ID" sqlStatement="DB2" identity="true" />
          <columnOverride column="DATE_FIELD" property="startDate" />
          <ignoreColumn column="FRED" />
          <columnOverride column="LONG_VARCHAR_FIELD" jdbcType="VARCHAR" />
        </table>
    
      </context>
    </generatorConfiguration>

    3.运行主程序生成代码

    package com.zhiyou100.xz.test;
    
    import java.io.File;
    import java.util.ArrayList;
    import java.util.List;
    
    import org.mybatis.generator.api.MyBatisGenerator;
    import org.mybatis.generator.config.Configuration;
    import org.mybatis.generator.config.xml.ConfigurationParser;
    import org.mybatis.generator.internal.DefaultShellCallback;
    
    public class Test {
          public static void main(String[] args) throws Exception{
              List<String> warnings = new ArrayList<String>();
               boolean overwrite = true;
               File configFile = new File("generator.xml");
               ConfigurationParser cp = new ConfigurationParser(warnings);
               Configuration config = cp.parseConfiguration(configFile);
               DefaultShellCallback callback = new DefaultShellCallback(overwrite);
               MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
               myBatisGenerator.generate(null);
        }
    }

    九、分页助手(pagehelper)

    1.导入jar包

     2.在mybatis工程下的conf.xml中配置PageHelper的拦截器插件

      <!-- 
        plugins在配置文件中的位置必须符合要求,否则会报错,顺序如下:
        properties?, settings?, 
        typeAliases?, typeHandlers?, 
        objectFactory?,objectWrapperFactory?, 
        plugins?, 
        environments?, databaseIdProvider?, mappers?
        -->
        <plugins>
        <!-- com.github.pagehelper为PageHelper类所在包名 -->
            <plugin interceptor="com.github.pagehelper.PageInterceptor">
                <!-- 使用下面的方式配置参数,后面会有所有的参数介绍 -->
                <property name="param1" value="value1"/>
            </plugin>
        </plugins>

    3.先在UsersMapper.xml中写出查询所有的sql语句

    <resultMap id="BaseResultMap" type="com.zhiyou100.xz.bean.Users">
        <id column="id" jdbcType="INTEGER" property="id" />
        <result column="NAME" jdbcType="VARCHAR" property="NAME" />
        <result column="age" jdbcType="INTEGER" property="age" />
        <result column="sex" jdbcType="VARCHAR" property="sex" />
      </resultMap>
      <sql id="Base_Column_List">
        id, NAME, age, sex
      </sql>
      <!-- 查询所有 -->
      <select id="selectAll" resultMap="BaseResultMap">
              select <include refid="Base_Column_List" /> from users
      </select>

    4.在接口UsersMapper中写 出查询所有的方法

    package com.zhiyou100.xz.dao;
    
    import java.util.List;
    
    import com.zhiyou100.xz.bean.Users;
    
    public interface UsersMapper {    
        //查询所有用户
        List<Users> selectAll();
    }

    5.测试运行

    package com.test;
    import java.io.Reader;
    import java.util.ArrayList;
    import java.util.List;
    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.jupiter.api.AfterAll;
    import org.junit.jupiter.api.BeforeAll;
    import org.junit.jupiter.api.Test;
    import com.github.pagehelper.PageHelper;
    import com.github.pagehelper.PageInfo;
    import com.zhiyou100.xz.bean.Users;
    import com.zhiyou100.xz.dao.UsersMapper;
    class TestMybatis {
        static SqlSession session=null; 
        final String str="com.zhiyou100.xz.mapper.UserMapper";
        static  UsersMapper usersMapper;
        @BeforeAll
        static void setUpBeforeClass() throws Exception {
            //解析配置文件conf.xml
                    Reader reader=Resources.getResourceAsReader("conf.xml");
                    //获取SessionFactory对象
                    SqlSessionFactory sessionFactory=new SqlSessionFactoryBuilder().build(reader);
                    
                    //获取Session对象,表示jdbc中connection,操作数据库的
                    session=sessionFactory.openSession();
                    //得到接口的实现类
                    usersMapper=session.getMapper(UsersMapper.class);//相当于创建一个Dao对象
        }
        @Test
        void testSelectByPage() {
          // 1.使用PageHelper类设置起始页和每页显示的条数
          int pageNum = 3;// 当前的页码 从网页中可以获取
          int pageSize = 2;// pageSize:自定义
          PageHelper.startPage(pageNum, pageSize);
    
          // 2.调用查询所有的方法
          List<Users> list = usersMapper.selectAll();
          System.out.println(list);
          // 3.把查询的結果封裝到pageInfo对象中
          PageInfo<Users> pageInfo = new PageInfo<>(list,3);
          System.out.println(pageInfo);
          //pageInfo.setNavigatePages(2);//setNavigatePages 设置每页显示的页码个数,这里这个属性没起作用
          System.out.println("总页码:"+pageInfo.getPages());
          System.out.println("当前页:"+pageInfo.getPageNum());
          System.out.println("上一页:"+pageInfo.getPrePage());
          int[] pages=pageInfo.getNavigatepageNums();//getNavigatepageNums显示页码的具体页数
          for(int p:pages) {
          System.out.print(p+"	");
          }
          System.out.println("下一页:"+pageInfo.getNextPage());
          List<Users> users=pageInfo.getList();
          for(Users users2:users) {
          System.out.println(users2);
          }
    
        }
        @AfterAll
        static void tearDownAfterClass() throws Exception {
            session.commit();//提交数据   事物管理:要么都执行,要么都不执行
        }
    }

    十、$和#的区别

    #{} 

      使用#{}意味着使用的预编译的语句,即在使用jdbc时的preparedStatement,sql语句中如果存在参数则会使用?作占位符,我们知道这种方式可以防止sql注入,并且在使用#{}时形成的sql语句,已经带有引号,例,select  * from table1 where id=#{id}  在调用这个语句时我们可以通过后台看到打印出的sql为:select * from table1 where id='2' 加入传的值为2.也就是说在组成sql语句的时候把参数默认为字符串。

    ${}

      使用${}时的sql不会当做字符串处理,是什么就是什么,如上边的语句:select * from table1 where id=${id} 在调用这个语句时控制台打印的为:select * from table1 where id=2 ,假设传的参数值为2

      从上边的介绍可以看出这两种方式的区别,我们最好是能用#{}则用它,因为它可以防止sql注入,且是预编译的,在需要原样输出时才使用${},如,

    select * from ${tableName} order by ${id} 这里需要传入表名和按照哪个列进行排序 ,加入传入table1、id 则语句为:select * from table1 order by id

    如果是使用#{} 则变成了select * from 'table1' order by 'id' 我们知道这样就不对了。

      <!-- $ Preparing:insert into users(name,age) values('吴立琪',18):完成sql拼接。Statement sql注入的缺陷
              如果你传入的为列名或表名时可以使用$
              # insert into users(name,age) values(?,?):防止sql的注入。PreparedStatement    -->
      <insert id="addUser" parameterType="com.zhiyou100.xz.bean.User" >
         insert into users(name,age) values(#{name},#{age})
      </insert>

    十一、添加时如何获取添加成功后的主键值

    Mybatis 配置文件 useGeneratedKeys 参数只针对 insert 语句生效,默认为 false。当设置为 true 时,表示如果插入的表以自增列为主键,则允许 JDBC 支持自动生成主键,并可将自动生成的主键返回。keyProperty是与主键对应的Java对象的属性名。

     <!-- 
         useGeneratedKeys="true" 表示使用字段生成的key
         keyProperyty:把生产的key赋值到哪个属性上。
      -->
      <insert id="addUser1" parameterType="com.zhiyou100.xz.bean.User" useGeneratedKeys="true" keyProperty="id">
           insert into users(name,age) values(#{name},#{age})
      </insert>
    @Test
        void testAdd() {
            User user=new User("张三",20);
            session.insert(str+".addUser1", user);
            int id=user.getId();//通过user对象中的getId()方法获取添加记录后返回自增列的值
            System.out.println(id);
        }
  • 相关阅读:
    JSP 072: 处理注册结果样式的显示
    JSP 07: 开发注册页面
    JSP 06: 两个内置对象request和response
    Java Web 01: 什么是http协议
    JSP 05: JSP定义表达式和内容输出表达式
    JSP 04: 如何在JSP页面中书写Java代码
    JSP 03: 创建一个JSP页面并启动运行项目
    Fail 02: Port 8080 required by Tomcat Server at localhost is already in use.
    Fail 03: netstat 不是内部或外部命令
    Build 01: 安装新的JDK
  • 原文地址:https://www.cnblogs.com/sitian2050/p/11439065.html
Copyright © 2011-2022 走看看