一、问题引入
public class JdbcTest {
public static void main(String[] args) {
Connection connection = null;
//预编译的Statement
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
// 加载驱动
Class.forName("com.mysql.jdbc.Driver");
// 连接服务器
connection = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/Test", "root", "123456");
String sqlStr = "Select * From users Where id = ?";
preparedStatement=connection.prepareStatement(sqlStr);
preparedStatement.setInt(1, 2);
resultSet=preparedStatement.executeQuery();
while(resultSet.next()){
int id=resultSet.getInt("id");
String name=resultSet.getString("name");
String password=resultSet.getString("password");
System.out.println(id+"\t"+name+"\t"+password);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
if(resultSet!=null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(preparedStatement!=null){
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection!=null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
String sqlStr = "Select * From users Where id = ?";
if(resultSet!=null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(preparedStatement!=null){
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection!=null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
3.Statement设置参数时候,对于参数的位置通过硬编码指定
preparedStatement.setInt(1, 2);
4.遍历结果集,resultset硬编码指定列名
while(resultSet.next()){
int id=resultSet.getInt("id");
String name=resultSet.getString("name");
String password=resultSet.getString("password");
System.out.println(id+"\t"+name+"\t"+password);
}
二、Mybatis介绍
MyBatis 本是apache的一个开源项目iBatis,2010年这个项目由apachesoftware foundation 迁移到了google code,并且改名为MyBatis 。
iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAO)。
Mybatis是支持定制化Sql、存储过程以及高级映射的优秀的持久层框架。Mybatis避免了几乎所有的JDBC代码和手工设置参数以及读取结果集。使开发者只需要关注Sql本身,而不需要花太多精力去处理如何注册驱动、创建connection、statement、手动设置参数、结果集检索等繁杂的过程代码。
Mybatis使用简单的XML或者注解来配置和映射基本体,将接口和普通的Java对象映射成数据库中的记录。
注:Mybatis是一个不完全的orm框架(可以进行对象关系映射,但映射不彻底,需要手动写sql语句)。
Hibernate是一套完全优秀的orm框架,可以完全由java对象到关系映射,不需要手动编写sql。
三、Mybatis框架
1、 SqlMapConfig.xml是mybatis的核心配置文件。
配置了数据源(连接池),事务
mapper.xml是mybatis的映射文件
2、 sqlSessionFactory会话工厂
用户产生会话SqlSession
3、 SqlSession会话
面向用户的门面接口,主要是为了操作数据库
Sqlsession内部是通过executor操作数据库
4、 Executor执行器
Executor是一个底层的封装对象,用户看不到
Executor需要使用Mapped Statement中封装的数据信息操作数据库
5、 Mapped Statement
Mapped Statement是mybatis的一个底层的封装对象,封装了Sql语句、传入的sql语句,将sql查询结果映射成的java对象。
四、Mybatis入门程序
# Global logging configuration
log4j.rootLogger=DEBUG,stdout
#Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
<?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>
<!--给实体类起一个别名 user -->
<!-- <typeAliases> <typeAlias type="com.forum.po.User" alias="User" /> </typeAliases> -->
<!--数据源配置 这块用 BD2数据库 -->
<!--和Spring整合后 environments配置将废除 -->
<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=utf-8" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
<!--UserMapper.xml装载进来 同等于把“dao”的实现装载进来 -->
<mappers>
<mapper resource="sqlmap/UserMapper.xml" />
</mappers>
</configuration>
第五步:创建实体类User(User类属性要和数据库列对应)
public class User {
private int id;
private String name;
private String password;
public int getId() {
return id;
}
public void setId(int 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+"]";
}
}
第六步:创建UserMapper.xml(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">
<!--这块等于dao接口的实现 namespace必须和接口的类路径一样 -->
<mapper namespace="test">
<select id="findUserById" parameterType="int" resultType="com.ghy.mybatis.po.User">
Select * From users Where id = #{id}
</select>
<insert id="insertUser" parameterType="com.ghy.mybatis.po.User">
Insert Into users(id,name,password) Values (#{id},#{name},#{password})
</insert>
</mapper>
第七步:将UserMapper.xml在SqlMapConfig.xml中配置
<!--UserMapper.xml装载进来 同等于把“dao”的实现装载进来 -->
<mappers>
<mapper resource="sqlmap/UserMapper.xml" />
</mappers>
第八步:创建Mybatis查询程序
public class Mybatis_Select {
public static void main(String[] args) throws IOException {
//mybatis的配置文件
String resource="SqlMapConfig.xml";
InputStream inputStream=Resources.getResourceAsStream(resource);
//创建会话工厂
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
//从会话工厂得到会话
SqlSession sqlSession=sqlSessionFactory.openSession();
//通过sqlSession操作数据库
//第一个参数:UserMapper.xml中定义的statement的id
//第二个参数:输入参数
User user=sqlSession.selectOne("test.findUserById",4);
System.out.println(user.toString());
//释放资源
sqlSession.close();
}
五、问题回顾
Mybatis 是如何解决JDBC中的问题
1.Sql语句硬编码到java代码中,不利于系统维护。
(解决:将sql单独抽取出来,在配置文件(xml,properties)中进行配置)
在映射文件(UserMapper)中配置Sql语句
<mapper namespace="test">
<select id="findUserById" parameterType="int" resultType="com.ghy.mybatis.po.User">
Select * From users Where id = #{id}
</select>
<insert id="insertUser" parameterType="com.ghy.mybatis.po.User">
Insert Into users(id,name,password) Values (#{id},#{name},#{password})
</insert>
</mapper>
2.数据库每次使用后都关闭,导致数据库连接不能重复利用。对数据库资源是一种浪费。
(解决:使用数据库连接池管理数据库)
在SqlMapConfig.xml中配置运行环境,使用连接池
<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=utf-8" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
3.Statement设置参数时候,对于参数的位置通过硬编码指定
(解决:是否能够自动的将java对象的值设置到Statement中)
在UserMapper.xml中通过parameterType:输入参数的类型,在Sql语句中通过#{}表示占位符。完成了自动将java对象映射到sql语句中。
4.遍历结果集,resultset硬编码指定列名
(解决:能否自动将sql查询结果集映射成java对象)
在UserMapper.xml中通过resultType:输出参数类型,mybatis自动将sql查询结果映射成java对象。
<select id="findUserById" parameterType="int" resultType="com.ghy.mybatis.po.User">
Select * From users Where id = #{id}
</select>