MyBatis笔记

来源:互联网 发布:大乐透 简单公式算法 编辑:程序博客网 时间:2024/06/03 21:03

MyBatis第一天笔记

MyBatis介绍

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。 MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatement、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。

MyBatis快速入门

  • 导入 MyBatis jar包
  • 配置 MyBatis 核心配置文件—SqlMapConfig.xml

    <?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration>    <!-- 关联数据库jdbc -->    <properties resource="db.properties"></properties>    <!-- 和spring整合后 environments配置将废除 -->    <environments default="development">        <environment id="development">            <!-- 使用jdbc事务管理 -->            <transactionManager type="JDBC" />            <!-- 数据库连接池 -->            <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></configuration>
  • 配置db.propertis

    jdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/myfirstdb?characterEncoding\=utf-8jdbc.username=rootjdbc.password=root
  • 配置log4j.properties

    # Global logging configurationlog4j.rootLogger=DEBUG, stdout# Console output...log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
  • 创建Bean

    public class User {private Integer id;private String username;private String password;private String sex;
  • 测试

    • 配置bean.xml

      <?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!-- namespace:命名空间,做sql隔离 --><mapper namespace="test"></mapper>
    • 在核心配置文件中添加引用

      <mappers><mapper resource="com/example/batis/domain/User.xml" /></mappers>
  • 测试查询

    • bean.xml中查询的方法

      <select id="selectUserById" resultType="com.example.batis.domain.User"parameterType="int">select * from t_user where id=#{id}</select><select id="selectUser" resultType="user">select * from t_user</select>
    • 定义创建工厂方法

      // 会话工厂private SqlSessionFactory sqlSessionFactory;@Beforepublic void createSqlSessionFactory() throws IOException {    // 配置文件    String resource = "SqlMapConfig.xml";    InputStream inputStream = Resources.getResourceAsStream(resource);    // 使用SqlSessionFactoryBuilder从xml配置文件中创建SqlSessionFactory    sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);}
    • 定义查询单个方法

      @Testpublic void testQuery() {    SqlSession openSession = sqlSessionFactory.openSession();    User user = openSession.selectOne("test.selectUserById", 5);    System.out.println(user.toString());    openSession.close();}
    • 定义查询集合方法

      @Testpublic void testQueryList() {    SqlSession openSession = sqlSessionFactory.openSession();    List<User> user = openSession.selectList("test.selectUser");    for (User user2 : user) {        System.out.println(user2.toString());    }    openSession.close();}
  • 测试添加

    <insert id="saveUser" parameterType="com.example.batis.domain.User">    insert into t_user    (username,password,sex) values(#{username},#{password},#{sex});</insert>@Testpublic void testInsert() {    SqlSession sqlSession = sqlSessionFactory.openSession();    User user = new User("王五", "123", "男");    sqlSession.insert("test.saveUser", user);    sqlSession.commit();    sqlSession.close();}
  • 测试修改

    <update id="updateUser" parameterType="com.example.batis.domain.User">update t_user setusername=#{username},password=#{password},sex=#{sex} where id=#{id}</update>@Testpublic void testUpdate() {SqlSession sqlSession = sqlSessionFactory.openSession();User user = new User("王小九", "1234", "女");user.setId(5);sqlSession.update("test.updateUser", user);sqlSession.commit();sqlSession.close();}
  • 测试删除

    <delete id="deleteUser" parameterType="int" >delete from t_user where id=#{a}</delete>@Testpublic void testDelete() {SqlSession sqlSession = sqlSessionFactory.openSession();sqlSession.delete("test.deleteUser", 1);sqlSession.commit();sqlSession.close();}
  • 测试模糊查询

    <select id="selectUserLike" resultType="user">select * from t_userwhere username like '%${value}%'</select>@Testpublic void testSelectUserLike() throws Exception{    SqlSession sqlSession = sqlSessionFactory.openSession();    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);    User selectUserLike = userMapper.selectUserLike("王");    System.out.println(selectUserLike.toString());}
  • {}和${}区别

    #{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}括号中可以是value或其它名称${}表示拼接sql串${}括号中只能是value。传入的内容拼接在sql中且不进行jdbc类型转换。
  • parameterType:指定输入参数类型

  • resultType:指定输出结果类型

插入数据并获取id

    <insert id="insertUserAndgetKey" parameterType="com.example.pojo.User">    <!--keyProperty 指定查询出的id设置到哪个字段上 resultType 结果类型 order 指定为after LAST_INSERT_ID() -->    <selectKey keyProperty="id" resultType="int" order="AFTER">        select        LAST_INSERT_ID()    </selectKey>    insert into t_user    (username,sex,age) values    (#{username},#{sex},#{age});    </insert>

插入UUID类型的主键

<insert id="insertPersonUUID" parameterType="com.example.pojo.Person">    <!-- 查询出的id对应的字段  order 必须是before  -->    <selectKey keyProperty="id" resultType="string" order="BEFORE">        select        uuid()    </selectKey>    insert into t_person    (id,username,sex,age) values    (#{id},#{username},#{sex},#{age});</insert>

API详细分析及

  • SqlSessionFactoryBuilder

    通过读取配置文件,创建sessionFactoryString resource = "SqlMapConfig.xml";InputStream inputStream = Resources.getResourceAsStream(resource);// 使用SqlSessionFactoryBuilder从xml配置文件中创建SqlSessionFactorysqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  • SqlSessionFactory

    会话工厂,用来创建会话 SqlSession openSession = sqlSessionFactory.openSession();
  • SqlSession

    是一个面向用户的接口, sqlSession中定义了数据库操作方法。每个线程都应该有它自己的SqlSession实例。SqlSession的实例不能共享使用,它也是线程不安全的。因此最佳的范围是方法范围。打开一个 SqlSession;使用完毕就要关闭它。通常把这个关闭操作放到 finally 块中以确保每次都能执行关闭。

Dao类的封装

普通方式Dao封装

  • 定义UserDao

    public interface UserDao {public List<User> queryUser();public User queryUserById();public void saveUser(User user);public void updateUser(User user);public void deleteUser(int id);}
  • 定义UserDaoImpl

    public class UserDaoImpl implements UserDao {private SqlSessionFactory sqlSessionFactory;public UserDaoImpl() {    // 配置文件    try {        String resource = "SqlMapConfig.xml";        InputStream inputStream = Resources.getResourceAsStream(resource);        sqlSessionFactory = new SqlSessionFactoryBuilder()                .build(inputStream);    } catch (IOException e) {        e.printStackTrace();    }}/** * 根据用户id删除用户 */@Overridepublic User queryUserById() {    SqlSession openSession = sqlSessionFactory.openSession();    User user = openSession.selectOne("test.selectUserById", 5);    openSession.close();    return user;}/** * 删除用户 */@Overridepublic void deleteUser(int id) {    SqlSession openSession = sqlSessionFactory.openSession();    int delete = openSession.delete("test.deleteUser", id);    System.out.println(delete);    openSession.commit();    openSession.close();}

动态代理方式封装

  • 编写规范

    Mapper接口开发需要遵循以下规范:1、  Mapper.xml文件中的namespace与mapper接口的类路径相同。2、  Mapper接口方法名和Mapper.xml中定义的每个statement的id相同 3、  Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同4、  Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
  • 配置UserMapper.xml

    <mapper namespace="com.example.batis.dao.UserMapper">其他配置和上述bean一致
  • 创建UserMapper对象

    public interface UserMapper {public List<User> selectUser() throws Exception;public User selectUserById() throws Exception;public void saveUser(User user) throws Exception;public void updateUser(User user) throws Exception;public void deleteUser(int id) throws Exception;}
  • 测试

    @Testpublic void testMapperQuery() throws Exception {    SqlSession sqlSession = sqlSessionFactory.openSession();    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);    List<User> queryUser = userMapper.selectUser();    for (User user : queryUser) {        System.out.println(user.toString());    }}

配置详解

SqlMapConfig.xml中配置的内容和顺序如下:properties(属性)settings(全局配置参数)typeAliases(类型别名)typeHandlers(类型处理器)objectFactory(对象工厂)plugins(插件)environments(环境集合属性对象)environment(环境子属性对象)transactionManager(事务管理)dataSource(数据源)mappers(映射器)
  • properties 关联properties文件

    <properties resource="db.properties"/>MyBatis 将按照下面的顺序来加载属性:在 properties 元素体内定义的属性首先被读取。 然后会读取properties 元素中resource或 url 加载的属性,它会覆盖已读取的同名属性。 
  • typeAliases(类型别名)

    别名  映射的类型_byte       byte _long       long _short      short _int        int _integer    int _double     double _float      float _boolean    boolean string      String byte        Byte long        Long short       Short int         Integer integer     Integer double      Double float       Float boolean     Boolean date        Date decimal     BigDecimal bigdecimal  BigDecimal map         Map
    • 配置自定义别名

      指定具体的类<typeAlias type="com.example.batis.domain.User" alias="user" />指定包名,会扫描所有的bean类,别名以类名大小写定义即可<package name="com.example.batis.domain" />
  • mappers

    • 使用相对于类路径的资源

      <mapper resource="com/example/batis/dao/UserMapper.xml" />
    • 类路径

      <mapper class="com.example.batis.dao.UserMapper" />此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。
    • 包路径

      <package name="com.example.batis.dao" />

输入映射和输出映射

  • 普通方式输入映射

    回顾上午内容
  • vo方式输入映射 VO value Object

    • 定义vo对象,用来放置输入的数据

      public class QueryVO {User user;public void setUser(User user) {    this.user = user;}public User getUser() {    return user;}}
    • mapper.xml中

      <select id="getUserByUserNameAndSex" resultType="user"    parameterType="com.example.mybatis.domain.QueryVO">    select * from t_user where username=#{user.username}    and sex=#{user.sex}</select>
    • 测试类中

      @Testpublic void testQueryVO() {    SqlSession sqlSession = sqlSessionFactory.openSession();    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);    QueryVO queryVO = new QueryVO();    User user = new User();    user.setUsername("王小九");    user.setSex("女");    queryVO.setUser(user);    List<User> selectUserLike = userMapper.getUserByUserNameAndSex(queryVO);    for (User user2 : selectUserLike) {        System.out.println(user2);    }}
  • 输出映射

    • 普通方式输出映射

      回顾知识
    • resultMap类型数据

      特点:当列和字段不一致时,可以指定列和字段的对应关系<select id="getUserListResultMap" resultMap="userListResultMap">select id    _id,username _username,password _password,sex _sex from t_user</select>       如果返回类型配置为 resultType="user",由于查询出来的column列名称不能和user中字段名名称对应,会导致出现错误指定对象和数据库列的映射关系<resultMap type="user" id="userListResultMap">    <id column="_id" property="id" />    <result column="_username" property="username" />    <result column="_password" property="password" />    <result column="_sex" property="password" /></resultMap>

动态SQL

通过mybatis提供的各种标签方法实现动态拼接sql。
  • if 条件判断某些语句添加或者不添加

  • 案例:多条件查询

    • 回顾JDBC代码写法:

      String sql="select * from t_user where 1=1";if(user.getUsername()!=null&&user.getUsername()!=""){    sql=sql+"and username like "+user.getUsername();}if(user.getSex()!=null&&user.getSex()!=""){    sql=sql+"and sex=" +user.getSex();}
    • mybatis中mapper.xml中配置

      <select id="getConditionUser" resultType="user" parameterType="user">    select * from t_user where 1=1    <if test="username!=null and username!=''">    and username like '%${username}%'    </if>    <if test="sex!=null and sex!=''">    and sex=#{sex}    </if></select>
  • where 代替sql中的where

        <select id="getConditionUser" resultType="user" parameterType="user">            select * from t_user        <where>            <if test="username!=null and username!=''">                and username like '%${username}%'            </if>            <if test="sex!=null and sex!=''">                    and sex=#{sex}            </if>        </where>    </select>
  • foreach 用法 通过遍历方式映射参数

    • xml中写法

          <select id="getUserByIds"   parameterType="com.example.mybatis.domain.QueryVO"        resultType="user">        select * from t_user where 1=1        <foreach collection="ids" open="and id in(" close=")"            separator="," item="id">            #{id}        </foreach>    </select>    * 参数名称     collection 代表集合     open 代表开始sql语句    close 代表sql结束    seperator代表分割符    item 代表集合遍历过程中的对象
    • QueryVO中定义

      public class QueryVO {public List<Integer> ids;public List<Integer> getIds() {        return ids;}public void setIds(List<Integer> ids) {        this.ids = ids;}
    • 测试代码

      @Testpublic void testForeach() {    SqlSession sqlSession = sqlSessionFactory.openSession();    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);    QueryVO queryVO=new QueryVO();    List<Integer> ids=new ArrayList<Integer>();    ids.add(1);    ids.add(3);    queryVO.setIds(ids);    List<User> userByIds = userMapper.getUserByIds(queryVO);    for (User user : userByIds) {        System.out.println(user.toString());    }}

Eclipse jsp报错

  • 项目右击 — buildPath – ConfigBuildPath –Libary – add Libary –server runtime

    jiyunhead@usian.cn

    8.9号开大会

    8.15号光耀学院工作总结会