• mybatis学习日志一


     Mybatis 介绍

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

    使用步骤:

    一、加入相关的jar包

    mybatis-3.2.2.jar

    mysql-connector-java-5.1.47.jar

    二、创建相应的实体类bean

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

    三、创建mybatis的配置文件

    <?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="development">
            <environment id="development">
                <transactionManager type="JDBC" />
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver" />
                    <property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
                    <property name="username" value="root" />
                    <property name="password" value="root" />
                </dataSource>
            </environment>
        </environments>
        
    </configuration>

    四、创建mybatis的映射文件

    <?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">
      <!-- 查询所有 -->
      <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>
      <!--
      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>

    五、mybatis的映射文件要引入到配置文件中

    <!--   把映射文件引入到配置文件中 -->
        <mappers>
            <mapper resource="com/zhiyou100/xz/mapper/UserMapper.xml"/>
        </mappers>

    六、测试

    public class Test {
        //测试根据id查询用户
        public static void main(String[] args) throws Exception {
            //解析配置文件conf.xml
            Reader reader=Resources.getResourceAsReader("conf.xml");
            //获取SessionFactory对象
            SqlSessionFactory sessionFactory=new SqlSessionFactoryBuilder().build(reader);
            
            //获取Session对象,表示jdbc中connection,操作数据库的
            SqlSession session=sessionFactory.openSession();
            //getUser是为了得到select中的sql语句
            //映射sql的标识字符串
            User user=session.selectOne("com.zhiyou100.xz.mapper.UserMapper.getUser", 1);
            System.out.println(user);
        }
    
    }

    七、优化

      1.如果映射文件中的查询条件有多个,则可以使用Map集合作为参数

    <!-- 查询年龄在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>

      2.将属性文件单独列出db.recourses,需要将属性文件导入Mybatis配置文件中,之后使用${}

    <!-- 引入数据源文件 -->
        <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> 

      3.为实体类起别名,为包下所有类起别名,别名为类名(不建议使用,不方便别人解读代码)

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

      4.加入日志信息log4j.properties,方便我们查错,步骤如下:

      把jar包引入;

      引入日志文件: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

    八、使用接口结合xml文件:

      1.创建一个接口,该接口要和映射文件匹配。方法名=ID名

    public interface UserDao {
         /**
          *  根据id查询
          * @param id
          * @return
          */
        public User getUser(int id);
    }
    <?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>
    </mapper>

      2.映射文件中,命名空间要与映射文件路径一直,例如:com.zhiyou100.klb.dao.UserDao,如上图

      3.测试程序运行状况,在junit下创建TestMybatis

    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.在SQL语句中为字段起别名,别名与类的属性名一致

      2.利用resultMap  

    <?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.ClazzDao">
        
        <!-- 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>
            -->
            <association property="teacher" javaType="com.zhiyou100.xz.bean.Teacher">
                    <id column="t_id" property="tid"/>
                    <result column="t_name" property="tname"/>
            </association>
            <!-- ofType:集合中泛型的类型 -->
            <collection property="students" ofType="com.zhiyou100.xz.bean.Student">
                    <id property="sid" column="s_id"/>
                    <result property="sname" column="s_name"/>
            </collection>
            
            <!-- column:外键列
            select="selectByTeacherId"
             -->
             <!-- 嵌套查询
            <association property="teacher" javaType="com.zhiyou100.xz.bean.Teacher"
                column="teacher_id" select="com.zhiyou100.xz.dao.TeacherDao.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>
        -->
        <select id="selectById2" resultMap="clazzMapper">
            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=#{cid}
        </select>
    </mapper>

    十、Mybatis中${ }和#{ }的区别

    1. $: 解析时不会为内容添加”” 它是sql语句的拼接存在sql注入的危害。传入的为表结构时
     <!-- $ 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>
    1. #: 解析时会为内容添加””,它的sql是采用占位符,防止sql注入。

    十一、添加对象时如何返回ID

    <!-- 
         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);
        }
  • 相关阅读:
    JAVA WEB开发环境与搭建
    计科院静态网页
    Python操作MySQL数据库的三种方法
    Appium环境搭建
    webstorm 默认代码格式化更改,webstorm设置prettier规则
    appium自动化环境搭建
    从事算法设计应当熟悉的资源
    redhat6如何配置本地yum源
    Windows命令查看活动连接及根据PID查看运行程序的路径、程序名等
    Tomcat与JavaWeb技术详解
  • 原文地址:https://www.cnblogs.com/sitian2050/p/11432529.html
Copyright © 2020-2023  润新知