原生态JDBC程序问题总结:
1、数据库连接,使用时就创建,不使用立即释放。该操作是对数据库进行频繁连接开启和关闭,造成数据库资源浪费,影响数据库性能。
解决:使用数据库连接池管理数据库连接。
2、将sql语句硬编码到java代码中,若sql语句修改,需要重新编译java代码,不利于维护。
解决:将sql语句配置在xml配置文件中,即使sql变化,也不需要对java代码进行重新编译。
3、在向PreparedStatement中设置参数时,对占位符位置和设置参数值,硬编码在Java代码中,不利于维护。
解决:将sql语句及占位符和参数全部配置在xml配置文件中。
4、从ResutSet中遍历结果集数据时,存在硬编码,将获取表的字段进行硬编码,不利于维护。
解决:将查询的结果集,自动映射成Java对象。
Mybatis简述:
mybatis是一个持久层框架,是Apache下的顶级项目。mybatis的前身是ibatis。mybatis开始是托管到goolecode下,再后来托管到github下(https://github.com/mybatis/mybatis-3/releases)
mybatis让程序将主要精力放在sql上,通过mybatis提供的映射方式,自由灵活生成(半自动)满足需要sql语句。
mybatis可以将向PreparedStatement中的输入参数自动进行输入映射,将查询结果集灵活映射成Java对象(输出映射)
Mybatis框架原理:
SqlMapConfig.xml:mybatis的全局配置文件,名称不固定;配置了数据源、事务等mybatis运行环境。mybatis还需要配置mapper.xml、mapper.xml等,mapper.xml就是映射文件(配置sql语句)。
SqlSessionFactory:会话工厂。根据配置文件创建工厂。作用就是创建SqlSession。
SqlSession:会话。是一个接口,面向用户的接口。作用,进行crud数据库操作。
Executor:执行器。是一个接口,存在俩个实现:基本执行器、缓存执行器。作用,SqlSession内部通过执行器进行crud数据库操作。
mapped statement:底层封装对象。作用,对crud数据库操作存储封装,包含sql语句、输入参数、输出结果类型。
Mybatis入门程序:
映射文件:
1、映射文件命名:User.xml(原始ibatis命名。),mapper代理开发映射文件名称为:XXXMapper。如:UserMapper.xml
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?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进行分类化管理,理解sql隔离 注意:使用mapper代理方法开发,namespace有特殊重要的作用 --> <mapper namespace="test"> <!-- 再映射文件中配置很多的sql语句: select标签执行数据库查询 id:标识映射文件中的sql,将sql语句封装到mappedStatement对象中,所以将id称为statement的id parameterType:指定输入参数的类型。 resultType:输出类型。指定sql输出结果的所映射的java对象类型,select指定resultType表示将单条记录映射成的Java对象。 #{}:表示一个占位符号 #{id}:其中的id表示接入输入的参数,参数名称就是id,如果输入参数是简单类型,#{}中的参数名可以任意;可以是value或其他名称。 --> <select id="findUserById" parameterType="参数的类型。如:int" resultType=""> select * from t_User where id=#{id} </select> <!-- 无论sql语句返回的是单条记录或多条记录都是所映射的Java对象类型 ${}:表示拼接sql串,将接收到参数的内容不加任何修饰拼接在sql中。使用${}拼接sql,会引起sql注入。 ${value}:接收输入参数的内容,若传入类型是简单类型,${}中只能使用value --> <select id="findUserByName" parameterType="String" resultType="cn.ccir.mybatis.entity.User"> select * from t_User where username like '%${value}%' </select> <!-- 添加配置 parameterType:指定输入参数类型是pojo(普通的java对象) #{}中指定pojo的属性名,接收到pojo对象的属性值,mybatis通过OGNL获取对象的属性值 --> <insert id="insertUser" parameterType="cn.ccir.mybatis.entity.User"> <!-- 将插入数据的自增主键值返回,返回到user对象中 select LAST_INSERT_ID():得到刚insert的记录主键值,只适用于自增主键 keyProperty:将查询到主键值设置到parameterType指定对象的那个属性 order:select LAST_INSERT_ID()的执行顺序,相对于insert语句来说它的指定顺序 resultType:指定select LAST_INSERT_ID()的结果类型 -->> <selectKey keyProperty="id" order="AFTER" resultType="java.long.Integer"> select LAST_INSERT_ID() </selectKey> <!-- 或 --> <!-- 将插入数据的非自增主键值返回,uuid()得到主键,在insert语句之前执行。 通过uuid()得到主键,将主键设置到user对象的id属性中。其次在insert执行时,从user对象中去除id属性值 --> <selectKey keyProperty="id" order="BEFORE" resultType="java.long.String"> select uuid()(mysql)/select 序列名.nextval()(oracle) </selectKey> insert into user(id,username,birthday,sex,address)value(#{id},#{username},#{birthday},#{sex},#{address}) </insert> <!-- 删除配置 -->> <delete id="deleteUserById" parameterType="java.lang.Integer"> delete from t_User where id=#{id} </delete> <!-- 修改配置 parameterType:指定user对象,包括id和更新信息。注:id必须在User对象中存在 #{}:从输入User对象中获取id属性值 -->> <update id="updateUserById" parameterType="cn.ccir.mybatis.entity.User"> update t_User set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id} </update> </mapper>
2、在SqlMapConfig.xml加载映射文件。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?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> <!-- 和spring整合后environments配置将废除 --> <environments default="development"> <environment id="development"> <!-- 使用jdbc事务管理,事务控制由mybatis --> <transactionManager type="JDBC"></transactionManager> <!-- 数据库连接池,有mybatis管理 --> <dataSource type="POOLED"> <property name="driver" value=""/> <property name="url" value=""/> <property name="username" value=""/> <property name="password" value=""/> </dataSource> </environment> </environments> <!-- 加载映射文件 --> <mappers> <mapper resource="UserMapper.xml"/> </mappers> </configuration>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public void findUserById() throws IOException{ //加载配置文件得到流对象 String resource="SqlMapConfig.xml"; InputStream inputStream=Resources.getResourceAsString(resource); //创建会话工厂 SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream); //通过工厂得到SqlSession SqlSession sqlSession=sqlSessionFactory.openSession(); //通过SqlSession来curd数据库 //第一个参数:映射文件中是statement的id,等于namespace+"."+statement的id //第二个参数:指定和樱色和文件中所匹配的parameterType类型的参数。 //sqlSession.selectOne结果是与映射文件中所匹配的resultType类型的对象。查询出的是一条记录。 //sqlSession.selectList查询出的是多条记录。 User user = sqlSession.selectOne("test.findUserById",parameter,1); //方法名:findUserByName List<User> list = sqlSession.selectList("test.findUserByName","条件值"); //添加 方法名: insertUser User user=new User(); user.setUsername(""); user.setBirthday(new Date()); user.setSex(""); user.setAddress(""); ...... sqlSession.insert("test.insertUser",user); sqlSession.commit();//提交事务 //删除 方法名:deleteUserById sqlSession.delete("test.deleteUserById",1); sqlSession.commit();//提交事务 user.getId();//获取主键id值。 //修改 方法名:updateUserById User user=new User(); user.setId(""); user.setUsername(""); user.setBirthday(new Date()); user.setSex(""); user.setAddress(""); ...... sqlSession.insert("test.updateUserById",user); sqlSession.commit();//提交事务 //释放资源 sqlSession.close(); }
#{} 与 ${}:
#{}:表示一个占位符,接收输入参数,类型可以时简单类型、pojo(简单java对象)、hashmap。
若#{}接收简单类型,#{}中可以写成value或其他名称。
若#{}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性。
${}:表示一个拼接符号,会引用sql注入,所以不建议使用${}。接收输入参数,类型可以时简单类型、pojo、hashmap。
若${}接收简单类型,${}中只能写成value。
若${}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性。
Mybatis和Hibernate本质区别及应用场景:
Hibernate:是一个标准的ORM框架(对象关系映射)。入门门槛较高,不需要书写sql语句,hibernate会自动生成。对sql进行优化、修改比较困难。
Mybatis:专注是sql本身,需要书写sql语句,sql的优化、修改比较方便。Mybatis不是一个完全的ORM框架,虽然可以实现映射(输入、输出框架),但还需要书写sql。