zoukankan      html  css  js  c++  java
  • Mybatis-Lesson1

    http://www.mybatis.cn/

    这个网站的内容很有意思,值得收藏!

    MyBatis原名iBatis

    2010年从Apache迁移到了Google


    原来的JDBC存在的毛病

    SET FOREIGN_KEY_CHECKS=0;
    
    -- ----------------------------
    -- Table structure for `orders`
    -- ----------------------------
    DROP TABLE IF EXISTS `orders`;
    CREATE TABLE `orders` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `user_id` int(11) NOT NULL COMMENT '下单用户id',
      `number` varchar(32) NOT NULL COMMENT '订单号',
      `createtime` datetime NOT NULL COMMENT '创建订单时间',
      `note` varchar(100) DEFAULT NULL COMMENT '备注',
      PRIMARY KEY (`id`),
      KEY `FK_orders_1` (`user_id`),
      CONSTRAINT `FK_orders_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
    ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of orders
    -- ----------------------------
    INSERT INTO `orders` VALUES ('3', '1', '1000010', '2015-02-04 13:22:35', null);
    INSERT INTO `orders` VALUES ('4', '1', '1000011', '2015-02-03 13:22:41', null);
    INSERT INTO `orders` VALUES ('5', '10', '1000012', '2015-02-12 16:13:23', null);
    
    -- ----------------------------
    -- Table structure for `user`
    -- ----------------------------
    DROP TABLE IF EXISTS `user`;
    CREATE TABLE `user` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `username` varchar(32) NOT NULL COMMENT '用户名称',
      `birthday` date DEFAULT NULL COMMENT '生日',
      `sex` char(1) DEFAULT NULL COMMENT '性别',
      `address` varchar(256) DEFAULT NULL COMMENT '地址',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of user
    -- ----------------------------
    INSERT INTO `user` VALUES ('1', '王五', null, '2', null);
    INSERT INTO `user` VALUES ('10', '张三', '2014-07-10', '1', '北京市');
    INSERT INTO `user` VALUES ('16', '张小明', null, '1', '河南郑州');
    INSERT INTO `user` VALUES ('22', '陈小明', null, '1', '河南郑州');
    INSERT INTO `user` VALUES ('24', '张三丰', null, '1', '河南郑州');
    INSERT INTO `user` VALUES ('25', '陈小明', null, '1', '河南郑州');
    INSERT INTO `user` VALUES ('26', '王五', null, null, null);
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    public class JdbcDemo {
        public static void main(String[] args) {
            Connection connection = null;
            PreparedStatement preparedStatement = null;
            ResultSet resultSet = null;
    
            try {
                // 加载数据库驱动
                Class.forName("com.mysql.jdbc.Driver");
                // 通过驱动管理类获取数据库链接
                connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8", "root", "root");
                // 定义sql语句 ?表示占位符
                String sql = "select * from user where username = ?";
                // 获取预处理statement
                preparedStatement = connection.prepareStatement(sql);
                // 设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值
                preparedStatement.setString(1, "王五");
                // 向数据库发出sql执行查询,查询出结果集
                resultSet = preparedStatement.executeQuery();
                // 遍历查询结果集
                while (resultSet.next()) {
                    System.out.println(resultSet.getString("id") + "  " + resultSet.getString("username"));
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                // 释放资源
                if (resultSet != null) {
                    try {
                        resultSet.close();
                    } catch (SQLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if (preparedStatement != null) {
                    try {
                        preparedStatement.close();
                    } catch (SQLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if (connection != null) {
                    try {
                        connection.close();
                    } catch (SQLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    毛病

    ①频繁的连接和释放资源
    ②硬编码问题(要着改SQL)
    ③返回结果不好包装处理

    Mybatis架构

     

    1、	mybatis配置SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。
    2、	通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂
    3、	由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。
    4、	mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。
    5、	Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。
    6、	Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
    7、	Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。

    不跟spring整合时需要配置

    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">
    <configuration>
        <properties resource="jdbc.properties"/>
        <!-- 别名 包以其子包下所有类   头字母大小都行-->
        <typeAliases>
    <!--         <typeAlias type="com.itheima.mybatis.pojo.User" alias="User"/> -->
            <package name="com.itheima.mybatis.pojo"/>
        </typeAliases>
        <!-- 和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:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
                    <property name="username" value="root" />
                    <property name="password" value="root" />
                </dataSource>
            </environment>
        </environments>
        <!-- Mapper的位置  Mapper.xml 写Sql语句的文件的位置 -->
        <mappers>
    <!--         <mapper resource="sqlmap/User.xml" class="" url=""/> -->
    <!--         <mapper resource="sqlmap/User.xml" class="" url=""/> -->
    <!--         <mapper class="com.itheima.mybatis.mapper.UserMapper" /> -->
    <!--         <mapper url="" /> -->
            <package name="com.itheima.mybatis.mapper"/>
        </mappers>
    </configuration>

    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">
    <!-- 写Sql语句   -->
    <mapper namespace="com.itheima.mybatis.mapper.UserMapper">
        <!-- 通过ID查询一个用户 -->
        <select id="findUserById" parameterType="Integer" resultType="User">
            select * from user where id = #{v}
        </select>
        <!-- //根据用户名称模糊查询用户列表
        #{}    select * from user where id = ?    占位符  ? ==  '五'
        ${}    select * from user where username like '%五%'  字符串拼接
         -->
        <select id="findUserByUsername" parameterType="String" resultType="com.itheima.mybatis.pojo.User">
            select * from user where username like "%"#{haha}"%"
        </select>
        <!-- 添加用户 -->
        <insert id="insertUser" parameterType="com.itheima.mybatis.pojo.User">
            <selectKey keyProperty="id" resultType="Integer" order="AFTER">
                select LAST_INSERT_ID()
            </selectKey>
            insert into user (username,birthday,address,sex) 
            values (#{username},#{birthday},#{address},#{sex})
        </insert>
        <!-- 更新 -->
        <update id="updateUserById" parameterType="com.itheima.mybatis.pojo.User">
            update user 
            set username = #{username},sex = #{sex},birthday = #{birthday},address = #{address}
            where id = #{id}
        </update>
        <!-- 删除 -->
        <delete id="deleteUserById" parameterType="Integer">
            delete from user 
            where id = #{vvvvv}
        </delete>
    </mapper>

    安照图示内容,需要搞一个session工厂了

    import java.io.InputStream;
    import java.util.Date;
    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.Test;
    
    import com.itheima.mybatis.pojo.User;
    
    public class MybatisFirstTest {
    
        //成员变量
        @Test
        public void testMybatis() throws Exception {
            //加载核心配置文件
            String resource = "sqlMapConfig.xml";
            InputStream in = Resources.getResourceAsStream(resource);
            //创建SqlSessionFactory
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
            //创建SqlSession
            SqlSession sqlSession = sqlSessionFactory.openSession();
            
            //执行Sql语句 命名空间com.itheima.mybatis.mapper.UserMapper
            User user = sqlSession.selectOne("test.findUserById", 10);
            
            System.out.println(user);
        }
        //根据用户名称模糊查询用户列表
        @Test
        public void testfindUserByUsername() throws Exception {
            //加载核心配置文件
            String resource = "sqlMapConfig.xml";
            InputStream in = Resources.getResourceAsStream(resource);
            //创建SqlSessionFactory
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
            //创建SqlSession
            SqlSession sqlSession = sqlSessionFactory.openSession();
            
            //执行Sql语句 
            List<User> users = sqlSession.selectList("test.findUserByUsername", "五");
            for (User user2 : users) {
                System.out.println(user2);
            }
        }
        //添加用户
        @Test
        public void testInsertUser() throws Exception {
            //加载核心配置文件
            String resource = "sqlMapConfig.xml";
            InputStream in = Resources.getResourceAsStream(resource);
            //创建SqlSessionFactory
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
            //创建SqlSession
            SqlSession sqlSession = sqlSessionFactory.openSession();
            
            //执行Sql语句 
            User user = new User();
            user.setUsername("何炅");
            user.setBirthday(new Date());
            user.setAddress("sadfsafsafs");
            user.setSex("男");
            int i = sqlSession.insert("test.insertUser", user);
            sqlSession.commit();
            
            System.out.println(user.getId());
            
        }
        //更新用户
        @Test
        public void testUpdateUserById() throws Exception {
            //加载核心配置文件
            String resource = "sqlMapConfig.xml";
            InputStream in = Resources.getResourceAsStream(resource);
            //创建SqlSessionFactory
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
            //创建SqlSession
            SqlSession sqlSession = sqlSessionFactory.openSession();
            
            //执行Sql语句 
            User user = new User();
            user.setId(29);
            user.setUsername("何炅292929");
            user.setBirthday(new Date());
            user.setAddress("222222sadfsafsafs");
            user.setSex("女");
            int i = sqlSession.update("test.updateUserById", user);
            sqlSession.commit();
        }
        //删除
        @Test
        public void testDelete() throws Exception {
            //加载核心配置文件
            String resource = "sqlMapConfig.xml";
            InputStream in = Resources.getResourceAsStream(resource);
            //创建SqlSessionFactory
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
            //创建SqlSession
            SqlSession sqlSession = sqlSessionFactory.openSession();
            
            sqlSession.delete("test.deleteUserById", 29);
            sqlSession.commit();
        }
    }

    Mybatis与Hibernate的区别

    Mybatis不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句。

    Mybatis学习门槛低,简单易学。

    Mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件,工作量大。


    dao层开发与测试(反面教材,自己写实现类)

    import com.itheima.mybatis.pojo.User;
    
    public interface UserDao {
        //通过用户ID查询一个用户
        public User selectUserById(Integer id);
    }
    import java.util.List;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import com.itheima.mybatis.pojo.User;
    
    public class UserDaoImpl implements UserDao {
    
        //注入
        private SqlSessionFactory sqlSessionFactory;
        public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
            this.sqlSessionFactory = sqlSessionFactory;
        }
        
        //通过用户ID查询一个用户
        public User selectUserById(Integer id){
            SqlSession sqlSession = sqlSessionFactory.openSession();
            return sqlSession.selectOne("test.findUserById", id);
        }
        
        //通过用户名称模糊查询
        public List<User> selectUserByUsername(Integer id){
            SqlSession sqlSession = sqlSessionFactory.openSession();
            return sqlSession.selectList("test.findUserById", id);
        }
        
    }

    注意这个before方法,用得很好!

    import java.io.InputStream;
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    import org.junit.Before;
    import org.junit.Test;
    import com.itheima.mybatis.dao.UserDao;
    import com.itheima.mybatis.dao.UserDaoImpl;
    import com.itheima.mybatis.pojo.User;
    
    public class MybatisDaoTest {
    
        public SqlSessionFactory sqlSessionFactory;
        @Before
        public void before() throws Exception {
            //加载核心配置文件
            String resource = "sqlMapConfig.xml";
            InputStream in = Resources.getResourceAsStream(resource);
            //创建SqlSessionFactory
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
        }
        @Test
        public void testDao() throws Exception {
            
            UserDao userDao = new UserDaoImpl(sqlSessionFactory);
            
            User user = userDao.selectUserById(10);
            System.out.println(user);
        }
    }

    mapper取代dao

    import com.itheima.mybatis.pojo.User;
    
    public interface UserMapper {
    //遵循四个原则 //接口 方法名 == User.xml 中 id 名 //返回值类型 与 Mapper.xml文件中返回值类型要一致 //方法的入参类型 与Mapper.xml中入参的类型要一致 //命名空间 绑定此接口 public User findUserById(Integer id); }

    注意关注/理解一下接口与实现类

    import java.io.InputStream;
    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.Test;
    import com.itheima.mybatis.mapper.UserMapper;
    import com.itheima.mybatis.pojo.User;
    
    public class MybatisMapperTest {
    
        @Test
        public void testMapper() throws Exception {
            //加载核心配置文件
            String resource = "sqlMapConfig.xml";
            InputStream in = Resources.getResourceAsStream(resource);
            //创建SqlSessionFactory
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
            //创建SqlSession
            SqlSession sqlSession = sqlSessionFactory.openSession();
            
            //SqlSEssion帮我生成一个实现类  (给接口)
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            
            User user = userMapper.findUserById(10);
            System.out.println(user);
        }
    }

    关于sqlMapConfig.xml文件

    properties(属性)
    settings(全局配置参数)
    typeAliases(类型别名)
    typeHandlers(类型处理器)
    objectFactory(对象工厂)
    plugins(插件)
    environments(环境集合属性对象)
    environment(环境子属性对象)
    transactionManager(事务管理)
    dataSource(数据源)
    mappers(映射器)

    击石乃有火,不击元无烟!!
  • 相关阅读:
    SQL Serever学习16——索引,触发器,数据库维护
    微信WeUI基础
    SQL Serever学习15——进阶
    SQL Serever学习14——存储过程和触发器
    微信WeUI入门2
    微信WeUI入门
    数据库—索引
    数据库—四种存储引擎
    视图
    事务
  • 原文地址:https://www.cnblogs.com/rain2020/p/12913340.html
Copyright © 2011-2022 走看看