新版全新重构,更加方便易用,请移步:https://gitee.com/selfly/sonsure-dumper
Данный универсальный dal был разработан в процессе разработки и предназначен для использования с простым инкапсулированным универсальным dao или слоем доступа к данным.
Если вам не нравятся такие ORM-фреймворки, как Hibernate или Mybaits, и вы предпочитаете Spring JdbcTemplate или DbUtils, то можете попробовать этот инкапсулированный универсальный dal, который на данный момент является самым удобным и простым в использовании универсальным dal-слоем.
Последние обновления:
Конфигурацию динамических источников данных см. здесь: Использование динамических источников данных в dexcoder-dal и настройка разделения чтения и записи.
Разделение таблиц данных см. здесь: Реализация разделения данных по таблицам в dexcoder-dal.
Некоторые особенности dexcoder-dal:
Имена следуют принципу соглашения вместо конфигурации, типичные соглашения включают:
Конечно, вы можете изменить их в расширении, но это не рекомендуется, так как это хороший стандарт.
Использовать универсальный dao в проекте очень просто, он уже доступен в центральном репозитории maven, просто добавьте зависимость в pom.xml:
<dependency>
<groupId>com.dexcoder</groupId>
<artifactId>dexcoder-dal-spring</artifactId>
<version>${version}</version>
</dependency>
Затем объявите bean в файле конфигурации spring следующим образом:
<bean id="jdbcDao" class="com.dexcoder.dal.spring.JdbcDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
<!--Необходимо объявить при использовании разбиения на страницы-->
<bean id="pageControl" class="com.dexcoder.dal.spring.page.PageControl"></bean>
После этого его можно внедрить в ваш Service или другие классы для использования.
Сначала рассмотрим объект User и его унаследованный Pageable:
public class User extends Pageable {
private Long userId;
private String loginName;
private String password;
private Integer userAge;
private String userType;
private String email;
private Date gmtCreate;
//......
}
Объект Pageable используется для сохранения информации о количестве элементов на странице и текущей странице для поддержки разбиения на страницы.
public class Pageable implements Serializable {
/** Количество элементов на одной странице */
protected int itemsPerPage = 20;
/** Текущая страница */
protected int curPage = 1;
//......
}
Это обычные объекты JavaBean, ниже показано, как выполнять конкретные операции вставки, удаления, изменения и запроса, демонстрируя два метода Entity и Criteria для каждой операции.
Способ Entity:
User user = new User();
user.setLoginName("selfly_a");
//......
Long userId = jdbcDao.insert(user);
Способ Criteria:
Criteria criteria = Criteria.insert(User.class).into("loginName", "selfly_b").into("password", "12345678")
.into("email", "selflly@foxmail.com").into("userAge", 22).into("userType", "2").into("gmtCreate", new Date());
Long userId = jdbcDao.insert(criteria);
###Операция сохранения, отличие от операции вставки заключается в том, что она не обрабатывает первичный ключ, который должен быть указан вызывающей стороной.
Способ Entity:
User user = new User();
user.setUserId(-1L);
//......
jdbcDao.save(user);
Способ Criteria:
Criteria criteria = Criteria.insert(User.class).into("userId", -2L).into("loginName", "selfly-2")
.into("password", "12345678").into("email", "selflly@foxmail.com").into("userAge", 22).into("userType", "2")
.into("gmtCreate", new Date());
jdbcDao.save(criteria);
Способ Entity:
User user = new User();
user.setUserId(57L);
user.setPassword("abcdef");
//Способ один: значения null для атрибутов будут проигнорированы
jdbcDao.update(user);
//Способ два: значения null для атрибутов будут обновлены до базы данных
jdbcDao.update(user,false);
Способ Criteria:
//В способе Criteria здесь email установлен в значение null, также будет обновлён
Criteria criteria = Criteria.update(User.class).set("password", "update222").set("email",null)
.where("userId", new Object[] { 56L, -1L, -2L });
jdbcDao.update(criteria);
По первичному ключу:
User user = jdbcDao.querySingleResult(критерии);
//max()
Критерии критерии = Критерии.select(User.class).addSelectFunc("max([userId])");
Длинный userId = jdbcDao.queryForObject(критерии);
//count()
Критерии критерии = Критерии.select(User.class).addSelectFunc("count(*)");
Длинный счётчик = jdbcDao.queryForObject(критерии);
//distinct
Критерии критерии = Критерии.select(User.class).addSelectFunc("distinct [loginName]");
Список<Карта<Строка, Объект>> mapList = jdbcDao.queryForList(критерии);
По умолчанию метод addSelectFunc
возвращает результаты и поля таблицы взаимоисключающими, и не сортирует их. Если необходимо вернуть вместе с другими полями таблицы и использовать сортировку, можно использовать следующий код:
Критерии критерии = Критерии.select(User.class).addSelectFunc("DATE_FORMAT(gmt_create,'%Y-%m-%d %h:%i:%s') date",false,true);
Список<Карта<Строка, Объект>> mapList = jdbcDao.queryForList(критерии);
Это выполнение функций в select, но как выполнять функции в update и where? Для этого можно использовать {}
и []
.
Рассмотрим следующий код:
Критерии критерии = Критерии.update(User.class).set("[userAge]", "[userAge]+1")
.where("userId", новый объект[] { 56L });
jdbcDao.update(критерии);
Этот код выполнит SQL-запрос: UPDATE USER SET USER_AGE = USER_AGE+1 WHERE USER_ID = ?
. В []
fieldName преобразуется в columnName.
Также можно использовать {}
, чтобы напрямую писать columnName, потому что содержимое в {}
выполняется без каких-либо операций:
Критерии критерии = Критерии.update(User.class).set("{USER_AGE}", "{USER_AGE + 1}")
.where("userId", новый объект[] { 56L });
jdbcDao.update(критерии);
Аналогично, функции можно выполнять в where:
Критерии критерии = Критерии.select(User.class).where("[gmtCreate]", ">",
новый объект[] { "str_to_date('2015-10-1','%Y-%m-%d')" });
Список<Пользователь> userList = jdbcDao.queryList(критерии);
Иногда даже при работе с одной таблицей необходимо использовать псевдонимы таблиц, например, в Oracle с типом xmltype. В Criteria можно установить псевдоним таблицы:
Критерии критерии = Критерии.select(Table.class).tableAlias("t").addSelectFunc("[xmlFile].getclobval() xmlFile")
.where("tableId", новый объект[]{10000002L});
Объект obj = jdbcDao.queryForObject(критерии);
//Соответствующий SQL
select t.XML_FILE.getclobval() xmlFile from TABLE t where t.TABLE_ID = ?
Аннотации можно использовать для указания имени таблицы, первичного ключа, имени столбца или игнорирования определённого свойства. Конкретное использование кода ясно видно из следующего примера. Единственное, на что следует обратить внимание, это то, что аннотации размещаются на методах getter
, а не на свойствах:
@Table(name = "USER_A", pkField = "userId", pkColumn = "USER_ID")
public class AnnotationUser extends Pageable {
/** Пользовательский идентификатор */
private Длинный userId;
/** Базовое ключевое слово */
частная Строка desc;
/** Время модификации базы данных */
частное Дата gmtModify;
//пропущено...
@Column(name = "`DESC`")
public String getDesc() {
return desc;
}
@Transient
public Date getGmtModify() {
return gmtModify;
}
}
В реальных приложениях некоторые сложные запросы, такие как соединения таблиц и подзапросы, неизбежны. Учитывая сложность такого SQL и необходимые оптимизации, универсальный dao не предоставляет прямой инкапсуляции, а предоставляет интерфейс для выполнения пользовательских SQL.
Существует два способа выполнения пользовательского SQL: прямое выполнение SQL и выполнение через mybatis.
Этот способ может привести к появлению SQL-кода за пределами слоя dao, поэтому его не рекомендуется использовать. Он подходит только для некоторых ситуаций, которые не требуют дальнейшего обслуживания, таких как разработка собственных инструментов или временная обработка бизнес-данных.
Чтобы выполнить пользовательский SQL, сначала необходимо внедрить sqlFactory
в jdbcDao
. Здесь используется SimpleSqlFactory
:
<bean id="jdbcDao" class="com.dexcoder.dal.spring.JdbcDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
<property name="sqlFactory" ref="sqlFactory"/>
</bean>
<bean id="sqlFactory" class="com.dexcoder.dal.SimpleSqlFactory">
</bean>
Затем можно напрямую передать SQL для выполнения:
List<Map<String, Object>> list = jdbcDao.queryRowMapListForSql("select * from USER where login_name = ?",
new Object[] { "selfly_a99" });
Эта реализация относительно проста, и параметр Object массива не поддерживает сложные пользовательские объекты.
Этот подход реализован с использованием плагинов. Сначала добавьте зависимость:
<dependency>
<groupId>com.dexcoder</groupId>
<artifactId>dexcoder-dal-batis</artifactId>
<version>${version}</version>
</dependency>
После этого также внедрите sqlFactory
, заменив SimpleSqlFactory
на BatisSqlFactoryBean
:
<bean id="jdbcDao" class="com.dexcoder.dal.spring.JdbcDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
<property name="sqlFactory" ref="sqlFactory"/>
</bean>
<bean id="sqlFactory" class="com.dexcoder.dal.batis.BatisSqlFactoryBean">
<property name="sqlLocation" value="user-sql.xml"/>
</bean> **BatisSqlFactoryBean** имеет свойство **sqlLocation**, которое указывает на пользовательский файл SQL, поскольку используется способ анализа Spring, можно использовать различные подстановочные знаки так же, как и при использовании в конфигурационном файле Spring.
User-sql.xml — это XML-файл, похожий на mapper-класс MyBatis:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//dexcoder.com//DTD Mapper 2.0//EN"
"http://www.dexcoder.com/dtd/batis-mapper.dtd">
<mapper namespace="User">
<sql id="columns">
user_id,login_name,password,user_age,user_type
</sql>
<select id="getUser">
select
<include refid="columns"/>
from user
<where>
<if test="params[0] != null and params[0].userType != null">
user_type = #{params[0].userType}
</if>
<if test="params[1] != null">
and login_name in
<foreach collection="params[1]" index="index" item="item" separator="," open="(" close=")">
#{item}
</foreach>
</if>
</where>
</select>
</mapper>
Затем вызывается код:
User user = new User();
user.setUserType("1");
Object[] names = new Object[] { "selfly_a93", "selfly_a94", "mapList = jdbcDao.queryRowMapListForSql("User.getUser", "params", new Object[] { user, names });
for (Map<String, Object> map : mapList) {
System.out.println(map.get("userId"));
System.out.println(map.get("loginName"));
}
Мы вызываем метод queryForSql, передавая три параметра:
Здесь поддерживается сложный параметр, первый — объект User, второй — массив объектов, способ получения можно увидеть в коде выше.
Помимо передачи параметров в виде массива объектов и использования способа доступа parameters[0] для доступа к соответствующим элементам, остальное аналогично MyBatis, здесь также поддерживается динамический SQL, потому что он сам происходит от MyBatis.
Кроме того, в возвращаемом результате ключи карты преобразуются из LOGIN_NAME в camelCase loginName.
Способ BatisSqlFactory был проанализирован после анализа исходного кода Mybatis и включает в себя большое количество кода, заимствованного из Mybatis.
JdbcDao может быть настроен с другими параметрами при объявлении:
<bean id="jdbcDao" class="com.dexcoder.dal.spring.JdbcDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
<property name="sqlFactory" ref="..."/>
<property name="mappingHandler" ref="..."/>
<property name="rowMapperClass" value="..."/>
<property name="dialect" value="..."/>
</bean>
— mappingHandler — по умолчанию использует DefaultMappingHandler, то есть следует указанным соглашениям, а не конфигурации, при необходимости можно реализовать этот интерфейс. — sqlFactory — при выполнении пользовательского SQL внедряется соответствующая фабрика SQL. — rowMapperClass — по умолчанию используется spring BeanPropertyRowMapper.newInstance(clazz), при необходимости можно самостоятельно реализовать, стандартный RowMapper Spring также подойдёт. — dialect — диалект базы данных, будет автоматически определяться при пустом значении, обычно не требуется внедрять.
Многие спрашивают, нужно ли мне наследовать этот dao и реализовывать свои методы? На самом деле в этом нет необходимости, вы можете использовать spring JdbcTemplate в соответствии со стандартами, чтобы реализовать свой собственный dao без привязки. Кроме того, вы всё ещё можете использовать этот универсальный компонент разбиения на страницы.
Часть о разбиении на страницы основана на общем плагине разбиения на страницы Mybatis: https://github.com/pagehelper/Mybatis-PageHelper
Блог: http://www.dexcoder.com/selfly
Электронная почта автора: javaer@live.com
QQ группа общения: 32261424
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )