以服务于中国广大创业者为己任,立志于做最好的创业网站。

标签云创业博客联系我们

导航菜单

sqlmap外部代理ip池,ip代理池原理

1. Mybatis介绍

MyBatis最初是apache的开源项目ibatis。2010年,这个项目被apache software foundation移植到谷歌代码中,并更名为MyBatis。2013年11月搬到Github。

MyBatis是一个优秀的持久层框架,它封装了jdbc操作数据库的过程,让开发人员只需要关注SQL本身,不需要花费精力去处理复杂的jdbc进程代码,比如注册驱动、创建连接、创建语句、手动设置参数、检索结果集。

Mybatis将各种语句(语句、preparedStatemnt、CallableStatement)配置为通过xml或注释来执行,并通过映射java对象和语句中的sql来生成最终执行的sql语句。最后,mybatis框架执行sql,将结果映射到java对象并返回它们。

1.1. jdbc编程步骤:

1.加载数据库驱动程序

2.创建和获取数据库链接

3.创建一个jdbc语句对象

4.设置sql语句

5.设置sql语句中的参数(使用preparedStatement)

6.通过语句执行sql并获得结果

7.分析sql执行结果

8.释放资源(结果集、准备状态、连接)

1.1. jdbc问题总结如下:

1.数据库连接的频繁创建和释放导致系统资源的浪费,从而影响系统性能。如果使用数据库连接池,可以解决这个问题。

2.Sql语句被硬编码在代码中,这使得代码难以维护。在实际应用中,sql可能会发生很大的变化,而sql的变化需要改变java代码。

3.使用preparedStatement将参数传递给占有符号是有硬编码的,因为sql语句的where条件不确定,这可能是或多或少的,修改sql时需要修改代码,所以系统不容易维护。

4.结果集的解析存在硬编码(查询列名),sql的变化导致解析代码的变化,使得系统难以维护。如果数据库记录可以封装为pojo对象,那么解决这个问题是很方便的。

1. 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编程中对结果的解析处理过程。


实验

创建一个项目


创建lib文件夹,然后将jar包粘贴过去,然后build path


加入配置文件

配置文件按照上面的mybatis需要多个,第一个是总的配置文件sqlMapConfig.xml,这个配置文件配置之后的Mapper.xml,我们一般有一个数据库表,我们就创建一个Mapper.xml,这个可以帮助我们配置这个数据库相关的数据库操作,比如针对于User数据库,我们需要设置一个User.xml来专门帮助我们配置user表的相关操作:


<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!-- 写Sql语句 --><mapper namespace="test"><!-- 通过ID查询一个用户 --><select id="findUserById" parameterType="Integer" resultType="com.huanfeng.bean.User">select * from user where id = #{value}</select><select id="findUserByUsername" parameterType="String" resultType="com.huanfeng.bean.User">select * from user where username like "%"#{value}"%"</select><!-- 添加用户 --><insert id="insertUser" parameterType="com.huanfeng.bean.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.huanfeng.bean.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 = #{value}</delete></mapper>

我们可以看到首先,我们通过namespace来定义一个命名空间,然后每条sql语句都有id,之后就可以通过命名空间.id来表示详细的调用的sql语句了。


然后就写sql语句,sql语句就有四种,增删改查,查是select,删是delete,改是update,增insert


然后每个语句需要写上id,这个前面说过 ,然后还要写上ParameterType表示传递的参数类型,resultType表示查询结果的类型,所以select需要写上查询的类型,注意计算是查询结果返回是列表,这里的类型指的是列表中的每一个元素的类型,也就是泛型。


mybatis的强大之处在于它可以将将查询结果进行封装,这个关键点在于javaBean应该和数据库的字段名是一致的


#{}表示从传递过来的参数中取值,当参数只有一个的时候,此时怎么写都行,不一定要写value,但是要是传递一个对象的话,那么就得#{对象的属性了},


其中在插入语句中还有如下所示的配置


<selectKey keyProperty="id" resultType="Integer" order="AFTER">


select LAST_INSERT_ID()


</selectKey>


因为插入一个数据的时候,我们并不需要id,因为id是自增长的,所以不需要,但是我们想插入之后,获取到新插入用户的id,那么此时我们可以通过这种方式来获取到id,并且返回,其中keyPropeerty表示我们想要获取的属性,resultType表示类型,order表示执行顺序,肯定是先插入在获取id了,这个是不会有问题的。


配置好这个之后就可以调用这些sql语句了


<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><!-- 和spring整合后 environments配置将废除 --><environments default="development"><environment id="development"><!-- 使用jdbc事务管理 --><transactionManager type="JDBC" /><!-- 数据库连接池 --><dataSource type="POOLED"><property name="driver" value="com.mysql.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"/></mappers></configuration>

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!-- 写Sql语句 --><mapper namespace="test"><!-- 通过ID查询一个用户 --><select id="findUserById" parameterType="Integer" resultType="com.huanfeng.bean.User">select * from user where id = #{value}</select><select id="findUserByUsername" parameterType="String" resultType="com.huanfeng.bean.User">select * from user where username like "%"#{value}"%"</select><!-- 添加用户 --><insert id="insertUser" parameterType="com.huanfeng.bean.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.huanfeng.bean.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 = #{value}</delete></mapper>

配置日志文件/mybatis/src/log4j.properties


# Global logging configurationlog4j.rootLogger=DEBUG, stdout# Console output...log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

测试


package com.huanfeng.test;import java.io.IOException;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.huanfeng.bean.User;public class Demo {@Testpublic void testMybatis() throws Exception {//加载核心配置文件String resource = "sqlMapConfig.xml";InputStream in = Resources.getResourceAsStream(resource);//创建SqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);//创建SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();//执行Sql语句 User user = sqlSession.selectOne("test.findUserById", 10);System.out.println(user);}//根据用户名称模糊查询用户列表@Testpublic void testfindUserByUsername() throws Exception {//加载核心配置文件String resource = "sqlMapConfig.xml";InputStream in = Resources.getResourceAsStream(resource);//创建SqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);//创建SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();//执行Sql语句 List<User> users = sqlSession.selectList("test.findUserByUsername", "五");for (User user2 : users) {System.out.println(user2);}}//添加用户@Testpublic void testInsertUser() throws Exception {//加载核心配置文件String resource = "sqlMapConfig.xml";InputStream in = Resources.getResourceAsStream(resource);//创建SqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);//创建SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();//执行Sql语句 User user = new User();user.setUsername("huanfeng");user.setBirthday(new Date());user.setAddress("aia");user.setSex("男");int i = sqlSession.insert("test.insertUser", user);sqlSession.commit();System.out.println(user.getId());}//更新用户@Testpublic void testUpdateUserById() throws Exception {//加载核心配置文件String resource = "sqlMapConfig.xml";InputStream in = Resources.getResourceAsStream(resource);//创建SqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);//创建SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();//执行Sql语句 User user = new User();user.setId(27);user.setUsername("huanfeng9");user.setBirthday(new Date());user.setAddress("as");user.setSex("男");int i = sqlSession.update("test.updateUserById", user);sqlSession.commit();}//删除@Testpublic void testDelete() throws Exception {//加载核心配置文件String resource = "sqlMapConfig.xml";InputStream in = Resources.getResourceAsStream(resource);//创建SqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);//创建SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();sqlSession.delete("test.deleteUserById", 27);sqlSession.commit();}}

现在的任务

现在的任务就是如何将sqlSession配置好,然后在dao中直接使用它:其中sqlSession是由sqlSessionFactory工厂创建的,所以每次执行sql语句都应该创建一个sqlSession,也就是说我们可以公用一个工厂,但是需要有多个sqlSession




Mapper动态代理开发

真正写的时候,我们需要在service层获取到sqlSessionFactory,也就是只创建一个,然后传递到Dao层,Dao层只获取到工厂之后就创建sqlSession,然后就可以通过SqlSession进行sql执行了,其实我们还可以进一步的变化,我们可以看到在Dao层中每次都要通过SqlSesssionFactory来获取SqlSession,然后执行对应的增删改查方法,很费事,要想解决这个问题可以使用Mapper动态代理的开发模式。


具体来说建立一个接口,这个结构中的抽象方法需要满足以下几个条件,只要满足以下几个条件,mybatis就可以自动帮助我们创建如下所示的代码了:


SqlSession sqlSession = sqlSessionFactory.openSession();//执行Sql语句 User user = sqlSession.selectOne("test.findUserById", 10);System.out.println(user);

我们可以在接口中进行如下方式的操作:


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

如图所示这里面的抽象方法满足了以下的几个条件:


//接口 方法名 == User.xml 中 id 名


//返回值类型 与 Mapper.xml文件中返回值类型要一致


//方法的入参类型 与Mapper.xml中入参的类型要一致


//命名空间 绑定此接口


其中第四个命名空间绑定此接口的意思是说,命名空间应该是UserMapper的接口,那么此时才可以自动创建


<mapper namespace="com.huanfeng.mapper.UserMapper">


<!-- 通过ID查询一个用户 -->


<select id="findUserById" parameterType="Integer" resultType="com.huanfeng.bean.User">


select * from user where id = #{value}


</select>


<mapper>


之后我们就可以直接通过这个接口来创建代理对象,然后调用xml中配置好的sql语句了:


public void test1() throws IOException {//加载核心配置文件String resource = "sqlMapConfig.xml";InputStream in = Resources.getResourceAsStream(resource);//创建SqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);//创建SqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();//SqlSEssion帮我生成一个实现类 (给接口)UserMapper userMapper = sqlSession.getMapper(UserMapper.class);User user = userMapper.findUserById(10);System.out.println(user);}

注意这里其实是在测试,真实的是SqlSessionFactory传给dao层,Dao层只需要根据UserMapper来创建一个实现类,这个实现类会自动帮助我们实现这个接口内的方法,我们只需要调用对应的方法就可以了,和之前我们写的一样,这样我们就只用写接口就好了。


SqlMapConfig.xml配置文件

SqlMapConfig.xml中配置的内容和顺序如下:


properties(属性)


settings(全局配置参数)


typeAliases(类型别名)


typeHandlers(类型处理器)


objectFactory(对象工厂)


plugins(插件)


environments(环境集合属性对象)


environment(环境子属性对象)


transactionManager(事务管理)


dataSource(数据源)


mappers(映射器)


我们主要使用properties、typeAliases、mappers,其中properties可以配置一个配置文件,然后在xml中就可以使用这个配置文件中的内容了


jdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8jdbc.username=rootjdbc.password=root

typeAliases可以配置别名


<typeAliases>


<typeAlias type="com.huanfeng.bean.User" alias="User"/>


</typeAliases>


这里是将com.huanfeng.bean.User的别名设置为User,那么在mapper这些xml文件中就可以直接使用user了.实际中bean下面可能有多个javaBean,如果全部这样设置也有一些复杂,所以可以从包的角度来进行设计


<typeAliases>




<package name="com.huanfeng.bean"/>


</typeAliases>


如果这样设计了,那么bean下面类的别名就是这个类的类名,所以后面我们可以直接将com.huanfeng.bean.User的别名看成是User,user也可以了,别名大小写不敏感


除了我们自定义的这些类的别名,mybatis还会java中本身自带的一些类进行了别名设置,




byte Byte long Long short Short int Integer integer Integer double Double float Float boolean Boolean date Date decimal BigDecimal bigdecimal BigDecimal mapMap

这就解释了为什么我们前面直接使用Integer了。


1.1. mappers(映射器)

Mapper配置的几种方法:


我们前面学习了一种:<mapper resource="sqlmap/User.xml" />


还有一种方式,通过类来配置:


<mapper class=com.huanfeng.mapper.UserMapper"/>


此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。


和之前的别名配置一样,如果有多个mapper,那么就要配置多次,为了解决这个问题,我们可以使用包的配置方式:


<package name=com.huanfeng.mapper"/>


注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。这样mybatis就会自动去找了,和接口一样名称的配置文件了。一般常用这种方式