mybatis框架入門
MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。
jdbc编程
1.加载数据库驱动
2.创建并获得数据库连接
3.创建jdbc statement对象
4.设置sql语句
5.执行sql语句的参数(使用preparedStatement)
6.通过statement执行sql并获得结果
7.对sql执行结果进行解析处理
8.释放资源(resultSet , preparedStatement,connection)
执行原始jdbc 操作数据库
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
//加载数据库驱动
Class.forName("com.mysql.jdbc.Driver");
//通过驱动管理类获取数据库链接
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8", "root", "root");
//定义sql语句 ?表示占位符
String sql = "select * from user where username = ?";
//获取预处理statement
preparedStatement = connection.prepareStatement(sql);
//设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值
preparedStatement.setString(1, "王五");
//向数据库发出sql执行查询,查询出结果集
resultSet = preparedStatement.executeQuery();
//遍历查询结果集
while(resultSet.next()){
System.out.println(resultSet.getString("id")+" "+resultSet.getString("username"));
}
} catch (Exception e) {
e.printStackTrace();
}finally{
//释放资源
if(resultSet!=null){
try {
resultSet.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(preparedStatement!=null){
try {
preparedStatement.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(connection!=null){
try {
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
总结:
1、 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
2、 Sql语句在代码中硬编码,造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。
3、 使用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能多也可能少,修改sql还要修改代码,系统不易维护。
4、 对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成pojo对象解析比较方便。
mybatis CRUD操作;
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编程中对结果的解析处理过程。
mybatis入门RRUD:
第一步:创建项目;
第二步:导入jar包;mybatis核心包 日志包 数据驱动包
第三步:创建 log4j.properties;
# 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
mybatis默认使用log4j作为输出日志信息。
第四步:建立po类:po类通常与数据库对应,为mybatis映射使用
例:
Public class User {
private int id;
private String username;// 用户姓名
private String sex;// 性别
private Date birthday;// 生日
private String address;// 地址
get/set方法 toString()方法
}
第五步:在sqlmap文件下建立sql映射文件user.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是命名空间,作用sql语句的隔离,后面还有重要作用
#{}作用就是占位符,相当于jdbc的“?”
parameterType:查询的参数类型
resultType:查询结果的数据类型,如果时候pojo应该给全路径。
-->
<mapper namespace="test">
<!--根据id查找记录 -->
<select id="getUserById" parameterType="int" resultType="com.itluofan.mybatis.po.User">
SELECT * FROM `user` WHERE id=#{id};
</select>
<!--
如果查询结果返回list, resultType设置为list中一个元素的数据类型
${}字符串拼接指令
-->
<select id="getUserByName" parameterType="string" resultType="com.itluofan.mybatis.po.User">
SELECT * FROM `user` WHERE username LIKE '%${value}%'
</select>
<!--保存记录 -->
<!-- 参数时候pojo时,#{}中的名称就是pojo的属性 -->
<insert id="insertUser" parameterType="com.itluofan.mybatis.po.User">
<!--
keyProperty:对于pojo的主键属性
resultType:对应主键的数据类型
order:是在insert语句执行之前或者之后。
如果使用uuid做主键,应该先生成主键然后插入数据,此时应该使用Before
-->
<selectKey keyProperty="id" resultType="int" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
INSERT into user (username,birthday,sex,address)
values (#{username}, #{birthday}, #{sex}, #{address})
</insert>
<!-- 删除用户 -->
<delete id="deleteUser" parameterType="int">
DELETE from user WHERE id=#{id1}
</delete>
<!-- 修改用户信息 -->
<update id="updateUser" parameterType="com.itluofan.mybatis.po.User">
update user set username=#{username} WHERE id=#{id}
</update>
</mapper>
第六步:创建SqlMapConfig.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>
<!-- 配置属性
先加载内部属性,再加载外部属性,如果有同名属性会覆盖。
-->
<properties resource="db.properties">
<property name="jdbc.url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8"/> //此处配置文件正确 会被加载
<property name="jdbc.username" value="hello"/> //此处配置文件错误 会加载成功因为外部覆盖
</properties>
<!-- 配置pojo别名 -->
<typeAliases>
<!-- <typeAlias type="cn.itheima.mybatis.po.User" alias="user"/> -->
<!-- 扫描包的形式创建别名,别名就是类名,不区分大小写 -->
<package name="com.itheima.mybatis.po"/>
</typeAliases>
<!-- 和spring整合后 environments配置将废除-->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理-->
<transactionManager type="JDBC" />
<!-- 数据库连接池-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<!-- 加载mapper文件 -->
<mappers>
<!-- resource基于classpath查找 -->
<mapper resource="sqlmap/user.xml"/>
<!-- <mapper resource="mapper/mapper.xml"/> -->
<!-- 根据接口名称加载mapper文件
要求:1、mapper映射文件和接口在同一个目录下
2、mapper映射文件的名称和接口名称一致。
3、class就是接口的权限定名
-->
<!-- <mapper class="cn.itheima.mybatis.mapper.UserMapper"/> -->
<!-- 使用扫描包的形式加载mapper文件 -->
<package name="com.itheima.mybatis.mapper"/>
</mappers>
</configuration>
第七步:编辑测试类:
public class mybatisTest {
private SqlSessionFactory sqlSessionFactory;
//@before 优先执行
@Before
public void init() throws Exception {
//第一步:创建一个SQLSessionFactoryBuilder对象。
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//第二步:加载配置文件。
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
//第三步:创建SQLSessionFactory对象
sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
}
//根据id查询记录
@Test
public void getUserById(){
//第四步 创建一个session对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行查询
User user = sqlSession.selectOne("getUserById", 10);
System.out.println(user);
sqlSession.close();
}
//根据name查询记录
@Test
public void getUserByName(){
SqlSession sqlSession = sqlSessionFactory.openSession();
List<User> userlist = sqlSession.selectList("getUserByName", "张");
for (User user :userlist) {
System.out.println(user);
}
sqlSession.close();
}
//插入记录
@Test
public void testInsert() {
// 数据库会话实例
SqlSession sqlSession = null;
try {
// 创建数据库会话实例sqlSession
sqlSession = sqlSessionFactory.openSession();
// 添加用户信息
User user = new User();
user.setUsername("张小明");
user.setAddress("河南郑州");
user.setSex("1");
sqlSession.insert("test.insertUser", user);
//提交事务
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (sqlSession != null) {
sqlSession.close();
}
}
}
// 根据id删除用户
@Test
public void testDelete() {
// 数据库会话实例
SqlSession sqlSession = null;
try {
// 创建数据库会话实例sqlSession
sqlSession = sqlSessionFactory.openSession();
// 删除用户
sqlSession.delete("test.deleteUserById",18);
// 提交事务
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (sqlSession != null) {
sqlSession.close();
}
}
}
}