zoukankan      html  css  js  c++  java
  • mybatis入门_mybatis基本原理以及入门程序

    一.传统jdbc存在的问题

    1.创建数据库的连接存在大量的硬编码,

    2.执行statement时存在硬编码.

    3.频繁的开启和关闭数据库连接,会严重影响数据库的性能,浪费数据库的资源.

    4.存在大量的重复性编码

    二.mybatis执行流程

    Mybatis基本的执行流程如下图所示:

    三.mybatis入门程序

    3.1 通过mybatis完成通过主键(id)查询用户(user)

    3.1.1.项目环境搭建

    建立的是Java项目.采用的mybatis版本为3.2.7.

    需要导入mybatis核心jar包和依赖jar包.建立log4j.properties配置文件记录日志.

    项目搭建后的架构如下:

    3.1.2.在Classpath路径下建立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>
        <!-- 配置mybatis的环境信息 ,与spring集成后,该信息由spring来管理-->
        <environments default="development">
            <environment id="development">
                <!-- 配置JDBC事务控制,由mybatis进行管理 -->
                <transactionManager type="JDBC"></transactionManager>
                <!-- 配置数据源,采用dbcp连接池 -->
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver" />
                    <property name="url"
                        value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&amp;characterEncoding=utf8" />
                    <property name="username" value="root" />
                    <property name="password" value="root" />
                </dataSource>
            </environment>
        </environments>
    </configuration>

    3.1.3.建立JavaBean对象.

    3.1.4.建立Mapping映射文件

    在config下建立一个包叫做sqlmap方便管理映射文件.在该包下建立一个User.xml文件.它作为配置映射的文件.配置了sql语句的详细信息.User.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是命名空间,可以分类管理sql -->
    <mapper namespace="test1">
        <!-- select标识一个MappedStatement -->
        <!-- id:statement的唯一标识. -->
        <!-- parameterType:指定输入参数的Java类型.由于采用的是根据id查询.指定int -->
        <!-- resultType:指定单条记录的类型.(例如:select * from user指定的resultType依然为User类) -->
        <!-- 标签主体里写sql语句.注意#{}里接受输入的参数类型.如果输入的参数类型为基本的数据类型.
        那么#内的内容可以任意.#{}会对输入类型进行解释.例如如果指定ParameterType为java.lang.String,
        那么#{}会默认为输入的值加上'' -->
        <select id="findUserById" parameterType="int" resultType="com.xyy.po.User">
            SELECT * FROM USER WHERE
            id=#{id}
        </select>
    </mapper>

    3.1.5.在SqlMapConfig.xml中配置mapping映射文件.

     

    3.1.6.建立测试类进行测试

    public class TestMyBatis1 {
    
        @Test
        public void testMyBatisById () throws IOException {
            //加载SqlMapConfig.xml配置文件
            InputStream in=Resources.getResourceAsStream("SqlMapConfig.xml");
            //创建SqlSessionFactory
            SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
            //创建SqlSession
            SqlSession session = factory.openSession();
            //利SqlSession完成查询操作,第一个参数是MappedStatement的id.注意namespace和配置的id唯一确定id.第二个参数是输入参数,对应配置文件的parameterType
            User user = session.selectOne("test1.findUserById", 1);
            System.out.println(user);
            //关闭SqlSession
            session.close();
        }
    }

    3.2 通过mybatis完成通过name模糊查询用户(user)

    3.2.1 建立MappedStatement标签.此处为<select>

    需要注意的是.这里用到了${}符号,它相当于连接符,不会对输入的类型进行类型解释.但是它无法有效的防止SQL注入!

    <select id="findUserLikeUsername" parameterType="java.lang.String" resultType="com.xyy.po.User">
            SELECT * FROM USER WHERE 
            username LIKE '%${value}%'
        </select>

    3.2.2 建立测试.

    @Test
        public void testMyBatisByLike() throws IOException {
            InputStream in=Resources.getResourceAsStream("SqlMapConfig.xml");
            SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
            SqlSession session = factory.openSession();
            List<User> users=session.selectList("test1.findUserLikeUsername","小明");
            System.out.println(users);
            session.close();
        }

    3.3 利用mybatis完成插入用户的操作
    3.3.1 编写sql语句的映射

    <!-- insert语句用的是insert标签.注意没有返回值可以不应写resultType -->
        <insert id="insertUser" parameterType="com.xyy.po.User">
            <!-- 使用#{属性名}可以获取传入的实体bean对象中的对应的属性值.由于数据库表中id是自动递增的
            因此不用插入主键id -->
            INSERT INTO USER (username,birthday,sex,address) 
            VALUES(#{username},#{birthday},#{sex},#{address});
        </insert>

    3.3.2 建立测试类

    注意对于增,删,改操作.需要手动提交事务但是不需要手动开启事务,事务在建立SqlSessionFactory的时候已经自动开启了

    public void testMyBatisInsert() throws IOException {
            InputStream in=Resources.getResourceAsStream("SqlMapConfig.xml");
            SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
            SqlSession session = factory.openSession();
            User user=new User();
            user.setUsername("hlhdidi");
            user.setAddress("北京昌平");
            session.insert("test1.insertUser", user);
            session.commit();//提交事务
            session.close();
        }

    3.4 返回主键

    3.4.1 配置文件的书写

    有时候会有一些应用场景需要返回刚刚生成的主键.这就涉及到一个新的标签.<selectKey>

    Selectkey可以用于返回主键.它用于执行指定的sql.然后将返回结果封装到输入参数(通常是一个JavaBean)的指定属性里.在下面的代码中,selectKey中的order属性指定为after是因为先插入数据,mysql数据库才会分配id.

    SELECT LAST_INSERT_ID()才能返回刚插入数据的主键

    insert id="insertUser" parameterType="com.xyy.po.User">
            <!-- selectkey:指定了查询主键的sql.查询的主键将会被封装在传入的参数的keyProperty指定属性中 -->
            <!-- resultType返回的主键的类型 -->
            <!-- order:指定查询主键发生在下面的sql语句的前面还是后面 -->
            <selectKey keyProperty="id" resultType="int" order="AFTER">
                SELECT LAST_INSERT_ID();
            </selectKey>
            <!-- 使用#{属性名}可以获取传入的实体bean对象中的对应的属性值.由于数据库表中id是自动递增的
            因此不用插入主键id -->
            INSERT INTO USER (username,birthday,sex,address) 
            VALUES(#{username},#{birthday},#{sex},#{address});
        </insert>

    3.4.2 测试

    @Test
        public void testMyBatisInsert() throws IOException {
            InputStream in=Resources.getResourceAsStream("SqlMapConfig.xml");
            SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
            SqlSession session = factory.openSession();
            User user=new User();
            user.setUsername("hlhdidi");
            user.setAddress("北京昌平");
            session.insert("test1.insertUser", user);
            System.out.println(user.getId());
            session.commit();//提交事务
            session.close();
        }

    3.4.3 返回uuid类型的主键.

    这种情况与上面情况的区别在于uuid是由我们指定并赋值到JavaBean的对应属性的,因此执行的order需要是BEFORE.只有这样才能先赋值,再插入数据库.同时在下面的sql语句,同时书写上#{id}

    <!-- 需要在Insert语句之前.才能查询出来并封装到user的属性. -->
            <selectKey keyProperty="id" resultType="String" order="BEFORE">
                SELECT UUID();
            </selectKey>
            INSERT INTO USER
            VALUES(#{id},#{username},#{birthday},#{sex},#{address});

    3.4.4 利用序列产生主键.(oracle数据库)

    Oracle数据库生成主键的方式是调用序列的nextval方法.我们可以用下面的方法去生成主键:

    4.传统Dao开发和Mapper开发.
    4.1 传统的Dao开发
    SqlSessionFactory有Dao外部的程序注入进来.需要注意SqlSessionFactory通常是单例的:

    public class UserDaoImpl implements UserDao{
    
        private SqlSessionFactory factory;
        
        public UserDaoImpl(SqlSessionFactory factory) {
            this.factory=factory;
        }
        @Override
        public User findUserById(Integer id) {
            SqlSession session=factory.openSession();
            return session.selectOne("test1.findUserById",id);
        }
    
        @Override
        public List<User> findUsersByName(String name) {
            SqlSession session=factory.openSession();
            return session.selectList("test1.findUserLikeUsername", name);
        }
    
        @Override
        public void saveUser(User user) {
            SqlSession session=factory.openSession();
            session.insert("test1.insertUser", user);
        }
    
    }

    测试类体现了SqlSessionFactory单例的思想..

    private SqlSessionFactory factory;//应当是单例的.
        
        @Before
        public void init() {
            try {
                InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
                factory=new SqlSessionFactoryBuilder().build(in);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
        @Test
        public void testDao() {
            UserDaoImpl udao=new UserDaoImpl(factory);
            User user=udao.findUserById(16);
            System.out.println(user);
        }

    4.2 Mapper开发

    4.2.1 规范

    Mapper开发通过开发Mapper接口来替代传统的Dao的开发方式.Mapper开发是mybatis最常用的开发方式!Mapper接口的实现类由mybatis通过jdk动态代理去实现.Mapper接口需要遵循以下开发规范:

    1. mapper接口的全限定名要和mapper映射文件的namespace保持一致.(方便找出对应的mapper建立动态代理)

    2. mapper接口的方法需要和mapper映射文件的statement的id保持一致.(方便找出对应的statement来执行sql语句)

    3. mapper接口的方法的参数类型要和mapper映射文件的statement的parameterType值保持一致.

    4. Mapper接口的方法的返回值类型要和mapper映射文件的statement的resultType保持一致.

    4.2.2 mapper接口的编写.

    只需要是一个接口即可.此外注意mapper的规范!

    public interface UserMapper {
        public User findUserById(Integer id);
        
        public void insertUser(User user);
    }

    4.2.3 映射文件的编写

    和之前的User.xml的编写基本保持一致.需要注意的是需要符合规范!(在下面的标识处)

    4.2.4 测试

    @Test
        public void testMapper() {
            SqlSession session = factory.openSession();
            UserMapper mapper = session.getMapper(UserMapper.class);//建立代理对象
            User user = mapper.findUserById(1);
            System.out.println(user);
        }
  • 相关阅读:
    PyQt作品 – PingTester – 多点Ping测试工具
    关于和技术人员交流的一二三
    Pyjamas Python Javascript Compiler, Desktop Widget Set and RIA Web Framework
    Hybrid Qt applications with PySide and Django
    pyjamas build AJAX apps in Python (like Google did for Java)
    PyQt 维基百科,自由的百科全书
    InfoQ:请问为什么仍要选择Java来处理后端的工作?
    Eric+PyQt打造完美的Python集成开发环境
    python select module select method introduce
    GUI Programming with Python: QT Edition
  • 原文地址:https://www.cnblogs.com/hlhdidi/p/6255953.html
Copyright © 2011-2022 走看看