MyBatis的一个入门程序

MyBatis在操作数据库时,主要分为8大步骤:

(1) 读取MyBatis配置文件mabatis-config.xml,mabatis-config.xml作为MaBatis的全局配置文件,配置了MyBatis的运行环境等信息,其主要是获取数据库连接。

(2) 加载映射文件Mapper.xml。Mapper.xml即SQL映射文件,该文件配置了操作数据库的SQL语句,需要在mybatis-config.xml中加载才能执行。mybatis-config.xml可以添加多个配置文件,每个配置文件对应数据库中的一张表。

(3) 构建会话工厂。通过MyBatis的环境等配置信息构建会话工厂SqlSessionFactory

(4) 创建SqlSession对象。由会话工厂创建SqlSession对象。,该对象中包含执行SQL的所有方法。

(5) MyBatis底层定义的一个Executor接口会根据SqlSession传递的参数动态生成SQL语句,同时负责查询缓存的维护。

(6) 根据生成的SQL语句生成MappedStatement对象。

(7) 向MappedStatement输入映射对象,这里的输入参数的映射过程就相当于JDBC编程中对preparedStatement对象设置参数的过程。

(8) 执行SQL语句,对MappedStatement对象返回的结果进行处理。

下面通过一个入门程序来理解。

1.根据学号查询学生信息

(1)这里用sql server数据库。

在SQL Server数据库中,创建一个名为student的数据库,创建一个student表,并插入几条数据。

创建代码:

create database student;
use student;
create table student
(
st_no int identity(1,1) primary key ,
st_name varchar(30) not null,
sex varchar(2) default '男' not null,
tel varchar(11),
address varchar(30),
) 
alter table student add constraint ck_sex check (sex in('男','女'));    
insert into student values('张三','女','13688883333','湖南长沙'); 
insert into student values('李四','女','13644443333','湖南益阳'); 
insert into student values('李元霸','男','13512222444','湖南衡阳'); 
insert into student values('张莉莉','女','13688883333','湖南长沙'); 
select * from student;    

(2)在Myeclipse创建一个名为project01的Web项目,将MyBatis的核心jar包、依赖包,以及Sql Server数据库驱动添加到项目的lib目录下。

(3)在src目录下创建log4j.properties文件,内容如下 :

# Global logging configuration 
log4j.rootLogger=ERROR, stdout 
# MyBatis logging configuration... 
log4j.logger.cn.swjd=DEBUG
# 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输出日志信息,如果要在控制台查看sql语句,就必须

在src目录下创建log4j.properties文件。

(4)在src目录下创建cn.swjd.entries包,在该包下创建持久化类Student。

package cn.swjd.entries;
//学生持久化类
public class Student {
	//主键学号
	private  Integer st_no;
	//姓名,性别,年龄,电话  ,地址
	private String st_name, sex, tel, address;
	public Integer getSt_no() {
		return st_no;
	}
	public void setSt_no(Integer st_no) {
		this.st_no = st_no;
	}
	public String getSt_name() {
		return st_name;
	}
	public void setSt_name(String st_name) {
		this.st_name = st_name;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public String getTel() {
		return tel;
	}
	public void setTel(String tel) {
		this.tel = tel;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	 @Override
	public String toString() {
		return "Student [st_no=" + st_no + ", st_name=" + st_name + ", sex="
				+ sex + ", tel=" + tel + ", address=" + address + "]";
	}
}

(5)在src目录下。创建cn.swjd.mapper包,在包里创建映射文件StudentMapper.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="cn.swjd.mapper.StudentMapper"> 
  <select id="findStudentById" parameterType="Integer" resultType="cn.swjd.entries.Student">
      select * from student where st_no= #{st_no}  
      </select> 
 </mapper>

说明:<mapper>元素是配置文件的根元素,它包含一个namespace属性,该属性指定了<mapper>的唯一命名空间,通常设置为“包名+SQL映射文件名”的形式。

子元素<select>中的信息是用于执行查询操作的配置,id是唯一标识符。

parameterType:指定传入参数的类型。

resultType:指定返回结果的类型。

#{}:表示一个占位符,相当于jdbc中的?,其里面的内容为接受参数的名称。

 (6)在src目录下,创建MyBatis的核心配置文件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="sqlserver"> 
      <environment id="sqlserver"> 
   <transactionManager type="JDBC"/>   
<!--    配置数据库连接池 -->
         <dataSource type="POOLED">    
          <property name="driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>  
 <property name="url" value="jdbc:sqlserver://localhost:1433;DataBaseName=student"/>   
 <property name="username" value="sa"/>    
 <property name="password" value="123"/>   
 </dataSource>  
   </environment>  
   </environments> 
<mappers>  
 <mapper resource="cn/swjd/mapper/StudentMapper.xml"/>
</mappers> </configuration>   

说明:

  <environments>下可配置多个运行环境,default属性用于设置默认运行环境。

(7)在src目录下,创建一个cn.swjd.test包,创建测试类MyBatisTest,再编写一个方法findStudentByIdTest(int st_id),并在main方法里调用。

package cn.swjd.test;
import java.io.IOException;
import java.io.InputStream;
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 cn.swjd.entries.Student;
public class MyBatisTest {
	public static void findStudentByIdTest(int st_id) throws Exception{
		//1.读取配置文件
		String resource="mybatis-config.xml";
		InputStream inputstream=Resources.getResourceAsStream(resource);
		//2.根据配置文件构建SqlSessionFactory
		SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(inputstream);
		//3.通过SqlSessionFactory构建SqlSession
		SqlSession sqlsession=factory.openSession();
		//4.SqlSession执行映射文件中定义的SQL,并返回其映射结果
		Student s=sqlsession.selectOne("cn.swjd.mapper.StudentMapper.findStudentById",st_id);
		//打印输出结果
		System.out.println(s.toString());
	}
	public static void main(String args[]) throws Exception{
		findStudentByIdTest(1);
	}

}

运行结果:

2.根据姓名模糊查询学生信息

修改映射文件StudentMapper.xml,添加一个<select>

<select id="findStudentByName" parameterType="String" resultType="cn.swjd.entries.Student">

      select * from student where st_name like '%${value}%' 

      </select>

这里传入参数为什么不设置为#{}而用${}呢?

假设传入参数在程序里为 String value=”张”;

如果使用的是#{},最终的sql语句就会变成:

select * from student where st_name like ‘’’’ 

使用${},最终的sql语句就会变成:

select * from student where st_name like ‘

原因:如果使用的是#{}传入参数?就会根据配置文件<select>中parameterType属性(即数据类型)自动变换,如果parameterType="String",就会自动加入’’, 如果parameterType="Integer",就不会加’’

而使用${} 不管parameterType属性为何值,都不会自动加’’

在类MyBatisTest,编写一个方法findStudentByNameTest(String value),并在main方法里调用。

public static void findStudentByNameTest(String st_name) throws Exception{
		//1.读取配置文件
		String resource="mybatis-config.xml";
		InputStream inputstream=Resources.getResourceAsStream(resource);
		//2.根据配置文件构建SqlSessionFactory
		SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(inputstream);
		//3.通过SqlSessionFactory构建SqlSession
		SqlSession sqlsession=factory.openSession();
		//4.SqlSession执行映射文件中定义的SQL,并返回其映射结果
		List<Student> s=sqlsession.selectList("cn.swjd.mapper.StudentMapper.findStudentByName",st_name);
		/*selectList方法第一个参数为<Mapper>的namespace属性+<select>的id属性,后面接传入参数*/
		//打印输出结果
		for(Student stu:s)
		System.out.println(stu.toString());
	}
	public static void main(String args[]) throws Exception{
		findStudentByNameTest("张");
	}

运行结果: 

结果出来了,但是这里有一个问题,使用“${}”拼接字符串,无法防止sql注入问题

比如这里,如果把方法调用改成:

findStudentByNameTest("1';delete from student where st_no>0;commit; select * from student where st_name like '”);

它竟然可以操作数据库!把表所有内容都删除了。显然,实际项目开发中,是不能出现这种bug的,你永远不知道用户会输入什么东西

所以,为了安全性,这里不能用${},只能用#{},我们可以用SqlServer中的拼接函数concat()

修改后:

select * from student where st_name like concat('%',#{value},'%')

 

修改、删除、增加操作都差不多

相比于查询,就是多了sqlsession.commit()提交事务这一步骤而已

<?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="cn.swjd.mapper.StudentMapper"> 
<!--  根据学号查询学生信息 -->
  <select id="findStudentById" parameterType="Integer" resultType="cn.swjd.entries.Student">
      select * from student where st_no= #{st_no}  
      <!--  根据姓名模糊查询学生信息 -->
      </select> 
      <select id="findStudentByName" parameterType="String" resultType="cn.swjd.entries.Student">
       select * from student where st_name like concat('#',#{value},'#') 
      </select>
      <!--  更新学生信息 -->
      <update id="updateStudent" parameterType="cn.swjd.entries.Student"
      >
      update student set st_name=#{st_name},sex=#{sex},tel=#{tel},address=#{address} where st_no=#{st_no}
      </update>
      <!--  删除学生信息 -->
      <delete id="deleteStudent" parameterType="Integer">
      delete from student where st_no=#{id}
      </delete>
      <!--  增加学生信息 -->
      <insert id="addStudent" parameterType="cn.swjd.entries.Student">
      insert into student values (#{st_name},#{sex},#{tel},#{address})
      </insert>
 </mapper>
package cn.swjd.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 cn.swjd.entries.Student;
public class MyBatisTest {
	//根据学号查找学生
	public static void findStudentByIdTest(int st_id) throws Exception{
		//1.读取配置文件
		String resource="mybatis-config.xml";
		InputStream inputstream=Resources.getResourceAsStream(resource);
		//2.根据配置文件构建SqlSessionFactory
		SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(inputstream);
		//3.通过SqlSessionFactory构建SqlSession
		SqlSession sqlsession=factory.openSession();
		//4.SqlSession执行映射文件中定义的SQL,并返回其映射结果
		Student s=sqlsession.selectOne("cn.swjd.mapper.StudentMapper.findStudentById",st_id);
		/*selectOne方法第一个参数为<Mapper>的namespace属性+<select>的id属性,后面接传入参数*/
		//打印输出结果
		System.out.println(s.toString());
	}
	//根据姓名模糊查找学生
	public static void findStudentByNameTest(String st_name) throws Exception{
		//1.读取配置文件
		String resource="mybatis-config.xml";
		InputStream inputstream=Resources.getResourceAsStream(resource);
		//2.根据配置文件构建SqlSessionFactory
		SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(inputstream);
		//3.通过SqlSessionFactory构建SqlSession
		SqlSession sqlsession=factory.openSession();
		//4.SqlSession执行映射文件中定义的SQL,并返回其映射结果
		List<Student> s=sqlsession.selectList("cn.swjd.mapper.StudentMapper.findStudentByName",st_name);
		/*selectList方法第一个参数为<Mapper>的namespace属性+<select>的id属性,后面接传入参数*/
		//打印输出结果
		for(Student stu:s)
		System.out.println(stu.toString());
	}
	//更新学生信息
	public static void updateStudent(Student s) throws IOException{
		//1.读取配置文件
		String resource="mybatis-config.xml";
		InputStream inputstream=Resources.getResourceAsStream(resource);
		//2.根据配置文件构建SqlSessionFactory
		SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(inputstream);
		//3.通过SqlSessionFactory构建SqlSession
		SqlSession sqlsession=factory.openSession();
		//4.SqlSession执行映射文件中定义的SQL,并返回其映射结果
		int i = sqlsession.update("cn.swjd.mapper.StudentMapper.updateStudent", s);
		//提交事务
		sqlsession.commit();
		if(i>0){
			System.out.println("更新学号为"+s.getSt_no()+"学生信息成功!");
		}
	}
	//删除学生信息
	public static void deleteStudent(int st_no) throws IOException{
		//1.读取配置文件
				String resource="mybatis-config.xml";
				InputStream inputstream=Resources.getResourceAsStream(resource);
				//2.根据配置文件构建SqlSessionFactory
				SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(inputstream);
				//3.通过SqlSessionFactory构建SqlSession
				SqlSession sqlsession=factory.openSession();
				//4.SqlSession执行映射文件中定义的SQL,并返回其映射结果
				int i = sqlsession.delete("cn.swjd.mapper.StudentMapper.deleteStudent", st_no);
				//5.提交事务
				sqlsession.commit();
				if(i>0){
					System.out.println("删除学号为"+st_no+"的学生信息成功!");
				}
				
	}
	//增加学生信息
	public static void addStudent(Student s) throws IOException{
		//1.读取配置文件
		String resource="mybatis-config.xml";
		InputStream inputstream=Resources.getResourceAsStream(resource);
		//2.根据配置文件构建SqlSessionFactory
		SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(inputstream);
		//3.通过SqlSessionFactory构建SqlSession
		SqlSession sqlsession=factory.openSession();
		//4.SqlSession执行映射文件中定义的SQL,并返回其映射结果
		int i = sqlsession.insert("cn.swjd.mapper.StudentMapper.addStudent", s);
		//5.提交事务
		sqlsession.commit();
		if(i>0){
			System.out.println("添加一条学生信息成功!");
		}
	}
	public static void main(String args[]) throws Exception{
		Student s=new Student();
		s.setSt_name("李云瑞");
		s.setSex("男");
		addStudent(s);
	}

}

 

猜你喜欢

转载自blog.csdn.net/cc1969281777/article/details/83048431