MyBatis对jdbc的封装
- 核心知识(执行伪代码)
已知:完整类名、字段名、属性名
2.通过反射机制,创建对象,给属性赋值
3。官网下载解压如下
第一个mybatis程序实现步骤:
1、新建一个java project即可。
2、引入mybatis的jar
mybatis-3.4.5.jar
3、引入mysql的驱动jar
mysql-connector-java-5.1.23-bin.jar
4、新建包:com.wkcto.mybatis.test
5、新建测试类:Test01,提供main方法,在main方法当中,粘贴以下代码:
main{
String resource = "com/wkcto/mybatis/resources/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
6、新建包:com.wkcto.mybatis.resources
7、在com.wkcto.mybatis.resources包下新建一个mybatis-config.xml文件
8、关于mybatis-config.xml文件:
注意:该文件是mybatis的核心配置文件,在该文件当中配置了连接数据库的信息、事务管理器、连接池等。
9、编写mybatis-config.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>
<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/wkcto" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
</configuration>
10、编写main方法,通过SqlSessionFactory获取SqlSession对象:
SqlSession sqlSession = sqlSessionFactory.openSession(); // sqlSession专门用来执行sql语句的。
sqlSession.commit();
sqlSession.rollback();
sqlSession.close();
注意:sqlSession默认情况下自动提交机制是关闭的。
11、写sql语句:在一个所谓的SqlMapper.xml文件中编写sql语句。(我们把这个文件叫做sql映射文件)
在src下新建SqlMapper.xml文件。(不一定在src的根目录下,只要在src中即可。也就是说只要在类路径下就行。)
我这里就在这个包下新建了:com.wkcto.mybatis.resources
SqlMapper.xml文件
12、在mybatis的核心配置文件中配置该文件的路径:
<mappers>
<mapper resource="com/wkcto/mybatis/resources/SqlMapper.xml"/>
</mappers>
13、编写SqlMapper.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="">
</mapper>
14、定义一个domain/javabean:Student
public class Student{
sid
sname
sbirth
}
故意:属性名和数据库表当中的列名不一致。
数据库列名:id name birth
15、在SqlMapper.xml文件中配置sql语句:
<select id="getAll" resultType="com.wkcto.mybatis.domain.Student">
select
id,name,birth
from
tbl_student
</select>
16、在main方法当中执行这条sql语句。
List<Student> studentList = sqlSession.selectList("getAll");
注意:getAll必须是sql语句的id。
重点掌握的知识点:
select
id as sid,name as sname,birth as sbirth
from
tbl_student
查询结果集的列名必须和java类的属性名一一对应。
不一致的时候,需要使用as关键字起别名。
完整代码:
package com.wkcto.mybatis.test;
import java.io.IOException;
import java.io.InputStream;
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 com.wkcto.mybatis.domain.Student;
public class Test01 {
public static void main(String[] args) {
SqlSession sqlSession = null;
try {
String resource = "com/wkcto/mybatis/resources/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// SqlSession对象可以等同看做JDBC当中的Connection
// 注意:openSession()方法只要调用,开启事务,事务自动提交机制关闭,等同于:conn.setAutoCommit(false);
sqlSession = sqlSessionFactory.openSession();
// do work (执行sql)
List<Student> studentList = sqlSession.selectList("getAll");
for(Student s : studentList){
System.out.println(s.getSid() + "," + s.getSname() + "," + s.getSbirth());
}
// 事务结束之后,必须手动提交
sqlSession.commit();
} catch (IOException e) {
// 回滚事务
if(sqlSession != null){
sqlSession.rollback();
}
e.printStackTrace();
} finally{
// 关闭资源
if(sqlSession != null){
sqlSession.close();
}
}
}
}
<?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目前先不要了解,可以随意编写 -->
<mapper namespace="fdasfdsajkfldjsakfldjsk">
<!-- 提供sql语句 -->
<!-- select标签是专门为DQL(查询语句)语句设计的。 -->
<!-- id非常重要,id在同一个xml文件中不能重复,唯一的,id代表了这条sql语句 -->
<!-- resultType是结果集即将封装的java对象的完整类名,通过resultType属性来告诉mybatis,结果集封装成什么类型的对象! -->
<!-- mybatis的sql语句不需要以“;”结尾。 -->
<select id="getAll" resultType="com.wkcto.mybatis.domain.Student">
select
id as sid,name as sname,birth as sbirth
from
tbl_student
</select>
</mapper>
<?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>
<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/wkcto" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/wkcto/mybatis/resources/SqlMapper.xml"/>
</mappers>
</configuration>
package com.wkcto.mybatis.domain;
public class Student {
private String sid;
private String sname;
private String sbirth;
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getSbirth() {
return sbirth;
}
public void setSbirth(String sbirth) {
this.sbirth = sbirth;
}
}
下面是增删改查小例子:
<?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>
<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/wkcto" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="SqlMapper.xml"/>
</mappers>
</configuration>
<?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="fdjkaslfjdklsafkjdls">
<!-- resultType属性是DQL语句专属的,表示查询结果集类型 -->
<!-- 插入语句没有结果集,没有ResultSet-->
<!-- parameterType是专门给sql语句的占位符赋值的/传值的, parameterType是参数的类型-->
<!-- 在mybatis当中,占位符不能使用?,必须使用#{} -->
<!-- 一个学生对象中的属性很多,拿出哪个属性传到哪个占位符上? -->
<insert id="save" parameterType="com.wkcto.mybatis.domain.Student">
insert into tbl_student(id,name,birth) values(#{sid},#{sname},#{sbirth})
</insert>
<!--
insert into tbl_student(id,name,birth) values(#{sid},#{sname},#{sbirth})
#{这里必须填写的是javabean的属性名}
因为要通过这个属性名拼接get方法。
拿到get方法,会从对象中取属性的值。
取出属性的值会给?传值。
-->
<update id="update" parameterType="com.wkcto.mybatis.domain.Student">
update tbl_student set
name = #{sname} , birth = #{sbirth}
where
id = #{sid}
</update>
<!-- 查询多个记录的时候,返回List集合,对于mybatis来说,必须告诉mybatis List集合中具体存储什么类型的对象!!! -->
<select id="getAll" resultType="com.wkcto.mybatis.domain.Student">
select
id as sid, name as sname, birth as sbirth
from
tbl_student
</select>
<!-- 当占位符只有一个的时候,#{这里可以随意编写},mybatis很健壮。 -->
<!--
<select id="getById" parameterType="java.lang.String" resultType="com.wkcto.mybatis.domain.Student">
-->
<!-- parameterType属性为简单类型的时候,该属性可以不提供。 -->
<!--
简单类型:
byte short int long float double boolean char
Byte Short Integer Long Float Double Boolean Character
String
-->
<select id="getById" resultType="com.wkcto.mybatis.domain.Student">
select
id as sid, name as sname, birth as sbirth
from
tbl_student
where
id = #{fkjdfdkjslafjdklsajfkdlsjakflds}
</select>
<delete id="deleteById">
delete from tbl_student where id = #{fdasfjdksafjdklsa}
</delete>
</mapper>
package com.wkcto.mybatis.test;
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 com.wkcto.mybatis.domain.Student;
public class Test {
public static void main(String[] args) {
SqlSession sqlSession = null;
try {
/*
* // 核心文件
* String resource = "mybatis-config.xml";
* // 输入流,输入流指向核心文件
* InputStream inputStream = Resources.getResourceAsStream(resource);
* //通过流来构建一个
* SqlSessionFactory SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
*/
// SqlSessionFactoryBuilder --> SqlSessionFactory --> SqlSession
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(Resources.getResourceAsStream("mybatis-config.xml"));
sqlSession = sqlSessionFactory.openSession();
// do work
// insert(增)
/*
Student stu = new Student();
stu.setSid("210");
stu.setSname("jack");
stu.setSbirth("1990-10-11");
int count = sqlSession.insert("save", stu); // 返回值int表示影响数据库表当中的记录条数。
System.out.println(count);
*/
// update(改)
/*
Student stu = new Student();
stu.setSid("210");
stu.setSname("杰克");
stu.setSbirth("1970-10-11");
int count = sqlSession.update("update", stu);
System.out.println(count);
*/
// selectOne(查一个)
/*
Student s = sqlSession.selectOne("getById", "210");
System.out.println(s.getSid() + "," + s.getSname() + "," + s.getSbirth());
*/
// selectList(查所有)
/*
List<Student> studentList = sqlSession.selectList("getAll");
for(Student s : studentList){
System.out.println(s.getSid() + "," + s.getSname() + "," + s.getSbirth());
}
*/
// delete(删)
int count = sqlSession.delete("deleteById", "210");
System.out.println(count);
sqlSession.commit();
} catch (Exception e) {
if (sqlSession != null) {
sqlSession.rollback();
}
e.printStackTrace();
} finally {
if (sqlSession != null) {
sqlSession.close();
}
}
}
}
改进版
mybatis执行的sql语句怎么输出到控制台呢?
可以借助一个第三方的组件<日志组件>:
log4j
我们这里不研究log4j,只是用一下。
怎么用?
第一步:引入log4j的jar : log4j-1.2.17.jar
第二步:引入log4j的配置文件
在类的根路径下,新建log4j.properties
第三步:在配置文件中编写mybatis日志配置信息。
在该文件中添加以下配置:
log4j.rootLogger=DEBUG,Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.org.apache=INFO
注意:
log4j是一个java语言平台通用的日志组件,可以使用在
各大框架当中,不只是可以用在mybatis里面。
<?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="jdbc.properties"/>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="SqlMapper.xml" />
</mappers>
</configuration>
<?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="fdsafdsajfkldsajfklds">
<!--
<insert id="save" parameterType="java.util.Map">
-->
<insert id="save" parameterType="Map">
insert into tbl_student(id,name,birth) values(#{xuehao},#{xingming},#{shengri})
</insert>
<!-- parameterType="String"可以省略-->
<!-- resultType是结果集的类型,结果集类型可以是简单类型,也可以是javabean,还可以使用Map -->
<!-- resultType即使是简单类型,例如:resultType = "String",那么它也不能省略不写。 -->
<select id="getById" parameterType="String" resultType="Map">
select
id , name , birth
from
tbl_student
where
id = #{id}
</select>
<select id="getAll" resultType="Map">
<!-- select id,name,birth from tbl_student -->
select id as x,name as y,birth as z from tbl_student
</select>
<delete id="deleteById">
delete from tbl_student where id = #{id}
</delete>
<update id="update" parameterType="Map">
update tbl_student set
name = #{xingming} , birth = #{shengri}
where
id = #{xuehao}
</update>
</mapper>
log4j.rootLogger=DEBUG,Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.org.apache=INFO
package com.wkcto.mybatis.test;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
/*
* MVC:
* service
* 控制事务(需要SqlSession)
* SqlSession sqlSession = factory.openSession();
* ...
* sqlSession.commit();
*
* dao
* 只做CRUD(需要SqlSession)
*
* 怎么保证事务?
* service和dao里面用的SqlSession对象必须是同一个才行。
* 将SqlSession对象存放到ThreadLocal当中。
* service和dao当中只要使用SqlSession对象都从ThreadLocal当中取。
*/
public class Test02 {
public static void main(String[] args) {
SqlSession sqlSession = null;
try {
SqlSessionFactory factory = new SqlSessionFactoryBuilder()
.build(Resources.getResourceAsStream("mybatis-config.xml"));
sqlSession = factory.openSession();
//org.apache.ibatis.session.defaults.DefaultSqlSession@64616ca2
System.out.println(sqlSession);
SqlSession sqlSession2 = factory.openSession();
//org.apache.ibatis.session.defaults.DefaultSqlSession@13fee20c
System.out.println(sqlSession2);
sqlSession.commit();
} catch (Exception e) {
if (sqlSession != null) {
sqlSession.rollback();
}
e.printStackTrace();
} finally {
if (sqlSession != null) {
sqlSession.close();
}
}
}
}
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/wkcto
jdbc.user=root
jdbc.password=root