一、连接数据库的配置单独放在一个properties文件中
在MyBatis入门中,我们是直接将数据库的连接配置信息写在了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="development">
<environment id="development">
<transactionManager type="JDBC"/>
<!-- 配置数据库连接信息 -->
<dataSource type="POOLED">
<property name="driver" value="${sql_driver}"/>
<property name="url" value="${sql_url}"/>
<property name="username" value="${sql_user}"/>
<property name="password" value="${sql_password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- UserMapper.xml位于mapper这个包下,
所以resource写成mapper/UserMapper.xml -->
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
</configuration>
其实我们完全可以将数据库的连接配置信息写在一个properties文件中,然后在mybatis-config.xml文件中引用properties文件,具体做法如下:
1、在src目录下新建一个config/config.properties文件
在config.properties文件中编写连接数据库需要使用到的数据库驱动,连接URL地址,用户名,密码,如下:
sql_driver=com.mysql.jdbc.Driver
sql_url=jdbc:mysql://localhost:3306/shopping?characterEncoding=UTF8
sql_user=root
sql_password=root
2、在MyBatis的mybatis-config.xml文件中引用config/config.properties文件,如下:
<?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>
<!-- 引用config.properties配置文件 -->
<properties resource="config/config.properties">
</properties>
<!--
development:开发模式
work:工作模式
-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<!-- 配置数据库连接信息 -->
<dataSource type="POOLED">
<!-- value属性值引用config.properties配置文件中配置的值 -->
<property name="driver" value="${sql_driver}"/>
<property name="url" value="${sql_url}"/>
<property name="username" value="${sql_user}"/>
<property name="password" value="${sql_password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- UserMapper.xml位于mapper这个包下,
所以resource写成mapper/UserMapper.xml -->
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
</configuration>
二、为实体类定义别名,简化sql映射xml文件中的引用
类型别名是为 Java 类型设置一个短的名字。它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余。例如:
<insert id="add" parameterType="user" useGeneratedKeys="true" keyProperty="id">
insert into user(userName, password, phone)
values
(#{userName}, #{password}, #{phone})
</insert>
也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,每一个在包中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如 com.hzyc.mybatislearn.entry.Student的别名为 student;若有@Alias注解,则别名为其注解值。
Mapper.xml文件
三、映射器配置方式(mappers)
如何让Mybatis框架找到SQL映射文件是保障Mybatis正常工作的核心步骤。可以使用相对于类路径的资源引用, 或完全限定资源定位符(包括 file:/// 的 URL),或类名和包名等
1、使用相对于类路径的资源引用
2、使用映射器接口实现类的完全限定类名,Mapper.xml文件需要和接口在同一个包中
3、将包内的映射器接口实现全部注册为映射器,Mapper.xml文件需要和接口在同一个包中
四、Java代码(单例模式)
package app;
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 java.io.IOException;
import java.io.InputStream;
public class SqlSessionUtil {
private SqlSessionFactory sqlSessionFactory;
private static SqlSessionUtil sqlSessionUtil = new SqlSessionUtil();
/*static {
try {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
System.exit(0);
}
}*/
private SqlSessionUtil() {
try {
InputStream inputStream = Resources.getResourceAsStream("config/mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
}
public static SqlSessionUtil getInstance() {
return sqlSessionUtil;
}
public SqlSessionFactory getSqlSessionFactory() {
return sqlSessionFactory;
}
public SqlSession getSqlSession() {
return sqlSessionFactory.openSession();
}
}
测试代码如下:
package app;
import mapper.UserMapper;
import model.UserBean;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
import java.util.Scanner;
/**
* @author xuehj2016
*/
public class Application {
public static void main(String[] args) {
while (true) {
System.out.println("1-添加\t2-查询");
String num = new Scanner(System.in).next();
switch (num) {
case "1":
add();
break;
case "2":
query();
break;
default:
System.out.println("输入错误!");
}
}
}
public static void query() {
SqlSession sqlSession = null;
try {
SqlSessionUtil sqlSessionUtil = SqlSessionUtil.getInstance();
sqlSession = sqlSessionUtil.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<UserBean> data = userMapper.query();
for (UserBean userBean : data) {
System.out.println(userBean.getId() + "\t" + userBean.getUserName()
+ "\t" + userBean.getPhone());
}
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
if (sqlSession != null) {
sqlSession.rollback();
}
} finally {
if (sqlSession != null) {
sqlSession.close();
}
}
}
public static void add() {
SqlSession sqlSession = null;
try {
SqlSessionUtil sqlSessionUtil = SqlSessionUtil.getInstance();
sqlSession = sqlSessionUtil.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
UserBean userBean = new UserBean();
userBean.setUserName("user");
userBean.setPhone("15771697568");
userBean.setPassword("user");
System.out.println(userBean);
int rows = userMapper.add(userBean);
System.out.println(userBean);
System.out.println(rows > 0 ? "添加成功!" : "添加失败!");
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
if (sqlSession != null) {
sqlSession.rollback();
}
} finally {
if (sqlSession != null) {
sqlSession.close();
}
}
}
}
五、知识点的总结
1、 #{}和${}
#{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换.#{}可以有效防止sql注入。#{}可以接受简单类型或者pojo属性值。如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。
${}表示sql的拼接,通过${}接收参数,将参数的内容不加任何修饰拼接在sql中。${}也可以接收pojo数据,可以使用OGNL解析出pojo的属性值.缺点:不能防止sql注入。
2、 parameterType和resultType
parameterType:指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中。
resultType:指定输出结果类型,mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。
mybatis-config.xml-数据源类型
数据源(dataSource)
dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象的资源。
有三种内建的数据源类型(也就是 type=”[UNPOOLED|POOLED|JNDI]”):
UNPOOLED– 这个数据源的实现只是每次被请求时打开和关闭连接。
POOLED– 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。 这是一种使得并发 Web 应用快速响应请求的流行处理方式。
poolMaximumActiveConnections – 在任意时间可以存在的活动(也就是正在使用)连接数量,默认值:10
poolMaximumIdleConnections – 任意时间可能存在的空闲连接数。
poolMaximumCheckoutTime – 在被强制返回之前,池中连接被检出(checked out)时间,默认值:20000 毫秒(即 20 秒)
JNDI – 这个数据源的实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。这种数据源配置只需要两个属性:
– 这个属性用来在 InitialContext 中寻找上下文(即,initialContexinitial_context t.lookup(initial_context))。这是个可选属性,如果忽略,那么 data_source 属性将会直接从 InitialContext 中寻找。
data_source – 这是引用数据源实例位置的上下文的路径。提供了 initial_context 配置时会在其返回的上下文中进行查找,没有提供时则直接在 InitialContext 中查找。
参数取值$与#的区别
默认情况下,使用 #{} 格式的语法会导致 MyBatis 创建 PreparedStatement 参数并安全地设置参数(就像使用 ? 一样)。这样做更安全,更迅速,通常也是首选做法,不过有时你就是想直接在 SQL 语句中插入一个不转义的字符串。比如,像 ORDER BY,你可以这样来使用:
ORDER BY ${columnName}