MyBatis学习笔记(01)

MyBatis学习总结大全:
- MyBatis学习总结第一天
- MyBatis学习总结第二天
- MyBatis学习总结第三天

今日大纲

  1. MyBatis的CRUD
  2. Mybatis的传值
  3. Mybatis的其他标签使用

1.Mybatis的CRUD

1.1、UPDATE

<!-- 修改数据 
        使用update语句,id:必要属性,随便写,但要保证在改xml文件是唯一
        没有返回值:因为更新语句,它的返回值是影响的行数,所以不需要设置resultType
    -->
    <update id="updateUser" >
        update t_user set pwd=#{pwd} where id=#{id}
    </update>

实现:

/**
     * 
     * @Description:有参数的数据传递   
     * @author 
     * @throws IOException 
     * @date   2017年10月27日
     */
    @Test
    public void updateUser1() throws IOException{
        Reader re  = Resources.getResourceAsReader("mybatis.cfg.xml");

        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(re);

        SqlSession openSession = build.openSession();
        /**
         * 第一个参数: statement id
         * 第二个参数:要传递的参数对象
         * 
         * 
         */
//      User user  = new User();
//      user.setPwd("jkl");
//      user.setId(1001);

        Map<String, Object> user= new HashMap<>();

        user.put("pwd", "zxc");
        user.put("id", 1001);

        int update = openSession.update("updateUser", user);

        openSession.commit();
        System.out.println(update);

        openSession.close();
    }

删除语句

<!-- 删除一个用户 -->
    <delete id="deleteUserById">
        delete from t_user where id= #{id}
    </delete>

实现:

/**
     * 
     * @Description:  删除
     * @throws IOException 
     * @author mao
     * @date   2017年10月27日
     */
    @Test
    public void deleteUsesr() throws IOException{
        Reader re  = Resources.getResourceAsReader("mybatis.cfg.xml");

        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(re);

        SqlSession openSession = build.openSession();
        /**
         * 参数传递:
         *  1.对象类型
         *  2.map集合类型
         *  3.简单类型
         */
//      User user = new User();
//      user.setId(1004);
//      Map<String, Object> user = new HashMap<>();
//      user.put("id", 1005);
        /**
         * delete():
         * 第一个参数:statement id
         * 第二参数: statement需要的参数
         * 返回值是影响的行数
         */
        int delete = openSession.delete("deleteUserById", 1006);

        System.out.println(delete);
        openSession.commit();
        openSession.close();
    }

添加
MYSQL的新增,通过主键自增


    <!-- 主键自增的添加用户 
        使用mysql的主键自增,不需要添加主键,在往数据库添加数据的时候,mysql会自动生成主键
        useGeneratedKeys="true":
            表示的如果访问的数据,有主键自增,就执行主键自增,没有就不执行,默认是开启的
            true:开启主键自增
            false:关闭主键自增
    -->
    <insert id="saveUser1">
        <!-- selectKey用于拿到主键信息 
            keyColumn:对应的数据库表主键信息.
                    例如:用户表:主键是id ==》keyColumn="id"
                        书籍表:主键是book_id ==> keyColumn="book_id"
            keyProperty:数据表对应的对象中表示主键的属性
                    例如:用户表:主键是id ==》对象是主键属性是id==》keyProperty="id"
                        书籍表:主键是book_id ==> 对象是主键属性是bookId==》keyProperty="bookId"
            resultType:返回值类型,需要写成对象的全路径
            order:
                BEFORE:是在insert语句执行之前,获取主键值
                AFTER:是在insert语句执行之后,获取主键值

            SELECT @@identity as id :是mysql获取主键的方式,是将主键信息赋值给对象属性 
                @@identity它与主键信息对应不上,所以 给它一个别名,as idid对应的属性
            获取主键值=》主键字段=》对象的属性
        -->
        <selectKey keyColumn="id" keyProperty="id" 
                    resultType="java.lang.Integer" order="AFTER">
            SELECT @@identity as id
        </selectKey>
        insert into t_user(name,pwd,age)
            values(#{name},#{pwd},#{age})
    </insert>

Oracle的新增,通过序列新增

    <!--

        oracle 新增 
        oracle 是通过序列进行主键生成的,
        oracle新增需要写主键值
    -->
    <insert id="saveUser2" >
        <!-- 
            test.currval :序列当前值
            test.nextVal:序列下一个值
            order="AFTER":在insert之后获取值,
                    使用test.currval来获取,在insert语句中是test.nextVal来添加值
            order="BEFORE":在insert之前获取值
                    使用test.nextVal来获取,在insert语句中是test.currval来添加值
         -->
        <selectKey keyColumn="id" keyProperty="id" resultType="java.lang.Integer" 
            order="AFTER">
            select test.currval from dual
        </selectKey>
        insert into t_user(id,name,pwd,age)
            values(test.nextVal,#{name},#{pwd},#{age})
    </insert>

查询

    <!-- 查询所有数据 -->
    <select id="getUsers" resultType="user">
        select * from t_user 
    </select>
    <!-- 根据id进行查询 -->
    <select id="getUserById" resultType="user">

        select * from t_user where id= #{id}
    </select>
    <!-- 返回map集合查询 -->
    <select id="getUserForMap" resultType="user">
        select * from t_user where id=#{id}
    </select>
    <!-- 模糊查询 -->
    <select id="getUserByName" resultType="user">
        select * from t_user where name like #{name}
    </select>
    <!-- 模糊查询的第二种方式  oracle-->
    <select id="getUserByName1" resultType="user">
        select * from t_user where name like '%'||#{name}||'%'
    </select>   
    <!-- 模糊查询的第二种方式  mysql
        concat:mysql是字符串拼接
        concat(参数无数个):参数是可以无数个,以,分割,mysql将这个字符进行自动拼接
    -->
    <select id="getUserByName2" resultType="User">
        select * from t_user where name like concat('%',#{name},'%')
    </select>   
    <!-- 分页查询 
        mysql:分页使用函数limit,两个参数与mybatis需要提供的两个参数是一样的
    -->
    <select id="getUserForPage" resultType="user">
        select * from t_user limit #{page},#{size}
    </select>

实现:

/**
 * 
* @ClassName:TestSelect
* @Description:查询
* @Company: 北京尚学堂科技有限公司 www.bjsxt.com
* @author mao
* @date 2017年10月27日
 */
public class TestSelect {
    /**
     * @Before|@After它俩是junit的注解
     * @Before:在执行@Test注解方法之前执行
     * 
     * @After:在执行@Test注解方法之后执行
     */
    private SqlSession session;
    /**
     * 
     * @Description:获取session   
     * @author mao
     * @date   2017年10月27日
     */
    @Before
    public void getSession(){
        session = MybatisUtil.getSession();
    }
    /**
     * 
     * @Description:物理分页   
     * 要多少条数据,就查询多少条数据,不会产生数据冗余,但是它增加数据库访问次数
     * 企业中,大部分使用的是物理分页
     * @author mao
     * @date   2017年10月27日
     */
    @Test
    public void getUserForPage1(){
        int page = 3; //要显示第几页
        int size = 3; //每页显示多少条
        Map<String, Object> map = new HashMap<>();
        map.put("page", (page-1)*size);
        map.put("size", size);
        List<User> selectList = session.selectList("getUserForPage",map);
        for (User user : selectList) {
            System.out.println(user);
        }

    }

    /**
     * 
     * @Description: 逻辑分页查询
     *  第一种方式:使用mybatis提供的分页查询  
     *      他逻辑查询,它一次查询出最大下标+1值,它会产生数据冗余,导致内容压力大
     * @author mao
     * @date   2017年10月27日
     */
    @Test
    public void getUserByPage(){
        /**
         * 第一个参数:statement id
         * 第二个参数:statement所需要的参数
         * 第三个参数:mybatis提供的分页查询类
         */
        /**
         * RowBounds:mybatis提供的分页查询类,
         * offset:数据开始查询的下标
         * limit:一次要查询多少条
         */
        int page = 3; //要显示第几页
        int size = 3; //每页显示多少条
        RowBounds rows = new RowBounds((page-1)*size, size);
        List<User> selectList = session.selectList("getUsers", null, rows);
        for (User user : selectList) {
            System.out.println(user);
        }
    }

    /**
     * 
     * @Description:查询所有数据   
     * @author mao
     * @date   2017年10月27日
     */
    @Test
    public void getUsers(){
        List<User> selectList = session.selectList("getUsers");
        for (User user : selectList) {
            System.out.println(user);
        }
    }

    /**
     * 根据主键查询用户
     */
    @Test
    public void getUserById(){

        User selectOne = session.selectOne("getUserById", 2101);
        System.out.println(selectOne);
    }

    /**
     * 
     * @Description:根据主键查询数据,返回为map集合   
     * @author mao
     * @date   2017年10月27日
     */
    @Test
    public void getUserForMap(){
        User user  = new User();
        user.setId(2101);
        /**
         * selectMap:
         * 第一个参数:statement id
         * 第二个参数: statement 需要的参数
         * 第三个参数:map 的 key值
         * 
         * key值的类型:与第三个参数的类型一致
         * value值的类型:与resultType的值一致
         */
        Map<Integer, User> selectMap = session.selectMap("getUserForMap",user, "id" );
        System.out.println(selectMap);
    }

    /**
     * 
     * @Description: 模糊查询  
     *  如果是手写的%%,不需要自己手写单引号,mybatis的会自动的进行补充
     * @author mao
     * @date   2017年10月27日
     */
    @Test
    public void getUserByName(){
        /**
         * 模糊查询的第一种方式:适合oracle和mysql
         */
//      List<User> selectList = session.selectList("getUserByName", "%张%");
//      for (User user : selectList) {
//          System.out.println(user);
//      }
        /**
         * 模糊查询的第二种方式 oracle
         */
//      List<User> selectList2 = session.selectList("getUserByName1", "张");
//      for (User user : selectList2) {
//          System.out.println(user);
//      }
        /**
         * 模糊查询第二种方式 mysql的
         */
        List<User> selectList = session.selectList("getUserByName2", "张");
        for (User user : selectList) {
            System.out.println(user);
        }

    }




    /**
     * 
     * @Description:关闭session   
     * @author mao
     * @date   2017年10月27日
     */
    @After
    public void closeSession(){

        MybatisUtil.closeSession();

    }
}

占位符 #{}

    <!-- 修改数据 
        使用update语句,id:必要属性,随便写,但要保证在改xml文件是唯一
        没有返回值:因为更新语句,它的返回值是影响的行数,所以不需要设置resultType
    -->
    <update id="updateUser" >
        update t_user set pwd=#{pwd} where id=#{id}
    </update>

参数传递
简单数据类型:
简单类型传递参数一般我们指的是:int\integer\string\long等类型,传递的参数类型要与statement的形参要求的类型一致。

    /**
     * 
     * @Description:  删除
     * @throws IOException 
     * @author mao
     * @date   2017年10月27日
     */
    @Test
    public void deleteUsesr() throws IOException{
        Reader re  = Resources.getResourceAsReader("mybatis.cfg.xml");

        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(re);

        SqlSession openSession = build.openSession();
        /**
         * 参数传递:
         *  1.对象类型
         *  2.map集合类型
         *  3.简单类型
         */
//      User user = new User();
//      user.setId(1004);
//      Map<String, Object> user = new HashMap<>();
//      user.put("id", 1005);
        /**
         * delete():
         * 第一个参数:statement id
         * 第二参数: statement需要的参数
         * 返回值是影响的行数
         */
        int delete = openSession.delete("deleteUserById", 1006);

        System.out.println(delete);
        openSession.commit();
        openSession.close();
    }

对象类型
如果使用对象类型传递参数,对象中的属性要生成getter/setter方法,而且要保证占位符的形参在对象的属性中

    /**
     * 
     * @Description:有参数的数据传递   
     * @author mao
     * @throws IOException 
     * @date   2017年10月27日
     */
    @Test
    public void updateUser1() throws IOException{
        Reader re  = Resources.getResourceAsReader("mybatis.cfg.xml");

        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(re);

        SqlSession openSession = build.openSession();
        /**
         * 第一个参数: statement id
         * 第二个参数:要传递的参数对象
         * 
         * 
         */
        User user  = new User();
        user.setPwd("jkl");
        user.setId(1001);


        int update = openSession.update("updateUser", user);

        openSession.commit();
        System.out.println(update);

        openSession.close();
    }

map集合类型
如果使用map集合传递参数,map集合中的key要与参数名称一致,要不找不到参数。

/**
     * 
     * @Description:有参数的数据传递   
     * @author mao
     * @throws IOException 
     * @date   2017年10月27日
     */
    @Test
    public void updateUser1() throws IOException{
        Reader re  = Resources.getResourceAsReader("mybatis.cfg.xml");

        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(re);

        SqlSession openSession = build.openSession();
        /**
         * 第一个参数: statement id
         * 第二个参数:要传递的参数对象
         * 
         * 
         */
//      User user  = new User();
//      user.setPwd("jkl");
//      user.setId(1001);

        Map<String, Object> user= new HashMap<>();

        user.put("pwd", "zxc");
        user.put("id", 1001);

        int update = openSession.update("updateUser", user);

        openSession.commit();
        System.out.println(update);

        openSession.close();
    }

参数传递总结:

简单类型参数传递    只需要传递一个参数的时候,保证类型相对应
对象类型    传递的参数在对象的属性中都存在的时候
Map集合类型 当参数是多个而且与对象的属性不匹配的时候

拼接符 ${}
Select * from t_user 该sql语句,如果查询字段、表、排序无法确认,而且会随着业务的变更而改变,我们的占位符就不能满足需求,所有需要使用拼接符,但是使用拼接符容易产生注入攻击。

    <!-- 使用拼接符 
    -->
    <select id="getUsers" resultType="user" >
        select ${column} from ${table} order by #{order}
    </select>
    <select id="getUsers1" resultType="user" >
        select ${column}
    </select>
    <select id="getUsers2" resultType="user" >
        select ${name}
    </select>

对象类型

    /**
     * 
     * @Description: 拼接符 使用对象进行传值  
     * @author mao
     * @date   2017年10月27日
     */
    @Test
    public void getUsers2(){
        User user1 = new User();
        user1.setName("name,pwd from t_user where id=100 order by name desc");
        List<User> selectList = session.selectList("getUsers2", user1);
        for (User user : selectList) {
            System.out.println(user);
        }
    }

map集合类型

    /**
     * 
     * @Description:拼接符   
     * @author mao
     * @date   2017年10月27日
     */
    @Test
    public void getUsers(){
        Map<String, Object> map = new HashMap<>();
        map.put("column", "name,pwd");
        map.put("table", "t_user where id=100 ");
        map.put("order", "name desc");
        List<User> selectList = session.selectList("getUsers", map);
        for (User user : selectList) {
            System.out.println(user);
        }
    }
    /**
     * 
     * @Description:拼接符   
     * @author mao
     * @date   2017年10月27日
     */
    @Test
    public void getUsers1(){
        Map<String, Object> map = new HashMap<>();
        map.put("column", "name,pwd from t_user where id=100 order by name desc");
        List<User> selectList = session.selectList("getUsers1", map);
        for (User user : selectList) {
            System.out.println(user);
        }
    }

MyBitis工具类

package com.bjsxt.utils;

import java.io.IOException;
import java.io.Reader;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

/**
 * 
* @ClassName:MybatisUtil
* @Description:mybatis的工具类
* @Company: 北京尚学堂科技有限公司 www.bjsxt.com
* @author mao
* @date 2017年10月27日
 */
public class MybatisUtil {

    private static String CONFIG_FILE = "mybatis.cfg.xml";

    private static Reader re = null;

    private static SqlSessionFactory sqlSessionFactory = null;
    /**
     * ThreadLocal:本地线程安全的
     */
    private static ThreadLocal<SqlSession> th = new ThreadLocal<>();

    static{
        try {
            re = Resources.getResourceAsReader(CONFIG_FILE);
        } catch (IOException e) {
            e.printStackTrace();
            System.err.println("mybatis的核心配置文件读取失败!");
        }
        try {
            //sqlSessionFactory有可能初始不了
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(re);
        } catch (Exception e) {

            e.printStackTrace();
            System.err.println("mybatis的sqlSessionFactory初始化失败!");
        }
    }

    /**
     * 提供私有的构造方法,就是防止人为new对象
     * User user = new User();
     */
    private MybatisUtil(){

    }
    /**
     * 
     * @Description:获取一次与数据库的会话  
     * @return 
     * @author mao
     * @date   2017年10月27日
     */
    public static SqlSession getSession(){
        //当线程没有sqlsession,就通过sqlSessionFactory来获取sqlsession,并放到threadlocal里
        if(th.get()==null){
            th.set(sqlSessionFactory.openSession());
        }
        //th.get() 返回sqlsession
        return th.get();
    }
    /**
     * 
     * @Description:关闭session   
     * @author mao
     * @date   2017年10月27日
     */
    public static void closeSession(){

        if(th.get() != null){
            //关闭session
            th.get().close();
            //清空threadlocal中的sqlsession
            th.set(null);
        }
    }
}

日志

asm-3.3.1.jar
cglib-2.2.2.jar   --类的代理
commons-logging-1.1.1.jar  --日志的工具类
javassist-3.17.1-GA.jar --
log4j-1.2.17.jar –-日志log4j的包  log for java –》log4j
log4j-api-2.0-rc1.jar–-日志log4j的包
log4j-core-2.0-rc1.jar–-日志log4j的包
mybatis-3.2.7.jar –mybatis的包
mysql-connector-java-5.1.30.jar –mysql的驱动包
ojdbc6.jar –oracle驱动包
slf4j-api-1.7.5.jar –日志的包
slf4j-log4j12-1.7.5.jar –日志的包

#根的概念,它表示日志数据的级别:info、默认使用的是info
#以什么样的形式输出:
#ServerDailyRollingFile:一天产生一个日志文件
#stdout:控制台输出
#file:日志文件
log4j.rootLogger=info, ServerDailyRollingFile, stdout 
//日志输出标准,以什么资源来输出 
log4j.appender.ServerDailyRollingFile=org.apache.log4j.DailyRollingFileAppender 
//日志文件,以什么形式结尾或者是文件的后缀名
log4j.appender.ServerDailyRollingFile.DatePattern='.'yyyy-MM-dd 
//日志文件的存放位置
log4j.appender.ServerDailyRollingFile.File=C://logs/notify-subscription.log 
//日志文件的输出的布局
log4j.appender.ServerDailyRollingFile.layout=org.apache.log4j.PatternLayout 
//日志文件的数据的格式
log4j.appender.ServerDailyRollingFile.layout.ConversionPattern=%d - %m%n 
//后面可以继续添加内容
log4j.appender.ServerDailyRollingFile.Append=true
//=====================================================
//控制台的输出
//日志输出标准,以什么资源来输出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender 
//日志文件的输出的布局
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 
//日志文件的数据的格式
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %p [%c] %m%n


#namespace
#log4j.logger.com.bjsxt.mapper.UserMapper=TRACE
#bao
log4j.logger.com.bjsxt.mapper=TRACE
#lei jibie
#log4j.logger.com.bjsxt.mapper.UserMapper=TRACE
#fangfa jibie
#log4j.logger.com.bjsxt.mapper.UserMapper.getUsers=TRACE


log4j定义了8个级别的log(除去OFF和ALL,可以说分为6个级别),
优先级从高到低依次为:OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、 ALL。

ALL 最低等级的,用于打开所有日志记录。

TRACE designates finer-grained informational events than the DEBUG.Since:1.2.12,
很低的日志级别,一般不会使用。开发的时候使用

DEBUG 指出细粒度信息事件对调试应用程序是非常有帮助的,
主要用于开发过程中打印一些运行信息。

INFO 消息在粗粒度级别上突出强调应用程序的运行过程。
打印一些你感兴趣的或者重要的信息,这个可以用于生产环境中输出程序运行的一些重要信息,
但是不能滥用,避免打印过多的日志。

WARN 表明会出现潜在错误的情形,有些信息不是错误信息,但是也要给程序员的一些提示。

ERROR 指出虽然发生错误事件,但仍然不影响系统的继续运行。打印错误和异常信息,如果不想输出太多的日志,可以使用这个级别。

FATAL 指出每个严重的错误事件将会导致应用程序的退出。这个级别比较高了。
重大错误,这种级别你可以直接停止程序了。

OFF 最高等级的,用于关闭所有日志记录。

OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、 ALL。
如果将log level设置在某一个级别上,那么比此级别优先级高的log都能打印出来。
例如,如果设置优先级为WARN,那么OFF、FATAL、ERROR、WARN 4个级别的log能正常输出,
而INFO、DEBUG、TRACE、 ALL级别的log则会被忽略。
Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。

从我们实验的结果可以看出,log4j默认的优先级为ERROR或者WARN(实际上是ERROR)。


Mybatis的核心配置 文件的其他标签:

<!-- mybatis提供了一个标签来读取properties文件 
    -->
    <properties resource="db.properties"></properties>
    <!-- 开启日志
         日志:记录系统运行的结果,可以以文件的形式进行保存,保存到本地磁盘中
         1.导入jar包
         2.在settings中添加日志开启
         3.添加日志的properties文件
     -->
    <settings>
        <setting name="logImpl" value="LOG4J"/>
    </settings>

    <!-- 别名
        将一个长路径 ,起一个别名称
        typeAlias:一个对象别名,
            type:指的是对象的全路径
            alias:别名
        package:包,它指的是,将包下面的所有对象都进行别名
            别名的方式就是类的名称,不区分大小写
        mybatis已经提供的了一系列的别名设置
     -->
    <typeAliases>
        <!-- <typeAlias type="com.bjsxt.pojo.User" alias="user"/> -->
        <package name="com.bjsxt.pojo"/>
    </typeAliases>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Anguser

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值