精华内容
下载资源
问答
  • SpringData持久层框架

    2020-02-13 17:32:29
    SpringData是用来简化基于Spring构建的应用程序的持久层框架的框架。简化了持久层方案的方案。SpringData有很多子模块,其中SpringDataJPA就是其中一个子模块。简化了我们的持久层开发工作,可以让我们在持久层不用...
  • .NET 优秀开源持久层框架 NHibernate & JAVA开源持久层框架 Hibernate Posted on 2005-12-16 22:36 庄稼汉 阅读(1247) 评论(1) 编辑收藏 引用 网摘 所属分类: 技术 不知不觉来大连已经三个多月,在这期间...
            不知不觉来大连已经三个多月,在这期间研究学习了Struts 、Webwork 、 Velocity 、Sitmesh 和Hibernate等优秀的开源JAVA开发框架或模板引擎,尤其是Struts和Hibernate,因为Struts事实上就是MVC设计模式的标准实现,被普遍的应用在各种大型的企业开发项目中;而Hibernate则可以说是众多持久层框架中的产业标准,加上其被JBoss组织收纳,更使其在企业级开发的持久化方面独立熬头。把这两个框架应用到项目中可以彻底把你从数据持久化管理和WEB开发的困境中解救出来,从而可以使你集中精力处理业务逻辑。

             近一段时间一直在学习.NET ,由于一直从事JAVA开发,学习C#就显得特别轻松。基本上利用三五天时间看一看C#与JAVA之间不同的地方以及写法上的差异就可以了。但是对ASP.NET的学习却要花费一些时间研究,ASP.NET明确的代码和页面分离、事件驱动模型、托管的数据集和优秀的IDE开发工具支持使得ASP.NET应用程序的开发工作变的轻松而愉快。当然要写出优秀的代码还是要靠经验的积累和对设计模式的理解。

            在JAVA领域里存在各种各样的开源框架,那么在.NET里是否也如此呢?到网上一搜真是吓了一跳,居然也有五六十个各种各样的开源框架。NHibernate 这个项目立刻引起了我的注意,粗略的看了一些这个项目的介绍,知道了它其实就是Hibernate框架的.NET实现。再看一看它的文档,和Hibernate的基本上差不多。决定好好的研究研究这个框架,如果谁也正在学习这个框架,那么欢迎交流经验!

            在此推荐一位网友翻译的NHibernate文档以及NHibernate的官方网站。

            http://wiki.nhibernate.org/display/NH/Home  NHibernate Wiki

            http://nhibernate.sourceforge.net/nh-docs/html/    NHibernate文档 

            NHibernate中文文档下载
     

    转载于:https://www.cnblogs.com/wzwind/archive/2008/10/13/1310077.html

    展开全文
  • 自定义持久层框架

    2020-03-21 14:24:05
    是的,这些开源框架都非常优秀,所以我们自定义实现一个持久层框架并不是为了在生产环境中去使用,而是在梳理,编写自定义持久层框架的过程中,加深对持久层框架原理的理解,帮组我们在日常开发工作中,更好的去使用...

    为什么要自定义持久层框架?

    为什么要自定义持久层框架?Mybatis,hibernate这些开源的持久层框架,它不香吗?是的,这些开源框架都非常优秀,所以我们自定义实现一个持久层框架并不是为了在生产环境中去使用,而是在梳理,编写自定义持久层框架的过程中,加深对持久层框架原理的理解,帮助我们在日常开发工作中,更好的去使用这些持久层框架。我这边常用的是Mybatis框架,本文模仿Mybatis实现一个简易版本的持久层框架。
    【注意】,这样的一个自定义框架,并没有和Spring进行整合。完整的代码,请参考:https://gitee.com/jiancongchen/stage1-module1-mybatis/blob/master/jiancongchen.zip,下载后,IDEA导入即可

    思路分析

    我们日常开发过程中,使用Mybatis的时候,一般需要:

    1. 配置数据源信息,也就是:sqlMapConfig.xml。(Springboot+Mybatis框架,当然可以在appliaction.yml中进行配置)
    2. 编写Mapper接口,提供Mapper接口对应的XML文件,或者是在Mapper中使用注解,目的都是提供可执行的sql语句,也就是:mapper.xml,本文只实现了xml的解析,注解形式未完成。
      那么,我们自定义的持久层框架,首先需要知道sqlMapConfig.xml文件的路径,以及mapper.xml文件的路径,至于mapper.xml文件的路径,我们可以配置在sqlMapConfig.xml中,这样我们就只需要知道sqlMapConfig.xml文件的路径就可以。
      那么解析sqlMapConfig.xml,我们可以拿到数据源的配置信息,构建一个DataSource,以及通过解析mapper.xml的文件,获得mapper.xml中配置的sql语句信息,那么一个Configuration的配置类,就不难想象:
    public class Configuration {
    
        private DataSource dataSource;
        
        /**
         *  key: statementid 
         *  value: 封装好的mappedStatement对象
         */
        Map<String,MappedStatement> mappedStatementMap = new HashMap<>();
    	...
    }
    

    数据源的配置信息,大家应该不会陌生,我们可以使用C3p0的ComboPooledDataSource构建一个数据源DataSource。

        <dataSource>
            <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
            <property name="jdbcUrl" value="jdbc:mysql:///zdy_mybatis"></property>
            <property name="username" value="root"></property>
            <property name="password" value="root"></property>
        </dataSource>
    

    那么,mappedStatementMap 中的id是什么,使用过Mybatis的同学肯定都能猜到是,namespace+id的形式,namespace是mapper接口的类路径,id是方法名,那么为什么这个id必须是这个形式呢?后续我们再探讨。我们先分析一下MappedStatement这个类中,应该有些什么属性?这个类封装了sql的信息,我们在编写mapper.xml的时候,需要些什么呢?
    sql语句总是需要的吧,那么这个sql语句如果需要参数,参数是什么类型,以及执行sql语句的返回结果是什么类型也是需要的。这句sql语句总是需要一个id来唯一标识区分。所以MappedStatement属性也就比较清楚了:

    public class MappedStatement {
    
        //id标识
        private String id;
        //返回值类型
        private String resultType;
        //参数值类型
        private String paramterType;
        //sql语句
        private String sql;
        ...
       }
    

    整体就是通过dom4j解析sqlMapConfig.xml,封装Configuration对象。

    DataSource有了,SQL语句也有了,如何执行sql语句呢?sql语句无非增删改查,那么我们定义一个Executor的接口:

    public interface Executor {
    
        public <E> List<E> query(Configuration configuration, MappedStatement mappedStatement, Object... params) throws Exception;
    
        public void insert(Configuration configuration, MappedStatement mappedStatement, Object... params) throws Exception;
    
        public void update(Configuration configuration, MappedStatement mappedStatement, Object... params) throws Exception;
    
        public void delete(Configuration configuration, MappedStatement mappedStatement, Object... params) throws Exception;
    
    }
    
    

    这里的Configuration参数主要是用来获取DataSource属性,params自然就是Sql语句的参数。在query方法的调用过程中,可以分为三个步骤,第一步是参数封装,Mybatis底层的查询实现还是依赖于JDBC的那一套机制,我们需要封装一个PreparedStatement,然后就是执行sql查询,最后是将sql返回的结果集封装为我们设置的返回类型。

    public class SimpleExecutor implements Executor {
    
        @Override
        public <E> List<E> query(Configuration configuration, MappedStatement mappedStatement, Object... params) throws Exception {
    
            //参数处理转换
            PreparedStatementHandler preparedStatementHandler = new PreparedStatementHandler(configuration, mappedStatement, params);
            PreparedStatement preparedStatement = preparedStatementHandler.getPreparedStatement();
    
            //执行sql
            ResultSet resultSet = preparedStatement.executeQuery();
    
            //查询结果集封装
            ResultSetHandler resultSetHandler = new ResultSetHandler(mappedStatement,resultSet);
            return resultSetHandler.getResultSet();
        }
    	...
    }
    
        public  PreparedStatement getPreparedStatement() throws Exception {
            //1.注册驱动,获取链接
            Connection connection = configuration.getDataSource().getConnection();
    
            //2.获取sql语句  ->  转换sql语句
            String sql = mappedStatement.getSql();
            BoundSql bondSql = getBoundSql(sql);
    
            //3.获取预处理对象
            PreparedStatement preparedStatement = connection.prepareStatement(bondSql.getSqlText());
    
            //4.设置参数
            String paramterType = mappedStatement.getParamterType();
            Class<?> paramterClass = paramterType != null ? Class.forName(paramterType) : null;
            List<ParameterMapping> parameterMappingList = bondSql.getParameterMappingList();
            for (int i = 0; i < parameterMappingList.size(); i++) {
                ParameterMapping parameterMapping = parameterMappingList.get(i);
                String content = parameterMapping.getContent();
                //反射
                Field declaredField = paramterClass.getDeclaredField(content);
                //暴力访问
                declaredField.setAccessible(true);
                Object o = declaredField.get(params[0]);
                preparedStatement.setObject(i+1,o);
            }
            return preparedStatement;
        }
    
        public <E> List<E> getResultSet() throws Exception {
            String resultType = mappedStatement.getResultType();
            Class<?> resultTypeClass = resultType != null ? Class.forName(resultType) : null;
            ArrayList<Object> objects = new ArrayList<Object>();
            //6.封装返回结果
            while (resultSet.next()){
                Object o = resultTypeClass.newInstance();
                ResultSetMetaData metaData = resultSet.getMetaData();
                for(int i = 1; i <= metaData.getColumnCount(); i++){
                    String columnName = metaData.getColumnName(i);
                    Object value = resultSet.getObject(columnName);
                    PropertyDescriptor propertyDescriptor = new PropertyDescriptor(columnName, resultTypeClass);
                    Method writeMethod = propertyDescriptor.getWriteMethod();
                    writeMethod.invoke(o,value);
                }
                objects.add(o);
            }
            return (List<E>) objects;
        }
    

    那么问题来了,Executor的mappedStatement参数哪里来的?它应该怎么知道要执行的是哪一个mappedStatement?我们在使用sql语句的时候,就需要提供namespace+id,来从Configuration的mappedStatementMap中获取到对应的mappedStatement。我们可以再封装一下:

    public interface SqlSession {
    
        public <E> List<E> selectList(String statementId, Object... params) throws Exception;
    
        public <T> T selectOne(String statementId, Object... params) throws Exception;
    
        public void insertOne(String statementId, Object... params) throws Exception;
    
        public void updateOne(String statementId, Object... params) throws Exception;
    
        public void deleteOne(String statementId, Object... params) throws Exception;
    
    }
    
        @Override
        public <E> List<E> selectList(String statementId, Object... params) throws Exception {
            SimpleExecutor simpleExecutor = new SimpleExecutor();
            MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);
            List<Object> list = simpleExecutor.query(configuration, mappedStatement, params);
            return (List<E>) list;
        }
    

    到这里,整个Sql的解析,执行调用过程就很清晰了,那么作为框架的使用者是如何使用的呢?假设我们有这么一个接口,UserMapper中已经编写好了对应的sql语句:

    public interface IUserDao {
    
        /**
         * 查询所有用户
         * @return
         */
        List<User> findAll() throws Exception;
    
        /**
         * 根据条件进行查询
         * @param user
         * @return
         */
        User findByCondition(User user) throws Exception;
    	...
    }
    
    public class UserDaoImpl implements IUserDao {
    
        public List<User> findAll() throws Exception {
            InputStream resourceAsSteam = Resources.getResourceAsStream("SqlMapConfig.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsSteam);
            SqlSession sqlSession = sqlSessionFactory.openSession();
    
            List<User> userList = sqlSession.selectList("com.jiancong.dao.IUserDao.findAll");
            for (User user1 : userList) {
                System.out.println(user1);
            }
            return userList;
        }
       
        public User findByCondition(User user) throws Exception {
            InputStream resourceAsSteam = Resources.getResourceAsStream("SqlMapConfig.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsSteam);
            SqlSession sqlSession = sqlSessionFactory.openSession();
            User user2 = sqlSession.selectOne("com.jiancong.dao.IUserDao.findByCondition", user);
            System.out.println(user2);
            return user2;
        }
        ...
     }
    

    那么以上的代码就能够运行了,但是有一个问题,在UserDaoImpl 存在一些冗余代码,sqlSession的获取过程是一致,不应该这样重复,还有一个问题就是我们在使用Mybatis的时候,并不需要显示的这样提供一个namespace+id的参数,我们只需要调用方法就好,那么Mybatis是怎么知道我们调用的是那一句SQL语句的呢?这里我们就要解释一下前面说到的,为什么namespace+id是有要求的,namespace是mapper接口的类路径,id是方法名,因为Mybatis使用JDK动态代理来完成方法的调用,简易的实现如下。在动态代理中,我们不能知道XML文件中的id,但是我们可以获取到类的路径,以及方法名,只要我们保持这样的一致性,动态代理就可以通过【类路径+方法名】作为namespace+id,获取到对应的sql语句。

    • 那么问题来了,Mybatis的Mapper接口中能否使用方法重载?
    • 显然是不能的,方法重载Mybatis通过JDK动态代理的方式,无法找到正确的SQL语句,在启动解析XML文件的过程中就会报错。
    @Override
        public <T> T getMapper(Class<?> mapperClass) {
            //使用JDK动态代理模式为DAO接口生成对象
            Object proxyInstance = Proxy.newProxyInstance(DefaultSqlSession.class.getClassLoader(), new Class[]{mapperClass}, new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    String methodName = method.getName();
                    String className = method.getDeclaringClass().getName();
                    String statementId  = className + "." + methodName;
                    Type genericReturnType = method.getGenericReturnType();
                    //是否为参数化类型
                    if(genericReturnType instanceof ParameterizedType){
                        List<Object> objects = selectList(statementId, args);
                        return objects;
                    }
                    //是否为基础类型,且为void
                    if(genericReturnType instanceof Class && VOID.equals(genericReturnType.getTypeName())){
                        updateOne(statementId, args);
                        return null;
                    }
                    return selectOne(statementId,args);
                }
            });
            return (T) proxyInstance;
        }
    

    完整的代码,请参考:https://gitee.com/jiancongchen/stage1-module1-mybatis/blob/master/jiancongchen.zip,下载后,IDEA导入即可

    展开全文
  • 1、引入自定义持久层框架的jar包。 2、提供存放数据库核心配置的信息。 3、提供sql配置信息(包括sql语句、参数类型和返回类型)。 从框架的角度来设计 设计持久层框架,本质上是对JDBC代码进行封装,因此我们需要...

    从使用端的角度来设计

    在这里插入图片描述
    从使用端的角度来看,我们需要做一些配置工作,原理等同于使用Mybatis框架时所进行的配置。这其中包括以下步骤:
    1、引入自定义持久层框架的jar包。
    2、提供存放数据库核心配置的信息。
    3、提供sql配置信息(包括sql语句、参数类型和返回类型)。

    从框架的角度来设计

    在这里插入图片描述
    设计持久层框架,本质上是对JDBC代码进行封装,因此我们需要做这样一些工作:

    1、既然是跟数据库相关的框架,那么第一步肯定是要先连接上数据库。因此我们首先要读取存放数据库核心配置信息和sql配置信息的配置文件,也就是根据配置文件的路径,加载配置文件成字节输入流,存储在内存中。当然,我们不能一直将读取到的配置信息以流的形式存储在内存中,这样操作起来很不方便。
    2、我们可以创建两个javaBean:Configuration和MappedStatement,讲解析出来的核心配置信息和sql配置信息分别存放在这两个容器对象中。
    3、上面提到了解析配置文件,这里来讲一下具体的实现思路。这里我们需要用到Java的XML应用程序编程接口:dom4j对两类配置文件进行解析,讲解析出来的内容封装到容器对象Configuration和MappedStatement中。
    4、创建SqlSessionFactory接口及其实现类,获取数据库核心配置信息参数,生产sqlSession。
    5、创建sqlSession接口及其实现类,用于封装数据库CRUD操作的相关方法,包括增删查改。
    6创建Executor接口及其实现类,用于调用JDBC的增删查改方法。

    展开全文
  • mybatis持久层框架技术

    千人学习 2019-03-09 22:40:20
    MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和...
  • CoreFS平台持久层框架使用说明CoreFS平台持久层框架使用说明
  • 接触过JDBC的同学应该不陌生,那么既然JDBC已经能够完成数据库的操作,为什么还会出现各种持久层框架呢?有新框架出现说明JDBC本身还是存在一些问题, 针对jdbc存在的问题 ,通过学习自定义持久层框架能帮助我们更好的...
  • java 实现自定义持久层框架代码,解析配置文件,手动封装返回结果,使用到了构建者模式、工厂模式、代理模式
  • 自己手写的Java持久层框架DdwDao
  • 持久层框架Ibatis

    2009-06-20 21:47:04
    持久层框架Ibatis 持久层框架Ibatis
  • mybatis持久层框架

    2014-06-16 11:36:14
    该配置文件描述mybatis持久层框架技术的,可有将SQL放到配置文件并且规范数据库连接等
  • iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAO),同时还提供一个利用这个框架开发的 JPetStore实例。 在线Javadoc:http://tool.oschina.net/apidocs/apidoc?api=mybatis-3.1.1 标签:...
  • 17-Spring持久层框架整合

    万次阅读 2020-11-04 19:15:23
    1.为什么Spring要与持久层框架进行整合 spring是一个优秀的框架,他的优秀支持就是能整合所有程序员想要让他整合的框架,这里所说的持久成也不例外。 JavaEE开发需要持久层进行数据库的访问操作,spring 当然不让。...

    上一篇:16-Spring 基于注解的AOP编程、AOP总结https://blog.csdn.net/fsjwin/article/details/109482768

    1.为什么Spring要与持久层框架进行整合

    spring是一个优秀的框架,他的优秀支持就是能整合所有程序员想要让他整合的框架,这里所说的持久成也不例外。

    • JavaEE开发需要持久层进行数据库的访问操作,spring
      当然不让。
    • JDBC Hibernate MyBatis进行持久开发过程存在大量的代码冗余
    • Spring基于模板设计模式对于上述的持久层技术进行了封装

    2.Spring要可以与那些持久层框架进行整合

    1. jdbc JdbcTemplate
    2. Hibernate (JPA) HibernateTemplate
    3. Mybatis SqlSessionFactoryBean、MapperScannerConfiger

    3.Mybatis开发回顾,在Spring没有整合前

    1. 实体
    2. 实体别名
    3. 创建DAO接口
    4. 实现Mapper文件(对maper编程)
    5. 注册Mapper文件
    6. MyBatisApi调用

    3.1 实体 User.java

    package mybatis;
    
    import java.io.Serializable;
    
    /**
     * @author yuhl
     * @Date 2020/11/4 10:51
     * @Classname User
     * @Description 1. 实体
     */
    public class User implements Serializable {
        private Integer id;
        private String name;
        private String password;
    
        public User() {
        }
    
        public User(Integer id, String name, String password) {
            this.id = id;
            this.name = name;
            this.password = password;
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", password='" + password + '\'' +
                    '}';
        }
    }
    
    

    3.2. 实体别名mybatis-config.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>
        <typeAliases>
           <!-- 2. 实体别名-->
            <typeAlias alias="user" type="mybatis.User"/>
        </typeAliases>
        <environments default="mysql">
            <environment id="mysql">
                <transactionManager type="JDBC"></transactionManager>
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost:3306/yuhl?useSSL=false"/>
                    <property name="username" value="root"/>
                    <property name="password" value="root"/>
                </dataSource>
            </environment>
        </environments>
    
        <mappers>
    
    
        </mappers>
    </configuration>
    

    在这里插入图片描述

    3.3. 表

    在这里插入图片描述

    
    -- ----------------------------
    -- Table structure for t_user
    -- ----------------------------
    DROP TABLE IF EXISTS `t_user`;
    CREATE TABLE `t_user`  (
      `id` int(0) NOT NULL AUTO_INCREMENT,
      `name` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
      `password` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
      PRIMARY KEY (`id`) USING BTREE
    ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
    
    

    3.4. 创建DAO接口 UserDao.java

    package mybatis;
    
    /**
     * @author yuhl
     * @Date 2020/11/4 10:59
     * @Classname UserDao
     * @Description TODO
     */
    public interface UserDao {
        //保存用户
        public void save(User user);
    }
    
    

    3.5. 实现Mapper文件UserDAOMapper.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">
    <mapper namespace="mybatis.UserDao"> <!--接口名-->
        <!--id:mybatis.UserDao接口中的方法面
        parameterType:面向对象的对象名字-->
        <insert id="save" parameterType="user">
            insert into t_user(name,password) value (#{name},#{password})
        </insert>
    </mapper>
    

    3.6. 注册Mapper文件UserDAOMapper.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>
        <typeAliases>
           <!-- 2. 实体别名-->
            <typeAlias alias="user" type="mybatis.User"/>
        </typeAliases>
        <environments default="mysql">
            <environment id="mysql">
                <transactionManager type="JDBC"></transactionManager>
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost:3306/yuhl?useSSL=false"/>
                    <property name="username" value="root"/>
                    <property name="password" value="root"/>
                </dataSource>
            </environment>
        </environments>
    
        <mappers>
            <!--注册mapper.xml到mybatis-->
            <mapper resource="UserDAOMapper.xml"/>
        </mappers>
    </configuration>
    

    在这里插入图片描述

    3.7. MyBatisApi调用

    import mybatis.User;
    import mybatis.UserDao;
    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 java.io.IOException;
    import java.io.InputStream;
    
    /**
     * @author yuhl
     * @Date 2020/11/4 11:06
     * @Classname MybatisTest
     * @Description 测试
     */
    public class MybatisTest {
    
        @Test
        public void test1(){
            try {
                //通过流加载mybatis的主配置文件:mybatis-config.xml
                InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
                //
                SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
                SqlSession sqlSession = sqlSessionFactory.openSession();
    
                UserDao userDao = sqlSession.getMapper(UserDao.class);
    
                userDao.save(new User("yuhl", "222222"));
                sqlSession.commit();
                sqlSession.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    }
    
    

    插入成功:
    在这里插入图片描述

    3.单纯的Mybatis编程存在的问题

    1. 配置繁琐 第2步和第7步
      如果有9999个类该怎办?
      在这里插入图片描述
    2. 代码冗余
      主要指的是API代码冗余 。
      在这里插入图片描述
      由于以上两个原因,我们不会使用mybatis单独做开发,会使用spring对于mybatis的整合,下面看对于整合后的mybitis的使用是不是更为丝滑呢!
      即spring可以积极2.6.7三个步骤的问题。

    4.Spring的Mybatis整合

    1. 实体
    2. 实体别名(<property name="typeAliasesPackage" value="com.yuhl.entity"/>)
    3. 表
    4. 创建DAO接口
    5. 实现Mapper文件(对maper编程)
    6. 注册Mapper文件(<value>classpath:com.yuhl.mapper/*DAOMapper.xml</value>)
    7. MyBatisApi调用(被优化了直接从factory.getBean("userDAO"))
    以上步在使用spring整合后
    	1. 实体
    	2. 表
    	3. 创建DAO接口
    	4. 实现Mapper文件(对maper编程)
    

    引入jar包:pom.xml 特别注意与mybatis整合是使用druid连接池

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>spring5_20201031</artifactId>
            <groupId>org.yuhl</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>Spring_mybatis</artifactId>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-tx</artifactId>
                <version>5.1.14.RELEASE</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>5.1.14.RELEASE</version>
            </dependency>
    
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-spring</artifactId>
                <version>2.0.2</version>
            </dependency>
    
            <!--阿里巴巴连接池-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.1.18</version>
            </dependency>
    
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.48</version>
            </dependency>
    
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.4.6</version>
            </dependency>
    
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.11</version>
                <scope>test</scope>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>5.1.4.RELEASE</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aop</artifactId>
                <version>5.1.14.RELEASE</version>
            </dependency>
    
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjrt</artifactId>
                <version>1.8.8</version>
            </dependency>
    
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.8.3</version>
            </dependency>
    
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>1.7.25</version>
            </dependency>
    
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>
        </dependencies>
    
    </project>
    

    4.1在mybatis-config.xml中的有所东西均可以在applicationContex.xml配置消灭mybatis-config.xml

    在这里插入图片描述
    在这里插入图片描述
    至此可以完全消灭mybatis-config.xml文件。仅使用applicationContex.xml

    4.1 代码如下

    1. 实体User .java
    package com.yuhl.entity;
    
    import java.io.Serializable;
    
    /**
     * @author yuhl
     * @Date 2020/11/4 10:51
     * @Classname User
     * @Description 1. 实体
     */
    public class User implements Serializable {
        private Integer id;
        private String name;
        private String password;
    
        public User() {
        }
    
        public User(String name, String password) {
            this.name = name;
            this.password = password;
        }
    
        public User(Integer id, String name, String password) {
            this.id = id;
            this.name = name;
            this.password = password;
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", password='" + password + '\'' +
                    '}';
        }
    }
    
    
    1. 表t_user 复用之前的表
    -- ----------------------------
    -- Table structure for t_user
    -- ----------------------------
    DROP TABLE IF EXISTS `t_user`;
    CREATE TABLE `t_user`  (
      `id` int(0) NOT NULL AUTO_INCREMENT,
      `name` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
      `password` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
      PRIMARY KEY (`id`) USING BTREE
    ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
    

    3 创建DAO接口UserDAO.java

    package com.yuhl.dao;
    
    
    import com.yuhl.entity.User;
    
    /**
     * @author yuhl
     * @Date 2020/11/4 10:59
     * @Classname UserDao
     * @Description TODO
     */
    public interface UserDAO {
        //保存用户
        public void save(User user);
    }
    
    
    1. 实现Mapper文件(对maper编程)com.yuhl.mapper/UserDAOMapper.xml
      特别注意:com.yuhl.mapper是一个文件集,不是三级包
    <?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">
    <mapper namespace="com.yuhl.dao.UserDAO"> <!--接口名-->
        <!--id:mybatis.UserDao接口中的方法面
        parameterType:面向对象的对象名字-->
        <insert id="save" parameterType="user">
            insert into t_user(name,password) value (#{name},#{password})
        </insert>
    </mapper>
    
    1. 测试
    import com.yuhl.dao.UserDAO;
    import com.yuhl.entity.User;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**
     * @author yuhl
     * @Date 2020/11/4 11:06
     * @Classname MybatisTest
     * @Description 测试
     */
    public class MybatisTest2 {
    
        @Test
        public void test1() {
            ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
            UserDAO userDao = (UserDAO) ctx.getBean("userDAO");
            userDao.save(new User("zhangsan","ddd"));
        }
    }
    
    
    1. 结果
      在这里插入图片描述

    5.Mybatis和spring整合事务控制

    在这里插入图片描述
    这句话告诉我们spring并没有提交事务,我们的事务是被谁提交的呢?
    前面我们单独使用mybatis的时候手动提交了了事务
    session.commint;
    这里直接给出答案,是我们引入的第三方数据源druid控制了事务的提交。
    但是在实战中我们不会让他控制我们的事务,我们会把事务的控制权交给spring,让spring来控制事务。
    下一篇:18-Spring事务控制@Transactional https://blog.csdn.net/fsjwin/article/details/109497305

    展开全文
  • MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google ...本文重点给大家介绍Java持久层框架MyBatis简单实例,非常不错,具有参考借鉴价值,感兴趣的朋友一起看下吧
  • iBATIS持久层框架开发

    2012-06-01 12:47:21
    iBATIS持久层框架开发
  • java持久层框架对比

    2012-02-10 15:07:52
    java持久层框架对比
  • Mybatis 的前身叫 iBatis,是一款优秀的持久层框架,用来访问数据库,做数据持久化操作。本质上只是对 JDBC 进行封装,简化 JDBC 繁琐的操作。《Mybatis 持久层框架》系列直播将以个人多年经验来快速讲解 Mybatis 的...
  • Hibernate也是目前Java开发中最为流行的数据库持久层框架,现已归JBOSS所有。 它的设计目标是将软件开发人员从大量相同的数据持久层相关编程工作中解放出来。无论是从设计草案还是从一个遗留数据库开
  • 持久层框架Mybatis

    2020-03-21 10:32:39
    MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的...
  • 自定义持久层框架本质就是对JDBC代码进行了封装,下面我们结合test的模块一起进行详细解说: 首先,在test模块编写配置文件,主要包括数据源和sql配置两部分: Test模块通过 “Resources.getResourceAsStream”...
  • 自定义数据库持久层框架kd-jdbc

    万次阅读 2020-08-31 19:07:46
    站在巨人的肩膀上前行,本文参考Mybatis设计思想,自定义了数据库持久层框架kd-jdbc,实现参数映射,sql解析,面向接口编程等功能。
  • 关于c++中litesql数据库持久层框架的源码,找了很久才找到的一份资料
  • MyBatis 本是apache的一个开源项目iBatis,接下来通过本文给大家介绍MyBatis持久层框架的用法知识小结,非常不错,具有参考借鉴价值,感兴趣的朋友一起学习吧
  • Mybatis学习(一):基础概念和基本应用一、一个简单自定义持久层框架demo 一、一个简单自定义持久层框架demo
  • MyBatis 是一个优秀的基于 java 的持久层框架,它内部封装了 jdbc,使开发者只需要关注 sql 语句本身,而不需要花费精力去处理加载驱动、创建连接、创建statement 等繁杂的过程。 MyBatis 通过 x...
  • 1、自定义持久层框架IPersistence解决JDBC存在的问题 使用配置文件解决了硬编码问题 使用连接池解决了频繁创建数据库连接问题## 标题 在simpleExecute中使用到了反射进行了参数的设置 在simpleExecute中使用了...
  • 仿照iBATIS 手写的持久层框架, 解析xml,反射、
  • 持久层框架-Mybatis

    千次阅读 2018-08-05 22:58:36
    持久层框架-Mybatis: 一:MyBatis介绍: 1:市场上目前的持久层框架: 1:Hibernate 2:jdbcTemplate,Spring提供的,不是很好用,也是面向sql语句的,和ibatis以及Mybatis有类似之处,但是没有这两者好用,也...
  • 浅谈MyBatis持久层框架

    千次阅读 2018-03-19 22:42:55
    浅谈MyBatis持久层框架

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 23,557
精华内容 9,422
关键字:

持久层框架