1、介绍
(1)mybatis的优势:
是一款持久层框架,支持定制化SQL、存储过程以及高级映射,避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。可以使用简单的XML或注解来配置和映射原生类型、接口和java的POJO为数据库中的记录
MyBatis是apache的一个开源项目,对jdbc操作数据库的过程进行了封装,开发者只需关注sql本身,而不需要去处理注册驱动、创建连接、创建执行者对象、手动设置参数等复杂的代码。可以通过xml或注解的方式将要执行的各种statement配置起来,最终由mybatis框架执行sql并将结果映射成java对象返回。
(2)传统的jdbc的不足:
public class JdbcDemo {
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/stu_mangement", "root", "root");
// 定义sql语句 ?表示占位符
String sql = "select * from student where studentno = ?";
// 获取预处理statement
preparedStatement = connection.prepareStatement(sql);
// 设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值
preparedStatement.setString(1, "201811");
// 向数据库发出sql执行查询,查询出结果集
resultSet = preparedStatement.executeQuery();
// 遍历查询结果集
while (resultSet.next()) {
System.out.println(resultSet.getString("studentno") + " " + resultSet.getString("sname"));
}
} 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();
}
}
}
}
}
201811 zhai
数据库连接创建、释放频繁造成系统资源浪费,从而影响系统性能,使用数据库连接池可解决此问题。
sql语句在代码中硬编码,造成代码不易维护,实际应用中sql变化的可能较大,sql变动需要改变java代码。
使用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能多也可能少,修改sql还要修改代码,不易维护。
对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成pojo对象解析比较方便。
(3)mybatis框架:
2、mybatis入门程序
(1)导包:
核心包、依赖包、数据库驱动包
(2)书写pojo:
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
private String studentno;
private String sname;
private String sex;
private String birthday;
private String classno;
private String point;
private String phone;
private String email;
public String getStudentno() {
return studentno;
}
public void setStudentno(String studentno) {
this.studentno = studentno;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "Student [studentno=" + studentno + ", sname=" + sname + ", sex="
+ sex + ", birthday=" + birthday + ", classno=" + classno
+ ", point=" + point + ", phone=" + phone + ", email=" + email
+ "]";
}
public String getClassno() {
return classno;
}
public void setClassno(String classno) {
this.classno = classno;
}
public String getPoint() {
return point;
}
public void setPoint(String point) {
this.point = point;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
(3)核心配置文件:
<?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事务管理 -->
<transactionManager type="JDBC" />
<!-- 数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/student" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
</configuration>
(4)日志文件(在控制台打印信息):
# 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
(5)书写Student.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">
<mapper namespace="test">
<select id="findStudentById" parameterType="Integer" resultType="pers.zhb.pojo.Student">
select * from student where studentno = #{v}
</select>
</mapper>
在核心配置文件中引入该文件:
<mappers>
<mapper resource="sqlmap/student.xml"/>
</mappers>
(6)书写测试类:
public class Test {
public void testMybatis() throws Exception {
//加载核心配置文件
String resource = "sqlMapConfig.xml";
InputStream in = Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
//创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行Sql语句
Student student = sqlSession.selectOne("test.findStudentById", 201811);
System.out.println(student);
}
public static void main(String args []){
Test test=new Test();
try {
test.testMybatis();
} catch (Exception e) {
e.printStackTrace();
}
}
}
DEBUG [main] - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 2094411587.
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@7cd62f43]
DEBUG [main] - ==> Preparing: select * from student where studentno = ?
DEBUG [main] - ==> Parameters: 201811(Integer)
DEBUG [main] - <== Total: 1
Student [studentno=201811, sname=zhai, sex=男, birthday=1998-11-11, classno=tx171, point=890, phone=1234567890, email=null]
(7)模糊查询:
<select id="findStudentBysname" parameterType="String" resultType="pers.zhb.pojo.Student">
select * from student where sname like '%${value}%'
</select>
public void testfindUserBysname() throws Exception {
//加载核心配置文件
String resource = "sqlMapConfig.xml";
InputStream in = Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
//创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行Sql语句
List<Student> students = sqlSession.selectList("test.findStudentBysname", "zh");
for (Student student : students) {
System.out.println(student);
}
}
DEBUG [main] - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 1555690610.
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@5cb9f472]
DEBUG [main] - ==> Preparing: select * from student where sname like '%zh%'
DEBUG [main] - ==> Parameters:
DEBUG [main] - <== Total: 4
Student [studentno=201811, sname=zhai, sex=男, birthday=1998-11-11, classno=tx171, point=890, phone=1234567890, email=null]
Student [studentno=201812, sname=zhai2, sex=男, birthday=1998-11-11, classno=tx171, point=893, phone=19837372533, email=null]
Student [studentno=201813, sname=zhai3, sex=男, birthday=1998-11-11, classno=tx171, point=892, phone=19837372534, email=null]
Student [studentno=201814, sname=zhai3, sex=男, birthday=1998-11-11, classno=tx101, point=892, phone=19837372534, email=null]
上面的方式不能防止sql注入,可以更改配置文件,如下:
<select id="findStudentBysname" parameterType="String" resultType="pers.zhb.pojo.Student">
select * from student where sname like "%"#{value}"%"
</select>
(8)添加:
<insert id="insertStudent" parameterType="pers.zhb.pojo.Student">
insert into student (studentno,sname,sex,phone)
values (#{studentno},#{sname},#{sex},#{phone})
</insert>
public void testInsertStudent() throws Exception {
//加载核心配置文件
String resource = "sqlMapConfig.xml";
InputStream in = Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
//创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行Sql语句
Student student=new Student();
student.setStudentno("2020319");
student.setSname("ma");
student.setPhone("18733356671");
student.setSex("男");
int i = sqlSession.insert("test.insertStudent", student);
sqlSession.commit();
}
最后需要提交。
DEBUG [main] - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 152134087.
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@91161c7]
DEBUG [main] - ==> Preparing: insert into student (studentno,sname,sex,phone) values (?,?,?,?)
DEBUG [main] - ==> Parameters: 2020319(String), ma(String), 男(String), 18733356671(String)
DEBUG [main] - <== Updates: 1
DEBUG [main] - Committing JDBC Connection [com.mysql.jdbc.JDBC4Connection@91161c7]
(9)更新:
<update id="updateStudentById" parameterType="pers.zhb.pojo.Student">
update student
set sname = #{sname}
where studentno = #{studentno}
</update>
public void testUpdateUserById() throws Exception {
//加载核心配置文件
String resource = "sqlMapConfig.xml";
InputStream in = Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
//创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
Student student=new Student();
student.setStudentno("2020319");
student.setSname("ma2011");
int i = sqlSession.update("test.updateStudentById", student);
sqlSession.commit();
}
10、删除
<delete id="deleteStudentById" parameterType="Integer">
delete from student
where studentno = #{value}
</delete>
public void testDelete() throws Exception {
//加载核心配置文件
String resource = "sqlMapConfig.xml";
InputStream in = Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
//创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.delete("test.deleteStudentById", 2020319);
sqlSession.commit();
}
DEBUG [main] - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 152134087.
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@91161c7]
DEBUG [main] - ==> Preparing: delete from student where studentno = ?
DEBUG [main] - ==> Parameters: 2020319(Integer)
DEBUG [main] - <== Updates: 1
DEBUG [main] - Committing JDBC Connection [com.mysql.jdbc.JDBC4Connection@91161c7]