对于相同的SQL语句,Statement对象只会对其编译执行一次吗

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了对于相同的SQL语句,Statement对象只会对其编译执行一次吗相关的知识,希望对你有一定的参考价值。

参考技术A 一次编译,多次执行 参考技术B PreparedStatement比Statement有什么优势?查看全部2个回答

我来答

我来答

查看全部2个回答



dayinspring

来自科学教育类芝麻团 推荐于 2017-09-15

一、PreparedStatement相比于Statement,有三个优点:
一)代码的可读性和可维护性。
从代码来看,用PreparedStatement来代替Statement会使代码多出几行,但这样的代码无论从可读性还是可维护性上来说,都比直接用Statement的代码高很多档次。

二)PreparedStatement尽最大可能提高性能。
每一种数据库都会尽最大努力对预编译语句提供最大的性能优化,因为预编译语句有可能被重复调用,所以语句在被DB的编译器编译后的执行代码被缓存下来,那么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中(相当于一个函数)就会得到执行。这并不是说只有一个Connection中多次执行的预编译语句被缓存,而是对于整个DB中,只要预编译的语句语法和缓存中匹配,那么在任何时候就可以不需要再次编译而可以直接执行。而statement的语句中,即使是相同一操作,而由于每次操作的数据不同所以使整个语句相匹配的机会极小,几乎不太可能匹配。比如:
insert into tb_name (col1,col2) values ('11','22');
insert into tb_name (col1,col2) values ('11','23');
即使是相同操作但因为数据内容不一样,所以整个个语句本身不能匹配,没有缓存语句的意义,事实是没有数据库会对普通语句编译后的执行代码缓存。

MyBatis

为什么使用mybatis:

 在知道为什么使用mybatis之前,我们先了解java如何进行jdbc访问数据库的。第一是从连接池取出或者自己创建Connection对象,第二是从Connection对象中创建出Statement对象,第三,根据Statement对象去执行SQL语句,第四,获取执行SQL语句的返回结果并处理,第五,关闭数据库。在这几个步骤中,有产生这样的一些困扰:

 1. 对于一个项目来说,在上述的第四步中,需要查询的结果集的数据封装到实体类中,由于每次查询以及对应封装的类不同,因此需要编写不是功能不重复但过程都是一样的代码。对于一个项目来说,这就产生了冗余度。

 2. 在第三步中,都在代码中编写SQL语句,尽管JDBC帮我们解决了一部分编写SQL语句的问题,但这个还不够,假设我们需要根据传递的值来查询,那么如果传入的值为空,便会导致sql语句是错误的语句从而导致程序出错,并停止程序,这对于程序来说,是致命的。

 以上的困扰,都可以通过mybatis来帮我们解决(还有其他的一些困扰,不过目前笔者感触最深的便是这两个),当然也可以使用编写程序的方式来帮我们解决问题,毕竟解决问题的方式不仅仅只有一种,就是要看那种解决问题的方式更好了。

  

myBatis访问数据库步骤:

 myBatis访问数据库与JDBC访问数据库有很大的不同,对于myBatis而言,访问数据库在代码上只有简单的几句,其余的都是在配置文件中实现,比如说连接数据库,sql语句,对象关系映射(orm)都是在配置文件中完成的。因此对于myBatis来说,配置文件是至关重要的。

 除了配置文件,myBatis是通过sqlSessionFactoryBuilder类来创建sqlSessionFactory对象,并让sqlSessionFactory对象来创建sqlSession。

  SqlSessionFactoryBuilder 相当于DriverManager类,不过DrivarManager是用来返回connection对象,而SqlSessionFactoryBuilder是用来返回SqlSessionFactory对象。

  SqlSessionFactory  相当于Connection类,不过Connection类是用来返回Statement对象,而SqlSessionFactory是用来返回SqlSession对象。

  SqlSession 相当于Statment类,用来执行SQL语句,但由于mybatis的SQL语句是写入配置文件中的,因此有两种方式来执行SQL语句。

   第一种方式:将编写SQL语句的配置文件与接口对应,让SqlSession调用getMapper()方法来实例化接口,并让接口对象去调用接口的方法。

   第二种方式:直接使用配置文件种编写好的SQL语句。

  通常都是选择第一种方式,尽管第一种方式比第二种方式多了一个编写接口的步骤,但却可以让程序看起来比较完整。

 

 myBatis-fonfig.xml 文件: myBatis最主要的配置文件

<?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>
    <!-- 存放连接数据库信息 -->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/test?characterEncoding=utf8" />
                <property name="username" value="root" />
                <property name="password" value="root" />
            </dataSource>
        </environment>
    </environments>
    
    <!-- 存放编写SQL的配置文件 -->
    <mappers>
        <mapper resource="adminUserMapper.xml"/>
    </mappers>
</configuration>

 

 SQL配置文件:

<?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.AdminUserMapper">
    <!-- 
        下面parameterType是代表执行SQL语句前需要传入参数的类型,只能指定一个,如果SQL语句中有多个参数,可以使用类以及map数据类型
        resultType是代表执行SQL语句后的返回类型,只能指定一个,如果SQL语句中返回结果有多列,可以使用类以及map数据类型
     -->
    <select id="selectAllAdminUser" resultType="myBatis.AdminUser">
        select * from tb_adminuser
    </select>
    <select id="selectAdminUserByID" parameterType="int" resultType="myBatis.AdminUser">
        SELECT * FROM tb_adminuser where id = #id
    </select>
    <insert id="insertAdmidUser" parameterType="myBatis.AdminUser" useGeneratedKeys="true" keyProperty="id">
        insert into tb_adminuser(id,aName,aPwd,adminType,isDelete,isValid)
        values(#id,#aName,#aPwd,#adminType,#isDelete,#isValid);
    </insert>
    <delete id="deleteAdminUserById" parameterType="Integer">
        delete from tb_adminuser where id = #id;
    </delete>
    <update id="updateAdminUserById" parameterType="adminUser">
        update tb_adminuser 
        set aUser=#aUser,aPwd=#aPwd,adminType=#adminType,isDelete=#isDelete,isValid=#isValid
        where id=#id
    </update>
</mapper>

  实体类:

public class AdminUser 
    Integer id;
    String aName;
    String aPwd;
    Integer adminType =0;
    Integer isDelete = 0;
    Integer isValid = 0;
    //get与set还有toString方法省略

  mybatisTest类:

public class MyBatisTest 
    private static SqlSessionFactory sqlSessionFactory = null;
    private SqlSession sqlSession = null;
    private AdminUserMapper adminUserMapper = null;
    
    public void queryAdminUserById()
        AdminUser adminUser = sqlSession.selectOne("adminUserMapper.selectAdminUserByID",1);
        System.out.println(adminUser);
    
    
    public void queryAllAdminUser()
        List<AdminUser> adminUserList = sqlSession.selectList("selectAllAdminUser");
        System.out.println(adminUserList);
    
    
    public void insertOneAdminUser()
        AdminUser adminUser = new AdminUser();
        adminUser.setaName("HJJ");
        adminUser.setaPwd("123456");
        sqlSession.insert("insertAdmidUser", adminUser);
        sqlSession.commit();
    
    
    public void insertMoreAdminUser()
        for(int i=0;i<5;i++)
            AdminUser adminUser = new AdminUser();
            adminUser.setaName("HJL_"+i);
            adminUser.setaPwd("123456_"+i);
            sqlSession.insert("insertAdmidUser", adminUser);
        
        sqlSession.commit();
    
    
    public void deleteAdminUserById()
        sqlSession.delete("deleteAdminUserById", 3);
        sqlSession.commit();
    

    public MyBatisTest(String resources)
        try
            File file = new File(resources);
            System.out.println(file.getAbsolutePath());
            InputStream in = Resources.getResourceAsStream(resources);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
            sqlSession = sqlSessionFactory.openSession();
            System.out.println(sqlSessionFactory+","+sqlSessionFactory.hashCode());
            System.out.println(sqlSession+","+sqlSession.hashCode());
        catch(Exception e)
            e.printStackTrace();
            
    
    
    public static void main(String[] args) 
        // TODO Auto-generated method stub
        String resource = "mybatis-config.xml";
        MyBatisTest myBatisTest = new MyBatisTest(resource);
        myBatisTest.queryAdminUserById();
        myBatisTest.queryAllAdminUser();
        myBatisTest.insertOneAdminUser();
        myBatisTest.insertMoreAdminUser();
        myBatisTest.deleteAdminUserById();
    

  上述代码中,实现了对数据库test下对tb_adminuser表进行了简单的增删改查操作。运行结果值显示查询SQL的操作结果,新增修改和删除的结果是要去看数据库

技术图片
D:\programme\javaEE\project\fzkjshop_project\fzkjshop_test\mybatis-config.xml
org.apache.ibatis.session.defaults.DefaultSqlSessionFactory@725bef66,1918627686
org.apache.ibatis.session.defaults.DefaultSqlSession@2aaf7cc2,716143810
AdminUser [id=1, aName=admin, aPwd=admin, adminType=1, isDelete=0, isValid=0]
[AdminUser [id=1, aName=admin, aPwd=admin, adminType=1, isDelete=0, isValid=0], AdminUser [id=4, aName=HJL_0, aPwd=123456_0, adminType=0, isDelete=0, isValid=0], AdminUser [id=5, aName=HJL_1, aPwd=123456_1, adminType=0, isDelete=0, isValid=0], AdminUser [id=6, aName=HJL_2, aPwd=123456_2, adminType=0, isDelete=0, isValid=0], AdminUser [id=7, aName=HJL_3, aPwd=123456_3, adminType=0, isDelete=0, isValid=0], AdminUser [id=8, aName=HJL_4, aPwd=123456_4, adminType=0, isDelete=0, isValid=0], AdminUser [id=9, aName=HJJ, aPwd=123456, adminType=0, isDelete=0, isValid=0], AdminUser [id=10, aName=HJJ, aPwd=123456, adminType=0, isDelete=0, isValid=0], AdminUser [id=11, aName=HJJ, aPwd=123456, adminType=0, isDelete=0, isValid=0], AdminUser [id=12, aName=HJJ, aPwd=123456, adminType=0, isDelete=0, isValid=0]]
View Code

  

  Mapper.xml配置文件是记录SQL语句,该文件是可以随便命名的,但通常来说,一个mapper.xml的配置文件都是指向同一个数据库的表,因此都是以数据库表对应java实体类的名称来命令,即XXXXMapper.xml文件,上述就是adminUserMapper.xml配置文件,该配置文件的SQL语句都是以tb_adminUser表展开,而该表对应java的实力类便是AdminUser。

  Mapper.xml配置文件中,mapper标签的namespace属性:该属性的作用是对mapper标签取个名称。

<mapper namespace="myBatis.AdminUserMapper"></mapper>

  该属性的用途便是,当两个不同的mapper.xml配置文件,mapper标签下都用两个select标签,但这两个标签的id属性值都是一样的,那么程序是调用哪个id值的SQL语句,因为区分不出,因此程序会报错,为了区别,一般是 ’namespace属性值.id值‘ 来给程序区分到底调用的是。即在上述java代码中,最好用的便是如下:

AdminUser adminUser = sqlSession.selectOne("selectAdminUserByID",1); //

AdminUser adminUser = sqlSession.selectOne("adminUserMapper.selectAdminUserByID",1); //后

  在mapper标签下,有select ,insert,delete ,update这四个标签,分别对应着数据库的查询,新增,删除与修改操作。在这四个标签中,都有以下的属性:

   id:用于对该标签进行命名,用来区分与其他的相同的标签

   parameterType: sql传入参数的数据类型

   resultType:执行sql语句后返回结果的数据类型,该数据类型要与返回结果的数据类型一致。

  在select等四个标签中,内容都是sql语句,若是传入值,是用#参数名来代替该值。一般SQL有多个参数名时,传入参数得类型只有两种,一个是类,一个是map,值得注意得是,参数名与类得属性或者map得key值要一致,否则是找不到传入该参数得具体值,导致程序出错。传出结果也是一样,若将结果赋值给了类或者map对象时,该类的属性名与map的key值不一致时,程序也会报错。

  1. 为了让java实体属性名可以与数据库的表的字段不一致,mapper标签下有个resultMap的标签,该标签可以让java实体类属性名与数据库表的字段形成对映关系。

  2. 在select等四个标签中,运行程序传入sql语句中的一部分语句,并与标签中的sql语句拼接形成正确的sql语句。一般使用传递sql语句的数据类型为map数据类型,在标签中,用$参数名来代表sql的部分语句。

  3. 在select等四个标签中,很多时候sql语句会有挺多重复的,比如说,查询的时候,如果都是查询该表的所有列,但因为查询的条件不同,所产生了很多的select标签,但这些select标签中SQL语句的前部分都是相同的,即 select * from tb_table where 或者更简单点的 select * from tb_table,编写这些时会对配置文件产生冗余,因此,可以将这些sql语句提取出来,在mapper标签下有个sql的标签,将提取的部分sql语句放入sql标签中,在select等四个标签下有个include的标签,该标签是用来提出sql标签的部分sql语句的内容

  与传入sql语句不同,传入sql部分语句是从java程序中以参数的形式出入到配置文件中的sql语句,并进行拼接;而该sql部分语句提取是将这部分sql语句进行封装。

  4. 当传入参数为空值时的解决办法,sql语句最怕的便是该sql语句条件中某个字段对空值来进行运算,借助程序对该sql语句出现空值的解决办法,那便是当给sql语句进行赋值值,先判断该参数是否为空,如果为空值,sql语句就去掉该条件,若不是为空,便可在sql语句中添加该条件。在配置文件中也可以做到,在select等四个标签下,有个if的标签,可以根据if来判断执行的是那条sql语句。避免了sql语句中出现空值的情况。

  5. where 标签

  6. chose标签

  7. bind标签来对like语句进行适配

  8. set标签

  9 forEach标签

 mybatis-config.xml文件:mybatis-config最常用的是environments与mappers标签。

  environments是用来放置数据源的一个标签,可以放置很多的数据源,即可以与多个数据库相互连接

  说到多种数据源连接,那就要说以下mybatis-config.xml配置文件下的databaseIdProvider标签了,该标签的作用是给连接的数据库弄个别名,如下:

  transationManager标签,该标签是用于连接数据库时,是以事务的形式提交并执行sql语句,还是以自动执行的形式来提交并执行sql语句

  dataSource标签的type属性,该属性指向一个数据库连接池,POOLED是mybatis的连接池,如要使用第三方的连接池也很简单,编写连接第三方的连接java代码,并让type属性的值指向该代码的全类名

  mappers标签,里面存放的mapper.xml文件的映射关系,mybatis-config.xml根据该mappers标签找到对应的mapper标签,从而找到对应的mapper.xml配置文件,并进行数据库的SQL操作,配置mappers标签可以有四种方式

   第一种,如上述所属,直接获取mapper.xml配置文件,由于上述是将mapper.xml配置文件放置于mybatis-config.xml配置文件下,因此没有写‘包名.mapper.xml’

   第二种,通过mapper.xml放置的包来检索对应的mapper.xml文件

   第三种,指定接口名称,该接口于mapper.xml是对应的关系,因此mapper标签指向了接口,接口指向了mapper.xml配置文件

   第四种,使用绝对路径的写法

  用时候,在mybatis-config.xml配置文件种,将指定的数据库连接参数写入不是很好的,可以使用将连接数据库的配置信息单独存放在一个文件里,让mybatis-config.xml文件的连接数据库参数从该配置信息中获取。实现以上的目前,可以使用properties标签,该标签中有个resource属性,该属性的值时配置信息的相对路径

  使用typeAliases单独配置别名,用使用在mapper.xml配置文件中,select属性的parameterType与resultType的值是为对应实体类的全类名,而如果该实体类的全类名名称太长的话,容易让配置位置文件显得很重中,因此可以用typeAliases标签用简单的名称与该实体类的全类名形成对应关系,在mapper.xml文件中使用该简单的名称便可,该标签不仅仅是应用在该地方,只要mybatis-config.xml与mapper.xml配置文件中有用到全类名的值都可以使用该标签进行对实体类的全类名配置别名。该typeAliases有两种配置别名格式

    第一种,一个实体类对应一个别名 使用的是typeAlias标签,alias属性值为别名的名称,type属性值为实体类的全类名

    第二种,以一个包作为导入源,该包下的全部实体类都配置别名,该别名与实体类的类名是一致的。好处是可以解决一个一个配置实体类别名的麻烦,使用的是package标签,该标签的name属性是指向包名

 

mapper.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属性值:该属性值是可以随便定义,但若要使用面向接口编程,该属性值要与对应接口的全类名一致,以形成对应的关系
 -->
<mapper namespace="myBatis.AdminUserMapper">
    <!-- 
        下面parameterType是代表执行SQL语句前需要传入参数的类型,只能指定一个,如果SQL语句中有多个参数,可以使用类以及map数据类型
        resultType是代表执行SQL语句后的返回类型,只能指定一个,如果SQL语句中返回结果有多列,可以使用类以及map数据类型
     -->
     <!-- 
         resultMap标签可以让数据库表与实体类的属性形成对应关系,默认的情况是实体类的属性名与表的字段一致
         使用resultMap标签可以让实体类的属性名在跟表的字段名不一致的情况下形成对应关系
         不过最好还是让实体类的属性名与表的字段名一致,
      -->
<!--      
    <resultMap type="myBatis.AdminUser" id="adminUser">
         <result column="id" property="adminUserId"/>
         <result column="aName" property="adminUserName"/>
         <result column="aPwd" property="aPassword"/>
         <result column="adminType" property="type"/>
         <result column="isValid" property="valid"/>
         <result column="isDelete" property="delete"/>
     </resultMap> 
-->
     
     <!-- sql标签,可以提出sql部分重复的语句 -->
     <sql id="select">
         select * from tb_adminuser
     </sql>
     
     <!-- 
         select,update,insert,delete这四个标签都是用来执行对应的SQL语句
         在上述4个标签中,都有以下的属性:
             id:用于标识,区分于其他相同标签
             paramterType:用于传入参数的数据类型
             returnType: 用于传出结构的数据类型
             databaseId: 用于选择数据库
             resultMap: 该属性是否传入值根据mapper.xml文件是否有定义resultMap标签
         由于4个标签中的SQL可以随意的拼接,只要拼接的SQL语句是真确的便可,因此在上述4个标签中,可以在标签内定义以下的标签:
             include标签: 与sql标签连用,用于提出sql标签的部分sql语句
             if标签: 用于判断
             where标签:用于多个条件的SQL语句,一般也与if标签连用
             forEach标签:循环,该标签是适用于条件中有in关键字的SQL语句
             choose标签:选择,用于多个条件中,一般与where标签连用
             set标签:使用在update语句中,一般与if标签连用,作用是修改一行记录时,可以根据传入的参数而修改对应值
             bind标签:用于拼接两个字符串,由于每个数据库拼接两个字符串的关键字或者符号不同会导致使用该sql语句不具有很高的一致性
             $:这个不是标签,不过$可以让SQL部分的语句有程序那边传入进来,并完成拼接
             #:用于传递参数,
      -->
    <select id="selectAllAdminUser" resultType="AdminUser">
        <include refid="select" />
    </select>
    <select id="selectAdminUserByID" parameterType="list" resultType="AdminUser" databaseId="">
        <if test="list==null or list.size==0">
            <include refid="select" />
        </if>
        <if test="list!=null and list.size>0">
            <include refid="select" />
            where id in
            <foreach collection="list" item="item" index="index" open="(" separator="," close=")">
                #item
            </foreach>
        </if>
    </select>
    <insert id="insertAdmidUser" parameterType="AdminUser" useGeneratedKeys="true" keyProperty="id">
        insert into tb_adminuser(id,aName,aPwd,adminType,isDelete,isValid)
        values(#id,#aName,#aPwd,#adminType,#isDelete,#isValid);
    </insert>
    <delete id="deleteAdminUserById" parameterType="Integer">
        delete from tb_adminuser where id = #id;
    </delete>
    <update id="updateAdminUserById" parameterType="AdminUser">
        update tb_adminuser 
        set aUser=#aUser,aPwd=#aPwd,adminType=#adminType,isDelete=#isDelete,isValid=#isValid
        where id=#id
    </update>
</mapper>

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>
    <!-- 引入数据库的配置信息,可以参考第一个environment与第二个environment的区别,这两个配置的数据库是一致的 -->
    <properties resource="c3p0.properties"/>
    
    <!-- 配置别名 -->
      <typeAliases>
        <package name="myBatis"/>
    </typeAliases>
    
    <!-- 存放连接数据库信息 -->
    <!-- environments 的default属性作用是默认使用的是那一种数据库,该属性值指向environment的id属性值 -->
    <environments default="dev">
        <!-- 可以配置多个数据库信息,mysql与orcle或者sqlServer等多个数据库 -->
        <environment id="development">
            <!-- 配置该数据库是使用事务还是自动更改 type属性值为JDBC 代表开启事务,值为MANAGED代表开启自动提交-->
            <transactionManager type="JDBC"/>
            <!-- type值指向数据库连接池,POOLED是mybatis提供的连接池,可以使用第三方的连接池,
                  但需要在现在代码中创建该连接池,type属性值为创建该连接池的全类名 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/test?characterEncoding=utf8" />
                <property name="username" value="root" />
                <property name="password" value="root" />
            </dataSource>
        </environment>
        
           <environment id="dev">
            <transactionManager type="JDBC"/>
             <dataSource type="myBatis.c3p0DataSourceFactory">
                <property name="driverClass" value="$c3p0.driverClass" />
                <property name="jdbcUrl" value="$c3p0.jdbcUrl" />
                <property name="user" value="$c3p0.user" />
                <property name="password" value="$c3p0.password" />         
                <property name="maxPoolSize" value="$c3p0.maxPoolSize"/>        
                <property name="initialPoolSize" value="$c3p0.initialPoolSize"/>
             </dataSource>
        </environment>
    </environments>
    
    <!-- 
        根据是否有多个environment标签来进行配置该标签,该标签的作用是将对应的sqlid值根据数据库的不同而执行不同的sql语句
        使用该标签后,一般与mapper.xml配置文件下的select等四大标签的databaseId属性值连用
        注意的是,该type的值最好不要与select等四个标签参数名一致
    -->
    <databaseIdProvider type="DB_VENDOR">
        <!-- 
            该标签下有个 property的标签,这个标签有两个属性,一个是name属性,一个是value属性
            name属性,该属性的值是不能随意乱写的,而且还属性值是区分大小写的,
                如果要使用mysql数据库,填入的是MySQL,如果使用oracle数据库填入的属性值为Oracle
            value属性,该属性是对应数据库的别名,可以随意填写,
            并且若select等四个标签使用databaseId属性时,该属性的对应值为指定数据库的value属性值
        -->
    </databaseIdProvider>
    
    <!-- 存放编写SQL的配置文件 -->
    <mappers>
        <mapper resource="adminUserMapper.xml"/>
    </mappers>
</configuration>

 使用c3p0连接池:

import org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory;
import com.mchange.v2.c3p0.ComboPooledDataSource;

public class c3p0DataSourceFactory extends UnpooledDataSourceFactory
    public c3p0DataSourceFactory()
        this.dataSource=new ComboPooledDataSource();
    

使用接口开发:

import java.util.List;

public interface AdminUserMapper 
    public List<AdminUser> selectAllAdminUser();
    public void insertAdmidUser(AdminUser adminUser);
    public AdminUser selectAdminUserByID(List list);
    public void deleteAdminUserById(Integer id);
    public void updateAdminUserById(AdminUser adminUser);

 实体类:

public class AdminUser 
    Integer id;
    String aName;
    String aPwd;
    Integer adminType =0;
    Integer isDelete = 0;
    Integer isValid = 0;
    //省略getter,setter以及toString方法

使用mabatis操作数据库

public class MyBatisTest 
    private static SqlSessionFactory sqlSessionFactory = null;
    private SqlSession sqlSession = null;
    private AdminUserMapper adminUserMapper = null;
    
    public void queryAdminUserById()
        List<Integer> idList = new ArrayList<Integer>();
        idList.add(1);idList.add(5);
        List<AdminUser> adminUserList = sqlSession.selectList("selectAdminUserByID",idList);
        System.out.println(adminUserList);
    
    
    public void queryAllAdminUser()
        List<AdminUser> adminUserList = sqlSession.selectList("selectAllAdminUser");
        System.out.println(adminUserList);
    
    
//    public void insertOneAdminUser()
//        AdminUser adminUser = new AdminUser();
//        adminUser.setAdminUserName("HJJ");
//        adminUser.setaPwd("123456");
//        sqlSession.insert("insertAdmidUser", adminUser);
//        sqlSession.commit();
//    
    
//    public void insertMoreAdminUser()
//        for(int i=0;i<5;i++)
//            AdminUser adminUser = new AdminUser();
//            adminUser.setAdminUserName("HJL_"+i);
//            adminUser.setaPwd("123456_"+i);
//            sqlSession.insert("insertAdmidUser", adminUser);
//        
//        sqlSession.commit();
//    
    
    public void deleteAdminUserById()
        sqlSession.delete("deleteAdminUserById", 3);
        sqlSession.commit();
    
    
    public void selectAll()
        List<AdminUser> adminUserList = adminUserMapper.selectAllAdminUser();
        System.out.println(adminUserList);
    
    
    public void selectOne()
        List<Integer> idList = new ArrayList<Integer>();
        idList.add(4);
        AdminUser adminUser = adminUserMapper.selectAdminUserByID(idList);
        System.out.println(adminUser);
    
    
//    public void insert()
//        AdminUser adminUser = new AdminUser();
//        adminUser.setAdminUserName("HJJ");
//        adminUser.setaPwd("123456");
//        
//        adminUserMapper.insertAdmidUser(adminUser);
//        sqlSession.commit();
//    
    
//    public void insertMore()
//        for(int i=0;i<5;i++)
//            AdminUser adminUser = new AdminUser();
//            adminUser.setAdminUserName("HJL_"+i);
//            adminUser.setaPwd("123456_"+i);
//            adminUserMapper.insertAdmidUser(adminUser);
//        
//        sqlSession.commit();
//    
    
    
    
    public MyBatisTest(String resources)
        try
            File file = new File(resources);
            System.out.println(file.getAbsolutePath());
            InputStream in = Resources.getResourceAsStream(resources);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
            sqlSession = sqlSessionFactory.openSession();
            adminUserMapper = sqlSession.getMapper(AdminUserMapper.class);
            System.out.println(sqlSessionFactory+","+sqlSessionFactory.hashCode());
            System.out.println(sqlSession+","+sqlSession.hashCode());
            System.out.println(adminUserMapper+","+adminUserMapper.hashCode());
        catch(Exception e)
            e.printStackTrace();
            
    
    
    public static void main(String[] args) 
        // TODO Auto-generated method stub
        String resource = "mybatis-config.xml";
        MyBatisTest myBatisTest = new MyBatisTest(resource);
        myBatisTest.queryAdminUserById();
        myBatisTest.queryAllAdminUser();
//        myBatisTest.insertOneAdminUser();
//        myBatisTest.insertMoreAdminUser();
//        myBatisTest.deleteAdminUserById();
        
//        myBatisTest.insert();
        myBatisTest.selectOne();
    

 

 

  

以上是关于对于相同的SQL语句,Statement对象只会对其编译执行一次吗的主要内容,如果未能解决你的问题,请参考以下文章

Java PrepareStatement

statement 对象执行sql语句

十四周总结

JDBC——Statement执行SQL语句的对象

prepareStatement与Statement的区别

JDBCl链接中Statement